GraphQL Subscriptions | WebSocket, SSE, and Multipart | WunderGraph Cosmo - WunderGraph
Five subscription protocols and automatic connection multiplexing
Cosmo Router accepts any subscription protocol from clients and translates to the subgraph protocol. Connection multiplexing reduces backend connection count automatically.
graphql-ws (default), SSE, Multipart HTTP, subscriptions-transport-ws, and Absinthe.
The problem
One URL, multiple protocols, many clients
Real-time features break when clients, routers, and subgraphs all expect different protocols. Connection overhead grows linearly with client count without multiplexing.
Clients and subgraphs use different protocols
Legacy mobile apps, modern web clients, and Elixir backends each prefer different subscription protocols. Without automatic translation, each combination requires separate handling.
Each client opens a separate backend connection
Without connection multiplexing, every client subscription opens its own connection to the subgraph. Backend connection count scales 1:1 with subscriber count, exhausting resources.
Adding subscriptions requires infrastructure work
Protocol negotiation, heartbeat handling, reconnection logic, and extension field forwarding all need to be implemented before a single real-time update ships.
Our solution
Protocol translation and multiplexing in the Router
The Cosmo Router supports five subscription protocols between clients and subgraphs. It translates between protocols automatically, so clients and subgraphs can use whatever they support.
How subscriptions work in Cosmo Router
- Clients connect using their preferred protocol. graphql-ws is the default. SSE and Multipart HTTP are recommended for unidirectional update streams.
- The Router accepts graphql-ws, SSE (GET and POST), Multipart HTTP, subscriptions-transport-ws, and Absinthe from clients.
- The Router communicates with each subgraph using the protocol configured for that subgraph. Set per-subgraph protocol via the CLI.
- Protocol translation is automatic. A legacy client using subscriptions-transport-ws can subscribe to a modern graphql-ws subgraph.
- Connection multiplexing groups subscriptions with matching authentication headers into shared upstream connections.
- The Router forwards extension field data (such as Bearer tokens) to subgraphs in the per-operation subscribe payload.
Clients use what they support. The Router handles the rest.
Before & After
| Before Cosmo | With Cosmo |
|---|---|
| Limited to one subscription protocol | Choose from WebSockets, SSE, or Multipart HTTP |
| Each client opens a new backend connection | Multiplexed connections share resources |
| Manual protocol negotiation logic | Automatic protocol translation between clients and subgraphs |
| Legacy clients break on protocol updates | subscriptions-transport-ws and Absinthe supported alongside modern protocols |
Supported protocols
graphql-ws— default and recommended. Widely adopted WebSocket subprotocol.SSE (GET and POST)— Server-Sent Events. Unidirectional. Uses less memory than WebSockets. Works better through certain proxies.Multipart HTTP— Chunked subscription responses over HTTP.subscriptions-transport-ws— Legacy Apollo WebSocket protocol. For existing clients that have not migrated.Absinthe— Phoenix (Elixir) protocol. For Elixir/Phoenix ecosystems.
How GraphQL Subscriptions work in Cosmo Router
01
All 5 protocols from clients.
Connect
Clients connect using graphql-ws, SSE, Multipart HTTP, subscriptions-transport-ws, or Absinthe. The Router accepts all five protocols from clients.
02
Shared upstream connections.
Multiplex
The Router groups client subscriptions with matching authentication headers into single upstream connections to subgraphs. Multiple clients share the same backend connection when their headers match.
03
Automatic protocol translation.
Translate
If the client protocol differs from the subgraph protocol, the Router translates automatically. Configure the subgraph protocol per-subgraph via the Cosmo CLI.
04
Router manages lifecycle.
Stream
The Router cleans up connections when its configuration updates. Clients should reconnect automatically on disconnect.
What GraphQL Subscriptions provides
Five protocols, automatic translation, and connection multiplexing.
graphql-ws (default)
The recommended WebSocket subprotocol. Widely supported by GraphQL client libraries. Enabled by default with no configuration required.
Server-Sent Events (GET and POST)
One-way event streaming over HTTP. Uses less memory than WebSockets and works better through certain proxies. Recommended for notification streams.
Multipart HTTP
Chunked subscription responses over standard HTTP. Useful for clients that cannot maintain WebSocket connections.
Legacy protocol support
subscriptions-transport-ws for existing Apollo clients. Absinthe for Phoenix/Elixir ecosystems. Migrate backend services without breaking existing clients.
Extension field forwarding
Pass additional metadata (such as Bearer tokens) in the GraphQL extensions field with subscription messages. The Router forwards extensions to subgraphs in the per-operation subscribe payload.
Per-subgraph protocol configuration
Configure the subscription protocol per subgraph via the Cosmo CLI. Modernize backend services gradually without changing client protocols.
Enable real-time subscriptions
Subscriptions work out of the box. Customize protocols per subgraph as needed.
FAQ
GraphQL Subscriptions questions
- Which subscription protocols does Cosmo Router support?
- How does connection multiplexing work?
- Can I use different protocols for different subgraphs?
- What happens when the Router updates its configuration at runtime?
- What is the extensions field used for?
- When should I use SSE instead of WebSockets?
Deep dive in the GraphQL Subscriptions documentation.