Engineering

Most real-time analytics is a five minute cron job

Published
Author
Tomás Reyes
Reading
4 min

The gap between a dashboard that says live and a dashboard that is live, and why the difference only shows up on the day it matters.

There is a badge on a lot of analytics products that says Live. Behind a fair number of them is a scheduled job running every five minutes.

That is not a scandal. Five minute freshness is fine for most questions. The problem is that the badge sets an expectation about a different class of question, and you only discover the gap on the day it matters.

Two kinds of question

Most analytics questions are retrospective. How did the August cohort convert. Which plan has the worst gross churn. For these, five minute freshness and five hour freshness give the same answer, because the underlying number barely moves.

A smaller set are operational. Did the release we shipped twenty minutes ago break signup. Is the queue draining. Did the alert fire because something is wrong, or because a batch job double counted. These questions have a half life measured in minutes, and stale data does not merely delay the answer. It produces a confidently wrong one.

Where the latency actually goes

When teams measure their own pipeline, the surprise is rarely the query. It is the wait before the query.

The client buffers events, sensibly, to avoid a request per interaction. Call it thirty seconds. The collector batches to object storage, another minute or two. The loader runs on a schedule. The transformation layer runs on its own schedule, usually keyed to the loader, usually with a safety margin. Then a caching layer holds the result for a while, because the dashboard is expensive to compute.

Each step is a reasonable engineering decision. Stacked, they turn an event into a number somewhere between four and forty minutes later, and the figure on screen carries no indication of which.

What to ask for instead of a badge

Ask what the pipeline does with an event that arrives late. Ask whether a query reads from the same store the writes land in, or from a derived copy. Ask what happens to a dashboard mid-refresh: does it show the old number, a partial number, or does it block.

Then ask for the freshness to be on screen. Not a badge, a timestamp on the panel saying what window the number covers. A dashboard that reads through 14:32 is more honest and more useful than one that reads live, and it costs a line of markup.

Our own answer

Ether queries the same store that writes land in, and every panel carries its own coverage window. The number in our marketing copy is a p95 from event acknowledgement to query result, which is the part we control. What happens inside your client SDK buffer is yours, and we would rather say so than round it into a badge.