System Design · hard · Reported at Netflix

Design a data pipeline to ingest 1B events/day.

Asked in Data Engineer interviews, in the System Design round.

Short answer

Kafka ingestion -> stream/batch processing (Spark/Flink) -> warehouse/lake, partition & schema mgmt.

Ingestion pipeline from producers through a log and object storage to the warehouse Producers Apps Append log Buffers peaks Stream job Validate Object store Raw, immutable Warehouse Modeled, BI Dead letter Would not parse
1B a day is about 11,600 events a second. Buffer the peak, keep raw immutable.

How to answer it

Requirements first

Say the numbers out loud before drawing anything. A billion a day is about 11,600 events per second on average, and peak is what you size for, usually three to five times that. At 1KB per event that is a terabyte a day, so retention and storage cost are part of the design rather than a footnote.

Then the questions that change the architecture:

Architecture

The diagram above is the shape. Each box exists for a reason:

Delivery semantics

at most once     fast, drops on failure. Rarely acceptable.
at least once    the practical default. Duplicates WILL happen.
exactly once     expensive end to end, and usually unnecessary.

The affordable answer is at least once plus idempotent consumers keyed on an event id, which gives the same result as exactly once without the cost. Say that phrase; it is what the question is testing.

Scaling and cost

Failure modes

Key points

FAQ

The 30-second answer

First the arithmetic: a billion a day is around eleven thousand six hundred events a second on average, and I would size for a peak several times that.
The shape I would draw is producers writing to an append-only log, a stream job that validates and enriches, raw events landing immutably in object storage partitioned by date, and a transform into the warehouse for BI. The log is there to decouple producers from consumers so a slow consumer creates lag rather than loss, and the immutable raw layer is there so a modeling bug becomes a replay rather than an incident.
On guarantees I would aim for at least once delivery with idempotent consumers keyed on an event id, because that gets exactly-once results without exactly-once cost. And anything unparseable goes to a dead-letter topic, so one bad event cannot block a partition.

In the interview

Practice this for real