Batch & Stream Processing

Turning raw event streams into answers. The two paradigms, windowing over time, and the sketches that make counting at scale affordable.

MapReduce Stream topologies Windowing Watermarks Lambda / Kappa Sketches
๐ŸŒŠ

The Two Paradigms

Batch processes a bounded, finite dataset โ€” yesterday's logs, the whole user table โ€” in one big job. High throughput, high latency: answers arrive in minutes to hours. Stream processes an unbounded, never-ending flow of events, producing results within seconds of each event arriving.

The split is really input shape. Batch has an end; stream never does. Most real systems run both: a stream layer for fresh, approximate answers and a batch layer for complete, correct ones.

  BATCH                                 STREAM
  [ bounded dataset ]                   โ€ฆeventโ€ฆeventโ€ฆeventโ€ฆโ–ถ (never ends)
        โ”‚  run over all of it                 โ”‚  process each as it arrives
        โ–ผ                                      โ–ผ
   result in minutesโ€“hours               result in seconds
   high throughput, high latency         low latency, incremental
   "daily report", "reindex everything"  "trending now", "live dashboard"
โ„น๏ธ
This page sits behind questions like "design ad-click aggregation," "design trending topics," and "design a metrics pipeline." The first move on any of them is deciding how fresh the answer must be โ€” that alone tells you batch, stream, or both.
๐Ÿ—บ

Batch Fundamentals

MapReduce is the mental model even when the engine is modern. Map transforms each input record into key-value pairs in parallel. Shuffle groups all pairs with the same key onto the same node. Reduce aggregates each group. Word count: map emits (word, 1), shuffle gathers each word, reduce sums.

  input split โ”€โ–ถ MAP โ”€โ–ถ (k,v) pairs โ”€โ”
  input split โ”€โ–ถ MAP โ”€โ–ถ (k,v) pairs โ”€โ”ผโ”€ SHUFFLE โ”€โ–ถ REDUCE โ”€โ–ถ output
  input split โ”€โ–ถ MAP โ”€โ–ถ (k,v) pairs โ”€โ”˜  (group by key)   (aggregate)
                  โ–ฒ                        โ–ฒ
             parallel, cheap          the EXPENSIVE part:
                                      moves data across the network

The shuffle is where the cost lives โ€” it moves data across the network to co-locate keys, and it's the bottleneck of every batch job. Modern engines like Spark keep the same map/shuffle/reduce model but run in memory and chain stages, cutting the disk round trips MapReduce paid between steps. ETL vs ELT is a related choice: transform before loading into the warehouse (ETL) or load raw and transform inside it (ELT, now the default given cheap warehouse compute).

๐Ÿ”€

Stream Fundamentals

Stream processing (Flink, Kafka Streams) runs events through a topology of operators โ€” a graph of transforms, filters, and aggregations that data flows through. Operators come in two kinds, and the difference drives everything hard about streaming.

Stateless operators easy

Each event handled independently โ€” map, filter, transform. No memory between events, so they scale trivially and recover for free. Any node can process any event.

Stateful operators the hard part

Aggregations, joins, counts โ€” they remember across events. That state must be partitioned by key, kept in memory, and checkpointed so it survives a crash. All the difficulty of streaming is managing this state.

โ„น๏ธ
Streams are fed by a durable log โ€” the replayable Kafka partition โ€” so a consumer can reprocess from an old offset after a bug or a new deployment. The log is the source of truth; the stream job is a materialized view over it (Messaging).
๐ŸชŸ

Windowing

You can't sum an infinite stream โ€” you sum a window of it. Three shapes cover most needs, and the deep problem is which clock defines them.

WindowShapeUse
TumblingFixed, non-overlapping (every 1 min)Per-minute counts, clean buckets
SlidingFixed size, overlapping (5 min, every 1 min)Moving averages, rolling metrics
SessionBounded by a gap of inactivityUser sessions, bursts of activity

The subtlety is event time vs processing time. Event time is when the event actually happened; processing time is when your system saw it. They differ because events arrive late and out of order โ€” a phone was offline, a network stalled. Bucket by processing time and a delayed event lands in the wrong window, corrupting the count.

๐Ÿ’ก
A watermark is the stream's answer: a moving signal that says "we've probably now seen every event up to time T." The system holds a window open until the watermark passes, absorbing late arrivals, then closes and emits. It's a bet โ€” set it aggressively for freshness and risk dropping stragglers, conservatively for completeness and pay latency. Naming event-time plus watermarks is the senior signal on any streaming question.
๐ŸŽฏ

Exactly-Once Processing

Streaming engines advertise "exactly-once," and it needs unpacking. Delivery over a network is at-least-once; what's achievable is exactly-once effect, built from three pieces: checkpointing (periodically snapshot operator state and input offsets together), replayable sources (rewind the log to the last checkpoint after a crash), and idempotent or transactional sinks (writing the same result twice has no extra effect).

โš ๏ธ
"Exactly-once" holds inside the engine's managed boundary โ€” its state and its offsets move as one atomic checkpoint. The moment output leaves for an external system, you're back to needing an idempotent or transactional sink to make replayed results harmless. Same principle as everywhere else: at-least-once delivery plus idempotency (Concurrency Control, Messaging).
๐Ÿ›

Lambda and Kappa Architectures

Lambda runs two layers in parallel: a batch layer that recomputes complete, correct results slowly, and a speed layer that gives fast approximate results now. Queries merge the two. The cost is maintaining the same logic twice, in two codebases that drift.

Kappa drops the batch layer. Keep everything as a replayable log and use the stream engine for both: for a "recompute from scratch," just replay the log from the beginning. One codebase, one system. Given durable logs and mature stream engines, kappa is winning.

  LAMBDA                                KAPPA
  events โ”€โ”ฌโ”€โ–ถ batch layer (slow, exact)  events โ”€โ–ถ log โ”€โ–ถ stream engine
          โ””โ”€โ–ถ speed layer (fast, approx)                    โ”‚
              โ”‚                                             โ”œโ”€ live results
              โ–ผ                                             โ””โ”€ reprocess by
          merge at query                                       replaying the log
   two codebases, they drift             one codebase, replay for correctness
๐Ÿ”ข

Top-K and Counting at Scale

"Trending topics" and "unique visitors" sound like GROUP BY. At billions of events, exact answers need too much memory โ€” a counter per distinct item, a set of every visitor ID. The move is probabilistic sketches: fixed-size structures that trade a small, bounded error for enormous memory savings.

NeedSketchTrades
Frequency of each itemCount-Min SketchMay overcount slightly, never undercounts
Count of distinct itemsHyperLogLog~2% error on cardinality, tiny memory
Top-K heavy hittersCount-Min + a heapApproximate ranking of the busiest keys

These merge cleanly, which is what makes them work in a distributed pipeline: each partition builds its own sketch, and you combine them into a global answer without re-scanning the data. Count per window (tumbling or sliding), keep heavy hitters per window, merge across partitions.

๐Ÿ’ก
The strong answer to "how do you count trending hashtags across billions of events" is not a giant hash map. It's "exact counting is unaffordable at this scale, so I'd use a count-min sketch for frequencies and HyperLogLog for uniques, per time window, merged across partitions." Naming the sketch is the whole point.
๐Ÿ“‹

Quick Reference

BatchStream
InputBounded, finiteUnbounded, continuous
LatencyMinutes to hoursSeconds
ThroughputVery highIncremental
ToolsSpark, MapReduceFlink, Kafka Streams
Question shapeTechnique
"Trending / top-K now"Count-Min + heap, over windows
"Unique visitors / distinct count"HyperLogLog
"Moving average / rolling metric"Sliding window
"Daily report / full recompute"Batch layer
"Late, out-of-order events"Event time + watermarks
โ„น๏ธ
The one-liners to keep ready. Batch is bounded and slow; stream is unbounded and fast; most systems need both. Shuffle is the cost of batch. Stateful stream operators need checkpointing; event-time windows need watermarks for late data. Exactly-once means at-least-once plus idempotent sinks. Kappa (one replayable log) is beating Lambda (two drifting layers). At scale, count with sketches, not hash maps.