When to add a queue

Start with the PDF upload requirement, find where the request path becomes fragile, then improve the design with a queue-backed path without losing interview scope.

System design deep dive8:46 video + written guideBy Daniyal Saqib
Watch the walkthrough, then follow the written guide below.Watch on YouTube
Learning depth

Derive the async boundary, keep accepted work recoverable, and distinguish waiting space from processing capacity.

7 sections in this guide.
01 / Requirement

Begin with the product requirement

Adding a queue is easy. Explaining why it belongs in the design is the part that matters.

Candidates sometimes add Kafka, SQS, or another messaging system as soon as they notice a slow operation. But “this operation is slow” is not enough to justify a queue. A stronger explanation connects the queue to a requirement, identifies the coupling in the current design, and states both what the queue improves and what it cannot solve.

Running example

Make an uploaded PDF useful inside the product

A user uploads a PDF. The goal is to make the document searchable so chat, search, or another product surface can reference it. For now, ignore the internal processing steps and focus on one question: must all of that work remain inside the upload request?

Hand-drawn Excalidraw diagram showing a client uploading a PDF, the upload service storing it in object storage, fast acknowledgement, later document processing, and a searchable documentHand-drawn Excalidraw diagram showing a client uploading a PDF, the upload service storing it in object storage, fast acknowledgement, later document processing, and a searchable document
The requirement. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

The product needs fast acknowledgement of a durable upload. Making the PDF searchable can finish afterward.

If document processing does not need to finish before we respond to the user, when and why should we move that work behind a queue?

In the diagram, “fast acknowledgement” means the system has taken responsibility for the document and its ingestion job. “Searchable document” is a later state in which the required processing is complete and the document is available to retrieval. That requirement creates an asynchronous boundary. The queue is a possible mechanism for implementing it, not the starting assumption.

02 / Baseline

Start without a queue

The simplest version performs the entire ingestion pipeline before returning success.

Hand-drawn Excalidraw diagram showing the synchronous request path from the client and API gateway through the ingestion service, OCR, compliance, embeddings, and search index before returning 200 OKHand-drawn Excalidraw diagram showing the synchronous request path from the client and API gateway through the ingestion service, OCR, compliance, embeddings, and search index before returning 200 OK
Naive synchronous path. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

The response returns only after OCR, compliance, embeddings, and search indexing have finished.

This can be reasonable at low volume. “Synchronous” does not mean the service processes only one request at a time. The service may handle many requests concurrently. The problem is that every open request remains coupled to the slowest and most variable stage.

Hand-drawn Excalidraw diagram showing several clients converging on the API gateway and ingestion service while requests remain open through slow OCR, compliance, throttled embeddings, and search indexingHand-drawn Excalidraw diagram showing several clients converging on the API gateway and ingestion service while requests remain open through slow OCR, compliance, throttled embeddings, and search indexing
What breaks under load. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

Concurrent clients keep requests open while slow OCR and throttled embeddings constrain the processing path.

As the system reaches one of those limits, new requests wait behind the constrained stage. They may slow down, time out, or be rejected. Client retries can then add work to a system already under pressure.

Say this out loud

Request-handling capacity is coupled to document-processing capacity, even though the user does not need processing to finish inside the request.

03 / Boundary

Separate acceptance from processing

Move only the work that can safely finish after the response.

Hand-drawn Excalidraw diagram separating the client, API gateway, ingestion service, validation, and 202 Accepted response from later OCR, compliance, embeddings, and search indexingHand-drawn Excalidraw diagram separating the client, API gateway, ingestion service, validation, and 202 Accepted response from later OCR, compliance, embeddings, and search indexing
The asynchronous boundary. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

Validation and the ingestion record belong before the response. OCR, compliance, embeddings, and indexing can finish later.

Durable-acceptance invariant

Do not return success while a process failure could leave an accepted job with no recoverable path to the queue. One implementation stores the document first, then atomically creates the ingestion job and a pending handoff record. A dispatcher publishes that pending work to the queue. The mechanism can vary; the invariant cannot.

The API can return 202 Accepted with an ingestion ID. In HTTP, that means the request was accepted for processing but processing has not completed. The status code is intentionally noncommittal and does not guarantee eventual success by itself.

This API defines a stronger application contract: after it returns 202 Accepted, the document and a recoverable record of the ingestion work are durable, and the system tracks the job to a terminal status.

202 response
{
  "ingestion_id": "ing-123",
  "status": "ACCEPTED",
  "status_url": "/ingestions/ing-123"
}

The status can move from ACCEPTED to QUEUED, PROCESSING, and finally READY or FAILED.

04 / Improvement

Improve the design with a queue-backed path

Introduce the queue after the accepted upload so pending work can wait durably until processing capacity becomes available.

Hand-drawn Excalidraw diagram showing a client, API gateway, ingestion service, object storage, status store, job queue, worker pool, and the processing path to the search indexHand-drawn Excalidraw diagram showing a client, API gateway, ingestion service, object storage, status store, job queue, worker pool, and the processing path to the search index
Queue-backed ingestion. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

The API returns 202 Accepted after durable acceptance, then the queue holds small pending jobs until workers can run OCR, checks, embeddings, and indexing.

The queue does not process the PDF. Workers process the PDF.

The queue holds a message that tells a worker which job is ready.

Representative queue message
{
  "ingestion_id": "ing-123",
  "document_id": "doc-456",
  "tenant_id": "tenant-7",
  "object_key": "uploads/doc-456.pdf"
}

The message contains identifiers and a storage reference instead of PDF bytes. Object storage owns the document. The queue carries enough information for a worker to find and process it.

Hand-drawn Excalidraw diagram showing a job queue delivering work to a worker, the worker fetching from object storage, running OCR compliance and embeddings, writing the search index and status store, then acknowledging after successHand-drawn Excalidraw diagram showing a job queue delivering work to a worker, the worker fetching from object storage, running OCR compliance and embeddings, writing the search index and status store, then acknowledging after success
Worker processing and job status. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

A worker fetches the PDF, marks the job as processing, performs the pipeline, marks it ready, and acknowledges the queue only after success. At-least-once delivery makes idempotent processing necessary.

TermMeaning in this design
RequestThe client's HTTP interaction with the ingestion service
JobThe durable unit of document-ingestion work
MessageThe queue entry announcing that a job is ready
DispatcherThe process that publishes recoverable pending jobs to the queue
QueueThe component that stores and distributes pending messages
WorkerThe process that executes or coordinates the ingestion job
05 / Consequence

A queue changes where the work waits

It can make waiting durable and controllable. It cannot make the bottleneck disappear.

Shorter request path

The client waits for durable acceptance, not OCR, embeddings, and indexing.

Explicit waiting

Pending work becomes jobs and messages instead of open requests or fragile in-process tasks.

Controlled concurrency

Workers can pull at a rate that protects a bounded downstream dependency.

Independent scaling

The request path and worker pool can scale according to different pressures.

Capacity check

A queue does not create processing capacity.

We changed where the document waits and how that waiting is managed. We did not make one document finish faster.

Temporary burst: the backlog drains

Arrival falls below processing

Uploads briefly arrive faster than workers can process them. Once the spike ends, the workers keep consuming jobs until the queue is empty.

1. many PDFs arrive2. input rate falls3. backlog drainsPDF uploadstemporary spike8 PDFs injob queue5 jobs outworkersconsume jobsqueue depth returns to zerothe spike ends, so processing eventually catches up

Temporary burst

Sustained overload: the backlog keeps growing

Arrival stays above processing

Workers remain busy, but new jobs arrive faster than they finish. The queue eventually reaches a limit, so the system must scale, throttle, or reject work.

1. PDFs keep arriving2. input stays > output3. limit is reachedPDF uploadssustained rate14 PDFs injob queue4 jobs outworkersstill processingqueue limitscale, throttle, or reject new workthe workers stay busy, but the system never catches up

Sustained overload

Adding workers helps only until they encounter the same shared OCR, embedding, database, or indexing constraint. A queue is effective when the processing system can catch up after a finite burst. It is not a capacity plan when the arrival rate remains above the processing rate.

06 / Technology

Choose from the required behavior

Only after deriving the need for a queue should you name a product.

The requirements we have today

  • Each document creates an independent job
  • One worker from the pool should process it
  • Global ordering is not required
  • Historical upload events do not need replay
  • Several consumer groups do not need the same event
Hand-drawn Excalidraw decision diagram comparing SQS Standard for independent jobs with Kafka for retained history, replay, partition ordering, and multiple consumer groupsHand-drawn Excalidraw decision diagram comparing SQS Standard for independent jobs with Kafka for retained history, replay, partition ordering, and multiple consumer groups
Choose SQS or Kafka from the required behavior. Original video diagram. Open the image at full size; scroll horizontally on smaller screens.

Independent jobs with no replay or global-ordering requirement point toward SQS Standard. Retained history, replay, partition ordering, or multiple consumer groups make Kafka more compelling.

Choose for this design

Amazon SQS Standard

A sensible AWS starting point for independent pending jobs claimed by one logical worker pool. Standard queues use at-least-once delivery and best-effort ordering, so processing must tolerate duplicate delivery.

Reconsider when requirements change

Apache Kafka

More compelling when retained history, replay, partition-level ordering, or several independent consumer groups become central to the design.

RequirementStarting abstraction
Independent background jobs claimed by a worker poolWork queue such as SQS
Retained event history and replayEvent log such as Kafka
Several independent consumer groups need the same eventEvent log such as Kafka
Ordering within a defined stream is centralA system with explicit ordering semantics

The comparison is not “SQS is good and Kafka is bad.” For these requirements, start with SQS. If replay, retained history, multiple independent consumers, or partition ordering becomes central, reconsider Kafka. Naming the requirement that would reverse your decision is strong interview signal.

07 / Decision pillars

Know when a queue belongs in the design

Look for evidence in the workload and product contract before reaching for a queue or naming a technology.

Queue selection framework

The pillars for deciding whether to introduce a queue

Start with the lifecycle of the request, then test whether the work needs a durable lifetime, buffering, or controlled consumption. These signals tell you when a queue solves a real problem and when it would only add complexity.

01

Request lifecycle

Does the work need to finish before the user receives a response?

Queue signal: The product can acknowledge a durable upload now and let expensive processing finish later.

Why it matters: This is the first reason to create an asynchronous boundary. If the result is required immediately, a queue may not help the request contract.

02

Work duration and variability

Is the processing slow, unpredictable, or likely to exceed request timeouts?

Queue signal: OCR, compliance checks, embeddings, or indexing vary enough that holding the request open creates fragile coupling.

Why it matters: Queues are useful when the lifetime of the work should not be constrained by the lifetime of one HTTP request.

03

Durability and recovery

Must accepted work survive a process crash, deployment, or temporary dependency outage?

Queue signal: The system needs a recoverable handoff and a durable place for pending jobs to wait.

Why it matters: A queue becomes valuable when work must outlive the service instance that accepted it.

04

Rate mismatch and burstiness

Can arrivals temporarily exceed the rate at which workers or dependencies can process them?

Queue signal: A finite spike creates a backlog that the processing system can drain after arrivals fall.

Why it matters: This is the buffering case a queue solves well. If arrivals remain above throughput, capacity or admission control is still required.

05

Downstream protection

Does a bounded dependency need protection from uncontrolled concurrency?

Queue signal: Workers should pull jobs at a controlled rate that OCR, the embedding service, or the search index can sustain.

Why it matters: A queue can turn a flood of requests into managed concurrency and make backpressure explicit.

06

Delivery and consumption model

Should one worker claim each job, and what delivery, ordering, replay, or fan-out behavior is required?

Queue signal: Independent jobs fit a work queue; retained history or several independent consumers may point toward an event log.

Why it matters: Recognizing that a queue belongs in the design is separate from choosing the correct queue technology and processing semantics.

Checkpoint

Documents arrive faster than the workers can process them. Does adding a queue make the backlog drain? What needs to change?

Compare your reasoning

The queue holds pending work, but it does not add processing capacity. A temporary burst drains only when effective processing throughput exceeds new arrivals. Sustained overload requires more effective capacity, less work per document, or admission control, while respecting downstream limits.

Scope boundary

This resource stops at introducing and defending the queue-backed boundary. Retry policies, visibility timeouts, dead-letter queues, worker autoscaling, multi-stage workflow orchestration, and a complete document-ingestion platform are separate deep dives.

Comments

Drag IL Pet to any screen edge. Use Shift with an arrow key to change edges, arrow keys to move along an edge, and Home to reset.

Follow the next connection.

New deep dives, straight to your inbox.

Get new free resources as they’re published.

New resources only. Unsubscribe anytime.