Two Years of Every Click

A hard Pipeline Design interview practice problem on DataDriven. Design the pipeline on the canvas: sources, transforms, storage and checks, then get feedback on it.

Domain
Pipeline Design
Difficulty
hard
Seniority
L7
Asked in
Walmart

Problem

Our e-commerce site generates 600 million clickstream events per day through Kafka. Analytics needs this data for user behavior analysis, funnel conversion, and A/B test evaluation, and retention policy requires two years of history. Design the storage and ingestion pipeline.

Every click, every aisle, every day for two years.

Business requirements

Worked solution and explanation

The trap is one warehouse holding two years

This is an access-pattern problem dressed up as a storage problem. Anyone can draw Kafka into a warehouse. What separates candidates is seeing that four requirements want four different things: fast recent queries, rare older queries, a minutes-fresh view for marketing, and a buffer for 10x spikes. Get it wrong and you pay warehouse compute on two-year data almost nobody touches, while a flash sale saturates the same compute marketing is watching.

Step 1: Land every event once in cold object storage

The Iceberg lake, partitioned by event date, is the system of record for all two years. It is cheap, and it keeps the rare six-month-old query possible. Nothing else has to hold the full history.

Step 2: Mirror only the recent window into a fast warehouse

Most queries hit the last month, so only that slice earns warehouse prices. Older partitions are read in place by a serverless SQL engine billed by bytes scanned: slower, but the bill follows the access pattern.

Step 3: Fork marketing off the buffer, not off the lake

A Flink job reads the buffer and keeps a conversion view fresh in seconds, so the flash-sale dashboard never waits on batch. Analytics reads the batch path and tolerates T+1, so it never pays streaming compute.

Step 4: Absorb the 10x spike in the queue

Both paths read from a Kafka buffer, so a spike becomes consumer lag that drains afterward instead of dropped events. Size the consumers for normal load and let queue depth carry the surge.

The buffer feeds a streaming path for marketing and a batch path into the lake. The lake holds all history; only recent data is mirrored to the warehouse.
  • web clickstream (source, API)
  • event buffer (queue, Kafka)
  • streaming aggregator (transform, Flink); freshness: real-time
  • marketing store (storage, PostgreSQL)
  • lake writer (transform, Spark)
  • event lake (storage, Iceberg)
  • recent warehouse (storage, warehouse); freshness: < 1h
  • cold query engine (transform, SQL)
  • marketing dashboard (consumer, Grafana)
  • analytics dashboard (consumer, Metabase)
  • web clickstream -> event buffer
  • event buffer -> streaming aggregator
  • event buffer -> lake writer
  • streaming aggregator -> marketing store
  • marketing store -> marketing dashboard
  • lake writer -> event lake
  • event lake -> recent warehouse
  • event lake -> cold query engine
  • recent warehouse -> analytics dashboard
  • cold query engine -> analytics dashboard
One warehouse, two years
Every query pays warehouse compute, older queries still scan wide, and marketing shares compute with the sale spike.
Lake plus recent warehouse
History sits in cheap Iceberg partitions, the warehouse holds only the hot window, and marketing has its own streaming path.

Common follow-up questions