You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/documentation/content/docs/router/subscriptions/index.mdx
+45Lines changed: 45 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -184,6 +184,16 @@ The protocols used between the router and subgraphs are independent from those u
184
184
185
185
If a client requests a subscription over an unsupported transport, the router returns `406 Not Acceptable`.
186
186
187
+
## Deduplication
188
+
189
+
Subscriptions participate in the same inbound deduplication mechanism as queries. When multiple clients subscribe to the same operation with the same deduplication parameters, the router opens exactly one upstream subgraph connection and fans events out to all connected clients via a broadcast channel.
190
+
191
+
See [Inbound Deduplication](/docs/router/guides/performance-tuning#inbound-deduplication) for how to enable and configure it.
192
+
193
+
## Schema Reload
194
+
195
+
When a new supergraph schema is loaded, the router closes all active subscriptions before the schema is swapped in. Each client receives a final error event with the `SUBSCRIPTION_SCHEMA_RELOAD` error code. Clients are expected to handle this code by reconnecting and re-subscribing. After reconnecting, the subscription runs against the new schema.
196
+
187
197
## Configuration
188
198
189
199
Subscriptions are disabled by default. To enable them, set `enabled: true` in the `subscriptions` section of your router configuration:
@@ -198,3 +208,38 @@ You can also enable subscriptions using the `SUBSCRIPTIONS_ENABLED` environment
198
208
```bash
199
209
SUBSCRIPTIONS_ENABLED=true
200
210
```
211
+
212
+
### Broadcast Capacity
213
+
214
+
Controls the buffer size of the internal broadcast channel used to fan subscription events out to clients.
215
+
216
+
When a consumer falls behind and the buffer fills up, it skips missed messages and continues from
217
+
the latest available event. The consumer is not disconnected - there is a trace log when this
218
+
happens. Increase this value if consumers are frequently falling behind on high-throughput
219
+
subscriptions.
220
+
221
+
```yaml
222
+
subscriptions:
223
+
enabled: true
224
+
broadcast_capacity: 64 # defaults to 32
225
+
```
226
+
227
+
### Long-Lived Client Limit
228
+
229
+
HTTP streaming responses (SSE, Incremental Delivery, Multipart HTTP) and WebSocket connections are
230
+
long-lived - they hold an open connection for the duration of the subscription. To protect the
231
+
router from resource exhaustion, a global limit caps the number of these connections that can be
232
+
active at the same time. Regular HTTP requests (queries and mutations) are not counted toward this
233
+
limit.
234
+
235
+
When the limit is reached, new long-lived connection attempts are rejected with
236
+
`503 Service Unavailable` and a `Retry-After: 5` response header. The limit defaults to `128` and
237
+
is configurable via [`traffic_shaping.router.max_long_lived_clients`](/docs/router/configuration/traffic_shaping#routermax_long_lived_clients):
Copy file name to clipboardExpand all lines: packages/documentation/content/docs/router/subscriptions/websockets.mdx
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -52,6 +52,8 @@ Client WebSocket support is configured at the root level under `websocket` - it
52
52
53
53
Each WebSocket connection from a client is long-lived and can carry multiple GraphQL operations. For every operation sent over the connection - including single-shot operations like queries and mutations - the router creates a **synthetic HTTP request**. This means every operation goes through the full [plugin system](/docs/router/plugin-system) exactly as if it were a regular HTTP request. Authorization, header manipulation, rate limiting, and all other plugins apply uniformly regardless of whether the client connected over HTTP or WebSocket.
54
54
55
+
Because operations are processed as synthetic HTTP requests, they share the same fingerprint space as regular HTTP requests. A query sent over WebSocket can deduplicate with the same query sent over HTTP, and a WebSocket subscription can deduplicate with the same subscription started over SSE (when the `Accept` header is excluded from the fingerprint). See [Inbound Deduplication](/docs/router/guides/performance-tuning#inbound-deduplication) for details.
0 commit comments