← Back to Articles

Series map

flowchart TD
    subgraph F["Foundations"]
        direction LR
        P0["0 · Batch = Special Case"] --> P1["1 · Events vs Messages"] --> P2["2 · Two Clocks"]
    end
    subgraph L["Log-Based Processing"]
        direction LR
        P3["3 · Topics vs Queues"] --> P4["4 · Micro-batching Fails"]
    end
    subgraph S["State & Time"]
        direction LR
        P5["5 · Stateful Engines"] --> P6["6 · Windows"] --> P7["7 · Late Events"]
    end
    subgraph D["Design Decisions"]
        direction LR
        P8["8 · Joins"] --> P9["9 · Three Questions"]
    end
    F --> L --> S --> D
  1. 00

    Streaming Pill 0: Batch Is a Special Case of Streaming

    Most engineers learn streaming as batch, but faster. Kleppmann flips that model in Designing Data-Intensive Applications: batch is the special case, streaming is the default. This pill sets up the whole series.

    StreamingDDIABatch ProcessingData Engineering
  2. 01

    Streaming Pill 1: Events Are Not Messages

    A message tells one consumer what to do. An event tells everyone that something happened. Mixing the two up is how a streaming pipeline turns into a distributed RPC system.

    StreamingEvent-Driven ArchitectureKafkaDDIA
  3. 02

    Streaming Pill 2: Event Time and Processing Time Are Different Clocks

    Every event carries two timestamps: when it happened, and when your system saw it. Only one of them is trustworthy for correctness, and picking the wrong one silently corrupts your aggregates.

    StreamingEvent TimeWatermarksDDIA
  4. 03

    Streaming Pill 3: A Topic Is Not a Queue

    A queue deletes a message the moment it is read. A Kafka topic keeps every event on disk and lets many independent consumers replay the same history. That difference is why log-based systems changed streaming, and it mirrors how a database's write-ahead log works.

    StreamingKafkaWALDDIA
  5. 04

    Streaming Pill 4: Micro-Batching Is Not Streaming

    A SQL script that runs every 10 minutes looks like streaming from a distance. Three things break that idea: which events belong to which run, the growing cost of recomputing state, and how long the business can wait.

    StreamingMicro-batchingData EngineeringDDIA
  6. 05

    Streaming Pill 5: State Is the Real Bottleneck

    Lambda functions have no memory between invocations, so computing anything over time forces a round trip to an external database on every single event. Stateful engines like Flink solve this by keeping a key-value store next to the computation itself.

    StreamingFlinkStateRocksDB
  7. 06

    Streaming Pill 6: Windows Are a Design Decision, Not a Data Property

    A stream has no start or end, so any window you compute over it, tumbling, sliding, or session-based, is a choice about memory, accuracy, and latency, not something you discover in the data.

    StreamingWindowsFlinkStream Processing
  8. 07

    Streaming Pill 7: What to Do With a Late Event

    Networks fail and phones lose signal, so late events are guaranteed to happen, not a rare exception. Every streaming pipeline needs an explicit policy: drop the event and log it, or reopen the window and correct the result.

    StreamingWatermarksLate DataStream Processing
  9. 08

    Streaming Pill 8: Streaming Joins Are a Memory Problem

    In batch, a join is one SQL statement. In streaming, a join is a promise to hold data in memory for a period of time, because streams never end and you cannot join against everything.

    StreamingJoinsFlinkState
  10. 09

    Streaming Pill 9: Three Questions Before You Design a Streaming System

    Before reaching for Flink or Kafka Streams, three questions decide whether you need a stateful streaming engine at all: is the pipeline stateful, what is your tolerance for late data, and can you trust the clocks on your source events.

    StreamingArchitectureDecision FrameworkData Engineering