advanced
3 min answer
A million devices report telemetry every ten seconds. How should ingest, buffering, backpressure and storage be designed, and where do naive designs fail?
Show the full answer Hide the answer
The arithmetic first
A million devices at one message per ten seconds is 100,000 messages per second, sustained, with no natural quiet period. The characteristics that matter:
- Small messages at very high rate, so per-message overhead dominates — protocol handshakes, connection setup, authentication and serialisation cost more than the payload.
- Write-heavy with almost no reads on the ingest path.
- Devices with intermittent connectivity, which buffer and then burst.
- A long tail of misbehaving devices — a firmware bug that reports every second instead of every ten, a device stuck in a reconnection loop, a clock set to 1970.
The design
- A protocol suited to the shape: MQTT or similar with persistent connections and small framing, rather than a fresh HTTPS request per message. Connection establishment and TLS handshakes at 100,000 per second are the dominant cost in a naive design, and persistent connections remove them.
- Edge or gateway aggregation where the topology permits, so many devices report through one connection and the ingest tier sees far fewer.
- Batching on the device, sending ten readings every hundred seconds rather than one every ten — which reduces the message rate by an order of magnitude and trades a small amount of freshness for it. This is usually the highest-value change available.
- A durable log at the ingest boundary, decoupling acceptance from processing so a slow consumer does not reject device data.
- Partitioning by device identifier, giving per-device ordering and horizontal parallelism.
- A time-series or columnar store for the retained data, with downsampling: full resolution for days, aggregates for months, since almost all queries are recent and the retention cost is otherwise unbounded.
Backpressure and misbehaviour
- Per-device rate limits enforced at the edge, because a firmware bug in a fleet of a million devices is a distributed denial of service against your own platform, and it will happen.
- Reject cheaply, so a rejection costs far less than acceptance — otherwise the limiter is the bottleneck.
- Server-directed backoff, telling devices when to return, since client-side backoff cannot be updated on devices already in the field and that is exactly where the problem originates.
- Jittered reconnection, mandatory, or a platform blip produces a synchronised reconnection storm from a million devices — the recovery load being an order of magnitude above steady state, which is the failure that turns a short outage into a long one.
- Bounded per-device buffering on the device, with an eviction policy chosen deliberately.
- Quarantine for misbehaving devices, so one bad firmware cohort can be isolated without affecting the rest.
Where naive designs fail
- A request per message over HTTPS, dominated by handshake cost.
- Synchronous writes to a database on the ingest path, coupling device acceptance to database availability.
- No per-device limits, so a firmware bug saturates the platform.
- Unjittered reconnection, producing a self-sustaining storm after any blip.
- Trusting device timestamps, where clock skew and unset clocks produce data far outside the expected window — so both device time and server receipt time must be recorded, and the ingest must handle a device claiming 1970.
- Full-resolution retention forever, which is an unbounded and rapidly dominant cost.
- Ingest capacity planned for average rather than for the reconnection burst, which is the number that actually matters.