Practice this topic in a realistic system design interview
Whenever one part of a system needs data from another, someone has to make the first move.
That one choice affects how fresh the data is, where the load lands, and what happens during failures. Push and pull are the two basic answers.
In a push architecture, the producer sends data to the consumer when new data is available.
In a pull architecture, the consumer asks for data when it is ready to handle it.
Neither option is always better.
Push is a good fit when data must be fresh and consumers can keep up with the update rate. Pull is a good fit when consumers need control over speed, batch size, retries, and recovery.
Most production systems use both. A common pattern is to push a small notification, then let the client pull the larger data when it is ready.
This chapter covers push and pull architectures, their trade-offs, and how systems combine them.
In push architecture, the sender starts delivery.
The consumer does not keep asking, "Is there anything new?"
Instead, it keeps a channel open, exposes a URL, subscribes to a broker, or registers with a delivery service.
When new data arrives, the system sends it.
Mobile notifications through APNs or FCM are a familiar example, as are webhooks from payment providers, GitHub, Stripe, or CI systems.
Server-Sent Events handle one-way browser updates, while WebSocket messages power chat, collaboration, and multiplayer state.
Brokers can push directly to an HTTP subscriber URL. AI systems can also stream model output to a client after the client sends a request.
Push is not the same as "anything that feels live." Many video streaming systems use client-driven fetching over HTTP.
The video player pulls small chunks as it needs them. The user experience feels continuous, but under the hood, the player is often pulling data.
The sequence below shows a common push flow. The consumer may set things up first, but after that, the server can send updates without waiting for a new data request.
The consumer may still start the setup. A browser opens a WebSocket. A mobile app registers a device token. A webhook receiver exposes a URL.
After that setup, the server can deliver updates without waiting for a fresh data request.
Push works well only when failures are handled clearly. At minimum, design retries, timeouts, safe duplicate handling, and a way to recover missed data.
In pull architecture, the receiver starts data retrieval.
The consumer asks for work, data, or updates when it is ready.
That request may be a normal API call, a polling loop, a worker fetching jobs from a queue, or a stream consumer reading the next batch from a log.
A browser or mobile app fetching an API response is the simplest case. A dashboard polling every 30 seconds is another.
Workers pulling jobs from a queue, Kafka consumers fetching records from partitions, and batch jobs reading files from object storage all follow this pattern.
ETL pipelines pull changed data from a source system. Embedding workers pull documents to process at their own pace.
Pull is the default model for many systems because it gives the consumer control.
Here the consumer drives the flow. It asks for the next batch, processes it, and records progress on its own schedule.
The consumer can choose how often it asks for data, how many items it asks for, how many workers it runs, and when to slow down.
Pull is usually easier to keep stable under load. It may be less immediate, but the consumer has a clear control point: it can stop asking for more.
Push and pull are often discussed as client-server patterns, but the same choice matters inside messaging systems.
Some brokers push messages to subscribers. Others let consumers pull messages. Some support both.
| Delivery Mode | Who Starts Delivery? | Good For | Main Risk |
|---|---|---|---|
| Push | Broker or server | Webhooks, low-delay notifications, browser updates | Receiver overload and retry storms |
| Pull | Consumer or worker | Queues, streams, batch processing, AI pipelines | Polling delay and consumer-side complexity |
For example, a webhook system pushes events to an HTTP URL, while a queue worker pulls jobs when it has available threads.
A Kafka consumer pulls records and saves its position. A browser may receive pushed updates over WebSocket, then pull full details through an API.
Do not assume publish/subscribe, often called pub/sub, always means push. Many pub/sub and streaming systems use pull-based consumers because pull gives better batching, progress tracking, and overload control.
Backpressure means a slow consumer can tell the system, "I cannot handle more right now."
In pull systems, this is built into the pattern. A busy worker simply stops asking for more messages.
In push systems, you have to design that protection yourself.
Push systems need safeguards. That usually means per-consumer rate limits, limited-size queues, and retries that slow down after each failure.
Dead-letter queues catch messages that keep failing. Handlers should be safe to run more than once, because retries can create duplicates. Delivery timeouts prevent slow receivers from blocking the producer forever.
Circuit breakers help isolate failing receivers. A replay or catch-up path gives the system a way to recover missed events.
Without these, push delivery can turn a downstream outage into a system-wide incident.
Use push when fresh data matters more than consumer control.
User notifications are an obvious fit. A user should know quickly when a message, payment, or alert arrives.
Live collaboration is similar. Edits, cursors, and presence need low-delay updates.
Operational alerts also belong here, because humans and systems should receive incidents quickly.
Webhooks let external systems get callbacks when events happen. Streaming AI responses use push to send partial model output to a client, so the user sees progress sooner.
Use pull when control, batching, and recovery matter more than immediate delivery.
Background jobs are a natural fit because workers can process tasks at a controlled rate.
Data pipelines also benefit because consumers can read batches, save progress, and replay if needed.
Expensive processing like GPU inference, embeddings, transcoding, and document parsing all need strict limits on how much work runs at once.
Unreliable clients such as mobile apps and edge devices can sync when they reconnect. Large datasets are safer to expose through pagination, cursors, and saved positions than to push all at once.
As a quick shortcut: when updates must arrive as quickly as possible, choose push.
When the consumer needs to control how much work it takes on, choose pull. Large batches or expensive processing also favor pull.
Browsers receiving live updates often do well with push over SSE or WebSockets. Receivers that are often offline are usually better served by pull, or by a push notification followed by a later pull.
If you need replay from a saved position, pull from a log or queue. For external callbacks, use a push webhook with retries and safe duplicate handling.
The best design is often a combination.
A common mobile pattern is:
This avoids putting sensitive or large data in the notification. It also gives the app a reliable way to catch up if it missed earlier updates.
Webhooks are push-based, but well-built integrations also provide pull APIs.
If a payment webhook fails or arrives out of order, the receiver can call the provider's API to fetch the current payment state.
The webhook tells the receiver, "Something changed." The pull API tells it what the current truth is.
Long polling is a pull request that behaves partly like push.
The client sends a request. If the server has no update, it holds the request open until data arrives or a timeout occurs. The client then immediately sends another request.
This is useful when WebSockets are not available but the user still needs near-real-time updates.
Event streams such as Kafka-style logs often use pull consumers.
The producer writes events to the log. Consumers pull at their own pace and save their position. This gives strong control over replay, batching, and recovery.
That is often a better fit for internal data pipelines than pushing every event directly into every consumer.
A few questions help frame the choice.
Start with the freshness requirement: how fresh must the data be? Milliseconds, seconds, minutes, or hours?
Then think about rate control. Who should decide the pace: the producer, broker, consumer, or user?
Ask whether the consumer can be reached reliably. A public URL, mobile device, private worker, and offline client all behave differently.
Consider what happens when the consumer is slow. Should the system queue, drop, retry, delay, or reject extra work?
If consumers need replay, plan for a log, queue, cursor, or API that keeps enough history. Assume messages can be duplicated or arrive out of order, because most real systems must handle both.
Finally, look at data size. Large data usually belongs in storage, with events carrying references.
Push gives low-delay delivery, but it needs careful failure handling. Pull gives control and reliability, but it can add polling delay.
Use push when the system must notify quickly. Use pull when the consumer must process safely at its own pace. Use both when you need fast notification and reliable recovery.
Push and pull describe who starts data movement.
In a push architecture, the producer sends data as soon as it is available. This gives low-delay delivery, but it needs careful handling when a consumer is slow, unreachable, or offline.
In a pull architecture, the consumer requests data when it is ready. This gives control and reliability, but it can add polling delay.
The choice comes down to a few questions: how fresh the data must be, who controls the rate, whether the consumer can be reached reliably, and what should happen when a consumer falls behind.
Consumers that need replay need a log, queue, cursor, or API with enough history. Most real systems must assume messages can be duplicated or arrive out of order. Large data usually belongs in storage, with events carrying references.
Use push when the system must notify quickly. Use pull when the consumer must process at its own pace. Many systems combine the two, using push for fast notification and a pull path for reliable recovery.
10 quizzes