Most data pipelines that fail in production don't have a technology problem. They have an architecture problem — built for an ideal world that doesn't exist in production.
In the real world, data arrives late. Events come out of order. State corrupts in unexpected ways. And the system that worked perfectly in testing collapses under production load. This article is about understanding why these failures happen — not about generic fix-it checklists.
Mistake One: Trusting Processing Time Over Event Time
Most teams build their pipelines around processing time — the moment data arrives at the system. It's simple and works in development. The problem: in production, data arrives from multiple sources with different delays.
Consider a real-time trading system. An event timestamped 14:30:00 arrives at your pipeline at 14:32:15 due to network latency or an upstream system issue. If your aggregation window is based on processing time, that event lands in the wrong window. The result: wrong statistics, wrong decisions downstream.
The architectural fix is to use event time — the actual timestamp embedded in the event — and define a watermark strategy that specifies how long you're willing to wait for late data. Apache Flink provides this mechanism natively, but tuning your watermark strategy is itself a serious architectural decision. Too tight a watermark and you discard valid late-arriving data. Too loose and your system latency increases across the board. There's no free lunch here.
Mistake Two: Stateful Processing Without Real State Management
Stateful processing means computations that depend on the history of prior events. A simple example: calculating a moving average for a financial instrument over a rolling time window. The state here is the recent price history you need to retain.
The common mistake is keeping state in memory with no plan for failure recovery. When a cluster node crashes, all its in-memory state is gone. The system restarts — but from where? With what state?
A proper architecture requires three things. First, choose the right state backend: RocksDB for large state volumes, in-memory backends for small, latency-sensitive state. Second, implement regular checkpointing so recovery can happen from a known-good point rather than from scratch. Third, explicitly define exactly-once semantics — guaranteeing each event is processed precisely once. In financial systems this last point is not optional. A transaction processed twice is not an edge case; it's a catastrophic failure.
Mistake Three: Ignoring Backpressure
Backpressure occurs when one stage of a pipeline produces data faster than the next stage can consume it. The theory is simple. The practice is messy — most pipelines have no explicit mechanism to handle it.
The typical consequence: buffers fill up, memory spikes, garbage collection pressure escalates, and the system either degrades or crashes. This pattern is especially visible in systems with burst traffic — financial markets during major news events are a textbook example.
The right architecture treats backpressure as a first-class citizen. Apache Kafka can act as a natural buffer between producers and consumers, absorbing burst load elegantly — but only if consumer groups and partition counts are designed correctly for your throughput profile. Don't treat Kafka as a magic buffer. A misconfigured Kafka cluster can be just as catastrophic as having no buffer at all.
Operational Reality: A Concrete Example
Imagine a financial transaction processing pipeline handling several million events per day. During normal hours, everything runs cleanly. Then quarterly earnings announcements hit — transaction volume spikes 10x in minutes.
If the pipeline operates on processing time, windowed aggregations break immediately. If state management is weak and a node crashes under load, you're looking at reprocessing the entire day's events — which takes hours. If backpressure is unhandled, the whole system cascades into failure. Three architectural mistakes, one catastrophic outcome.
The solution in this case wasn't a full rewrite. It was three targeted architectural changes: migrating to event time with a watermark strategy aligned to the system's SLA, enabling incremental checkpointing in Flink at 30-second intervals, and introducing Kafka with partitioning by instrument type to isolate burst traffic from normal flow. Each change addressed one specific failure mode.
A data pipeline that fails in production is rarely a sign that you chose the wrong technology. It's a sign that the architecture wasn't designed for failure. Stable systems are engineered for failure first — success takes care of itself.
Comments (0)
You need to log in to post a comment.
Login / Sign up