All templates
Sequence template

GraphQL subscription flow

Client subscribes, server establishes WebSocket, pushes real-time updates.

Real-time dashboards, live feeds, and collaborative apps all rely on pushing data from server to client the moment something changes. This template shows the GraphQL subscription flow: a client establishes a persistent WebSocket connection, the server listens for database changes (or events on a message bus), filters the update against the subscription query, and pushes only the relevant fields to the client. The server maintains the subscription until the client disconnects or unsubscribes.

The diagram makes visible the asymmetry between REST (request-response, client pulls) and subscriptions (persistent connection, server pushes). A real-time dashboard with 1,000 users polling every 5 seconds is 12,000 requests per hour; the same dashboard with subscriptions sends data only when it actually changes.

When to use this template

  • Building real-time features — design subscriptions for live dashboards, activity feeds, collaborative document editors, or live notifications so you understand the server-side listener and filtering logic before you code.
  • Capacity planning — subscription workload (persistent connections + listeners per subscription) is different from request workload. This diagram helps ops estimate memory and CPU for a given scale.
  • Explaining WebSocket to stakeholders — show why subscriptions are worth the complexity compared to polling for a feature that updates frequently.

How to adapt it

Start by replacing the generic Database with your data source and adding your specific event flow:

  • Change Event Bus to your real system (Redis Pub/Sub, RabbitMQ, Kafka) if you use message queues instead of direct database listeners.
  • Add filtering and transformation logic in the server after the event arrives to show how only matching updates are sent to each client.
  • Insert a heartbeat or ping-pong exchange before the data update to show how the server detects dead connections and the client keeps the socket alive.

Visual edits regenerate clean Mermaid code, so you can sketch your subscription architecture and export the result for your API documentation.

Mermaid code

Copy it anywhere Mermaid is supported — GitHub, Notion, or your docs.

sequenceDiagram
    actor Client
    participant Server as GraphQL Server
    participant DB as Database
    participant Bus as Event Bus

    Client->>Server: POST /graphql (subscription query)
    Server->>Server: Parse subscription query
    Server-->>Client: 101 Switching Protocols (WebSocket)
    activate Server
    Note over Server: Subscribe to DB changes
    activate DB
    
    Client->>Server: Send via WebSocket
    Server->>DB: Register listener for table
    DB-->>Server: Listener registered
    
    Note over DB: Data changes (INSERT/UPDATE)
    DB->>Bus: Emit event
    Bus->>Server: Notification received
    Server->>Server: Filter update (matches query)
    Server-->>Client: GraphQL message + data
    Client->>Client: Render new data
    
    Client->>Server: Send via WebSocket (unsubscribe)
    Server->>DB: Unregister listener
    deactivate DB
    Server-->>Client: Subscription ended
    deactivate Server

Frequently asked questions

What is a GraphQL subscription flow?
It shows how a client subscribes to real-time data over a persistent WebSocket connection. The server registers listeners on the database, and when data changes, the server filters the update against the subscription query and pushes only the relevant changes to the client. It's the foundation for live dashboards, collaborative editing, and real-time notifications.
Why use WebSocket instead of polling for real-time data?
Polling requires the client to ask 'any updates yet?' every few seconds, wasting bandwidth and battery on requests that return no data. WebSocket is persistent: the server pushes updates only when data actually changes. For a dashboard with 100 clients polling every 5 seconds, that's 1,200 wasted requests per hour if nothing changes; subscriptions send zero.
How do I handle subscription errors or disconnections?
Add error messages and a reconnection flow: if the WebSocket closes, the client queues mutations offline and reconnects. The server should clean up listeners if a client disconnects ungracefully. Many production systems add exponential backoff for reconnection attempts and heartbeat pings to detect dead connections.
Can I use GraphQL subscriptions with databases that don't support listeners?
Yes — instead of database change listeners, use a message queue or event bus (Redis Pub/Sub, RabbitMQ, Kafka). The application publishes events when data changes, and the subscription handler receives them from the queue. This is more scalable for multi-server deployments where each instance needs to hear about changes.

Related templates