GraphQL in Production · Advanced GraphQL

Subscriptions and Live Data

Real-time updates with graphql-ws, SSE and incremental delivery.

Subscriptions push events to clients, typically over WebSockets using the graphql-transport-ws protocol (the graphql-ws library) or over Server-Sent Events (graphql-sse), which works better with HTTP infrastructure. Back them with a pub/sub system (Redis, Kafka, NATS) so any server instance can deliver events, authenticate at connection time, authorize each event, and keep payloads small (clients can refetch details). For progressively loading slow parts of a query, @defer/@stream (incremental delivery) are supported by several servers while the spec work continues.

Live data options

Criterion graphql-ws (WebSocket) graphql-sse (SSE) Polling query
Direction Bidirectional Server → client Client pulls
Infra friendliness Needs WS support/sticky LB Plain HTTP Plain HTTP
Latency Low Low Interval
Complexity Higher Medium Lowest
type Subscription {
  orderStatusChanged(orderId: ID!): OrderStatusEvent!
}
type OrderStatusEvent { orderId: ID!  status: OrderStatus!  at: DateTime! }

subscription OnOrder($id: ID!) { orderStatusChanged(orderId: $id) { status at } }

Common pitfalls

  • In-memory pub/sub that only works on one instance.
  • Auth checked at connect but not per event.
  • Subscriptions for data that changes rarely (polling is simpler).

Key points

  • graphql-ws or SSE transports
  • Shared pub/sub backend
  • Authorize per event

Further reading: graphql-ws

Practice questions

Why do GraphQL subscriptions need a shared pub/sub backend in production?

Answer

Clients connect to different server instances; events published on one instance must reach subscribers on all others.

When is polling a better choice than subscriptions?

Answer

When updates are infrequent or eventual freshness is acceptable; polling is simpler to operate and cache.

Open in the app to mark lessons complete, take notes and track your progress.