Subscriptions & Real-Time Data
You'll learn to
- -Define a GraphQL subscription and explain how it differs structurally from a query or mutation
- -Design event filtering so a subscriber only receives updates relevant to what they actually subscribed to
Queries and mutations are both request-response - the client asks, the server answers once. A subscription is GraphQL's third root operation type, for cases where the client wants to be pushed updates over time rather than asking repeatedly: new messages in a chat, live order status changes, a live-updating dashboard.
Defining a Subscription
type Subscription {
orderStatusChanged(orderId: ID!): Order!
}
subscription {
orderStatusChanged(orderId: "501") {
id
status
updatedAt
}
}A subscription is defined the same way as a query field, but instead of resolving once and returning, it stays open (typically over a WebSocket) and pushes a new payload to the client every time the underlying event fires - here, every time order 501's status actually changes, not on a polling interval.
Filtering: Only Send What This Subscriber Asked For
def resolve_order_status_changed(root, info, order_id):
# A shared pubsub channel receives events for EVERY order.
# This subscriber only asked about order_id="501" - filter here,
# not at the client, so irrelevant events never even get pushed.
return pubsub.subscribe("order_status_changed", filter_fn=
lambda event: event["order_id"] == order_id
)The naive mistake is pushing every event on a shared channel to every subscriber and letting the client filter client-side - that wastes bandwidth on data the client will just discard, and for a busy system (thousands of orders changing status per minute) it means every subscriber's connection carries irrelevant traffic. Filtering server-side, scoped to exactly the arguments this specific subscriber provided (`orderId: "501"`), means each client's connection only ever carries events it actually asked for.
Subscriptions Are Not a Replacement for Queries
A subscription typically pushes the delta or the changed state, not the full picture a client needs on first load - a well-designed real-time feature usually pairs an initial query (to fetch the current full state when the client first connects) with a subscription (to receive updates from that point forward), rather than expecting the subscription alone to somehow deliver both the initial state and every subsequent change.
Subscriptions hold an open connection per subscribed client, which is a meaningfully different resource cost than a stateless request-response query - at real scale, this needs its own connection-management and horizontal-scaling story (a pubsub backend fanning out to many server instances), not just "add a WebSocket handler" bolted onto the existing query/mutation infrastructure.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.
Design Real-Time Feed in the API Design Lab's GraphQL Mastery act.