Your dashboard is lying by twelve hours
Moving from overnight batch to streaming pipelines, and knowing when real-time is genuinely worth the complexity.
part 1 of 2 · Data and AI that hold up in productionthe ideaA dashboard number is only as fresh as its last load, so show its age.
after reading, you can- Before acting on a dashboard number, ask how old it is, and whether that age matters for the decision you're making.
- Write a freshness SLO per consumer and put the measured lag on the dashboard it serves.
- Put each feed on streaming, micro-batch or daily batch, depending on what the decision behind it actually needs.
Every dashboard carries a timestamp nobody reads. The overnight ETLdefinitionStands for extract, transform, load. It's a job that copies data out of your source systems, reshapes it and drops it into a warehouse, often overnight. finished at 3 a.m., the meeting is at 3 p.m., and the number on screen is a description of yesterday. So before anyone acts on it, the honest question is: how old is the number you're about to make a decision with? For some decisions, twelve hours is fine. For others, it's the whole error.
If you move from batch to streaming, the main change is in what you'll promise about freshness. The technology matters less. We make three claims below, based on pipelines we've built and repaired.
Staleness is a decision tax, so measure it decision by decision
Data freshness only matters relative to the decision it feeds. Fraud holds, inventory rebalancing, surge pricing and incident response get worse by the minute. A quarterly revenue view genuinely doesn't. The failure mode is treating freshness as something the whole platform has ("we're a batch shop") instead of asking, decision by decision, what a twelve-hour-old input actually costs when it's wrong.
The practical tool is a freshness SLOdefinitionA written target for how far a data feed may fall behind its source, say a few minutes at most. You measure it continuously. per consumer: this feed will be no more than N minutes behind the source, measured continuously and displayed on the dashboard it serves. Writing those SLOs down does two things: it exposes which decisions are quietly running on stale inputs, and it kills the vague demand for "real-time everything" by attaching each freshness target to a consumer who has to justify it.
The real work is in the streaming semantics
Standing up Kafka is the easy week; the engineering is in the semantics. Event time and processing time diverge the moment a mobile client goes offline or a partition lags, so every aggregation needs a watermarkdefinitionThe rule a streaming job uses to decide how long it waits for late events before it closes a time window and spits out a result. policy: how long to wait for late events, and what to do with the ones that arrive after the window closed (drop them, or emit a correction downstream consumers must handle). A dashboard that silently ignores late data is just wrong faster.
Delivery guarantees deserve the same scrutiny. Exactly-once within a Flink or Kafka Streams topology is real; end-to-end exactly-once across your CDC source, broker and warehouse sink is a design you build: idempotent writesdefinitionWrites you can run once or several times and get the same result. They're why replaying events is safe: duplicates don't double-count., transactional sinks, keys that make replays safe. Change data capturedefinitionStreaming every insert, update and delete out of a database's log as events, so other systems see changes as they happen. with Debezium is the right front door for operational databases, but plan for schema evolution and for backfill from day one: the first production incident will be replaying three hours of events, and replay safety is either designed in or it isn't.
Real-time is a promise about how stale a decision is allowed to be. It isn't a refresh rate.
# freshness is measured, not assumed $ pipeline status --feed orders-live source: postgres · debezium cdc watermark lag: 42s slo: < 120s late events: 0.3% → corrections emitted downstream ✓ slo met · ✓ replay-safe · ✓ lag on the dashboard it serves
Real-time must earn its keep: tier the pipeline instead of converting it
Streaming everything is how a data platform doubles its operational surface for the handful of feeds anyone needed fresh. A streaming pipeline is a 24/7 distributed system, with on-call, backpressure, state migrations and consumer-lag alerting to look after. That cost only pays off where the freshness SLO demands it. The architectures that hold up are tiered. True streaming goes to decisions measured in seconds. Incremental micro-batchdefinitionSmall, frequent batches, run every few minutes. Simpler to operate than true streaming, and close enough to live for a lot of feeds. or materialized views cover the many feeds where five to fifteen minutes is indistinguishable from live, and honest daily batch handles the rest.
The discipline is refusing to let "real-time" become a prestige label. Each feed's tier follows from its written SLO. Any tier upgrade has to name the decision that pays for it. And the lag metric ships on the dashboard itself, so the next time someone acts on a number, its age is part of the number. That's the fix for the twelve-hour lie. Staleness becomes something you can see, and something someone chose, where before it was invisible and inherited. Everything doesn't have to be instant.
What to take from this
- 01
Give each decision its own freshness SLO and show the data's age right on the dashboard that serves it.
- 02
Do the semantic work: watermarks and late-data policy, replay-safe idempotent sinks, CDC with schema evolution and backfill planned from day one.
- 03
Tier the pipeline. Streaming is for places where seconds matter and micro-batch for where minutes do. Everything else can be honest batch.
Three questions, about a minute
Pick an answer and we'll tell you if it's right, and why it is or isn't. The score stays in this browser.
-
Q1Someone on the team wants every pipeline moved to streaming. Which feed most clearly justifies what it'd cost to operate?
show the answer
D. Fraud holds that degrade by the minute The post says freshness only matters relative to the decision it feeds. A fraud hold loses value by the minute. A quarterly revenue view doesn't, so only the fraud feed earns a 24/7 streaming system.
-
Q2A mobile client reconnects, then sends events whose aggregation window already closed. What should the pipeline have defined up front?
show the answer
A. A watermark and late-data policy: drop them or emit a correction Event time and processing time diverge, so every aggregation needs a watermark policy. Skip it and you get what the post warns about: a dashboard that silently ignores late data is just wrong faster.
-
Q3People reading the dashboard are getting the twelve-hour lie. What one change fixes that most directly?
show the answer
C. Showing the measured data age on the dashboard itself The fix the post lands on is making staleness visible and chosen. Ship the lag metric on the dashboard and a number's age is part of the number, whatever tier the feed runs on, streaming or batch.