In our last article we walked through an IoT platform whose cloud bill dropped from ₹30,000 a month to under ₹10,000 a year. The single biggest lever was replacing polling with event-driven communication.
That article was a case study. This one is the playbook — the decision framework we use to work out whether a given platform should switch, and the migration path we follow when it should.
Because the honest answer isn't "always go event-driven." Sometimes polling is genuinely the right call. What matters is knowing which situation you're in before you've deployed 200 devices into the field.
The arithmetic nobody runs before deploying
Start with one device on a fixed interval. The message count is fully determined by the interval:
- Every 1 second → 86,400 messages per device per day
- Every 10 seconds → 8,640
- Every 30 seconds → 2,880
- Every 5 minutes → 288
- Every 1 hour → 24
Multiply by your fleet size, then by 30. A 50-device fleet on a 10-second interval produces roughly 13 million messages a month. A 200-device fleet on the same interval produces 52 million.
Now the part that actually costs money. Each of those messages typically triggers a chain:
- A TLS connection or request
- An ingress charge on the payload
- A function or container invocation to handle it
- One or more database writes
- A log line, which is itself billable storage
So "one ping" is rarely one line item. On request-priced managed cloud it's commonly four or five. That's why polling bills don't grow linearly with your device count — they grow linearly with your device count times your per-message fan-out, and the fan-out is the part nobody budgets for.
Here's the question that reframes it: what fraction of those messages carry information you didn't already have?
For the vending platform in the last article, a machine dispensed a few times a day and its state was otherwise static. Roughly 99.5% of its messages said "nothing has changed since the last time I told you nothing had changed." The business was paying full price for every one of them.
Why teams build polling anyway
Nobody chooses polling because they think it's better. They choose it because of these four reasons, and it's worth naming them honestly:
It's the mental model from web development. Request/response is how the web works. If your team came from building web apps and REST APIs, a device that periodically POSTs its status is the obvious design. Persistent bidirectional connections are a different shape and feel exotic until you've built one.
It's easier to debug on day one. A polling device makes an HTTP request you can curl, log, and replay. Debugging a stuck MQTT subscription at 2am is genuinely harder than reading an nginx access log. This is a real advantage — it's just a day-one advantage you pay for every day after.
Firewalls and NAT feel safer. Outbound HTTPS on 443 gets through anything. Teams worry that a persistent connection on port 8883 will be blocked at customer sites. Usually it isn't, but the worry is reasonable and rarely tested before the architecture is locked.
The cost penalty is invisible at prototype scale. With five devices on your desk, polling every 10 seconds costs nothing. The bill only becomes a problem at a scale where changing the architecture is expensive. By then the pattern is in the firmware of devices sitting in the field.
That last one is the trap. The decision gets made when it's cheap and gets re-examined when it's expensive.
When polling is genuinely the right call
Switching has real costs — broker operations, connection-state handling, a harder debugging story. Don't switch if you're in one of these situations:
Your devices sleep. Battery-powered sensors that wake every 15 minutes, transmit, and go back to deep sleep are already event-driven in every way that matters. A device that's awake 0.1% of the time can't hold a persistent connection, and it doesn't need to. Low-interval polling is the efficient pattern here. Don't add a broker to it.
Your interval is already long. At a 15-minute interval you're at 96 messages per device per day. Ninety-six. The entire cost argument evaporates. If your data genuinely changes on that cadence, leave it alone.
Your fleet is small and will stay small. Twenty devices in one building, no growth plan. The savings won't cover the migration. Spend the time elsewhere.
You're on cellular with strict data caps. This one cuts both ways and deserves care. Persistent connections require keepalive traffic even when idle, and on a metered SIM that's a real cost. If your device sends two readings a day over NB-IoT, a persistent connection is worse than polling. Run the numbers on keepalive overhead before assuming event-driven wins.
Latency genuinely doesn't matter. If nobody cares whether a fault surfaces now or in ten minutes, polling is fine. Be honest here, though — "nobody cares" is often "nobody has asked yet."
The five questions that decide it
Run these in order. If you answer yes to three or more, switching will pay for itself.
1. What fraction of your messages change state? Sample a day of production traffic and count how many messages differ meaningfully from the one before. Below 10% is the strong signal — you're paying to transmit redundancy. Above 60% and polling is roughly tracking reality.
2. How fast do you need to know about a failure? Write down the number your business actually needs, not the number that sounds impressive. If a machine going offline needs to reach someone within 30 seconds, polling forces you down to a 30-second interval fleet-wide, and you pay that cost 24 hours a day for an event that happens twice a month. Event-driven decouples detection speed from message volume — that's the real win, more than the cost saving.
3. Do you need to send commands to devices? This is the one teams underestimate. Remote unlock, config push, firmware update, forced refresh. With polling, the device has to ask "any commands for me?" on every cycle, and your command latency is bounded by your poll interval. A persistent connection gives you sub-second downlink for free. If there's any remote-control feature on your roadmap, that alone usually settles it.
4. Is your fleet going to grow 5× or more? Polling costs scale linearly and unforgivingly. If you're at 40 devices heading for 400, the architecture you pick now is the one you'll be stuck with — the cost curve gets steep exactly when you're least able to pause and rewrite.
5. Can you update firmware in the field? Not strictly a decision input, but a sequencing one. If you can't push firmware over the air, every device is a site visit and the migration plan below needs a very different shape. Fix OTA first.
What "event-driven" actually means in practice
Saying "we'll use MQTT" is the beginning of the design, not the end. Four decisions do most of the work.
Topic hierarchy
Design it before you write a line of firmware, because changing it later means touching every device. Structure it broadest-to-narrowest:
omega/{site}/{device_id}/telemetry
omega/{site}/{device_id}/events
omega/{site}/{device_id}/status
omega/{site}/{device_id}/cmd
The payoff is that wildcard subscriptions become useful. One dashboard subscribes to omega/+/+/events for everything. A site-level view takes omega/chennai-01/+/status. Your access-control rules also map cleanly onto this shape — a vendor's credentials can be scoped to their own site prefix, which is much harder to retrofit onto a flat topic namespace.
Keep commands on a separate branch from telemetry. Mixing them makes authorisation rules awkward, because devices should be able to publish telemetry and subscribe to commands, never the reverse.
Last Will and Testament
This is the feature that makes offline detection work, and it's the one most teams miss when they first move off polling.
When a device connects, it registers a "will" message with the broker — typically {"status":"offline"} on its status topic. If the device disconnects ungracefully (power cut, network drop, crash), the broker publishes that message on its behalf.
This matters because it inverts the detection problem. With polling, you detect an offline device by not hearing from it, which means running a timeout sweep across your whole fleet and tuning it against false positives. With a Last Will, the broker actively tells you the moment the connection drops. You go from a polling loop over device state to an event you can alert on directly.
Pair it with a retained message on the same status topic so that anything connecting later immediately learns current state instead of waiting for the next update.
Quality of Service
MQTT gives you three levels, and the temptation is to set everything to the highest. Don't:
- QoS 0 — fire and forget. Fine for high-frequency telemetry where the next reading is 30 seconds away and a gap doesn't matter.
- QoS 1 — at least once. Delivery is guaranteed but duplicates are possible, so your handlers must be idempotent. This is the right default for events that matter.
- QoS 2 — exactly once, via a four-part handshake. Genuinely more expensive in round trips and broker state. Reserve it for things like financial transactions where a duplicate is unacceptable and you can't dedupe downstream.
The practical answer for most platforms: QoS 1 for events, QoS 0 for routine telemetry, and idempotency keys on every handler so duplicates are harmless. If your handlers are idempotent, you almost never need QoS 2.
Keepalive interval
The device sends a small packet within each keepalive window; the broker declares it dead after roughly 1.5× that interval. Shorter means faster failure detection and more idle traffic. On wired or WiFi connections, 60 seconds is a sane default. On metered cellular, push it to 300 seconds or higher and accept slower detection — this is exactly the tradeoff that makes persistent connections a poor fit for tightly capped SIMs.
The migration playbook
The mistake here is attempting a big-bang cutover. Firmware in the field, a live broker, and a database schema change all at once is how you spend a weekend rolling back. We run it in six phases, and the fleet keeps working throughout.
Phase 1 — Measure first. Before changing anything, capture a week of production traffic and compute the change-rate from question 1. This is your business case and your baseline. If the change-rate comes back at 40%, stop here; the savings won't justify the work.
Phase 2 — Stand up the broker alongside, not instead. Deploy Mosquitto or EMQX with TLS and per-device credentials. Change nothing about the existing polling path. The broker sits idle. Get certificate rotation and authentication working now, while nothing depends on it.
Phase 3 — Dual-publish from a pilot group. Pick 5–10 devices, ideally including your worst-connectivity site. Their firmware now does both: existing polling and MQTT publishing. Traffic goes up for this group — that's expected and temporary. Run for two weeks and reconcile the two streams. Every discrepancy is a bug you would otherwise have found during cutover.
Phase 4 — Move consumers to the event stream. Point dashboards, alerts, and reporting at the MQTT-derived data while polling still runs underneath as a safety net. Your users should notice nothing except that alerts arrive faster. If something breaks, the polling path is still live and you can fall back without touching firmware.
Phase 5 — Retire polling, in waves. Site by site, not fleet-wide. Disable the polling path in firmware, leave the endpoint running but instrumented. Watch for devices that unexpectedly still call it — there are always a few, usually ones that missed an OTA update.
Phase 6 — Decommission and re-baseline. Remove the polling endpoint, resize your infrastructure to the new traffic profile, and re-measure the bill. This last step is the one teams skip, and it's where the savings actually land: if you moved to event-driven but never downsized the infrastructure you provisioned for polling volumes, you've done the engineering work and kept paying the old bill.
Four things that will bite you
Idempotency isn't optional. QoS 1 means duplicates, and reconnection storms mean bursts of them. Every handler needs a message ID or a natural key it can deduplicate on. Retrofitting this after go-live, into a schema that assumed exactly-once delivery, is painful.
Clock skew becomes visible. Polling hides bad device clocks because the server timestamps the arrival. Event-driven systems care about device-reported event time, and cheap RTCs drift badly. Send both device time and broker receive time, and decide deliberately which one your reports use.
Reconnection storms after an outage. When a site's internet returns, every device reconnects and flushes its queued backlog simultaneously. Without jittered exponential backoff in the firmware, your broker takes the entire site at once. Add randomised backoff before you need it.
Silence is ambiguous. In a polling system, no message means something is broken. In an event-driven system, no message usually means nothing happened — which is the desired behaviour and also indistinguishable from a dead device. This is precisely what Last Will and a low-frequency heartbeat are for. Keep the heartbeat: once an hour, not once every ten seconds.
What should stay on a schedule
Going event-driven doesn't mean nothing runs on a timer. Keep these periodic:
- A slow heartbeat — hourly, so you can distinguish "quiet" from "gone" even if a Last Will was missed
- Daily reconciliation — a full state snapshot per device to catch drift between what the device believes and what your database records
- Aggregate reporting — batch jobs on your own schedule, not triggered per event
- Certificate expiry checks — the failure mode nobody plans for, and it takes out the whole fleet at once
The goal was never "zero scheduled messages." It's that the schedule carries information proportional to what actually changed.
The checkpoint
If you take one number away from this: audit your platform if you're paying more than ₹15,000 a month in cloud for a fleet under 100 devices. That's not a scaling cost at that size — it's almost always an architecture cost, and it compounds every month you leave it.
Sample a day of your device traffic. Count how many messages actually changed something. If it's under 10%, you now know exactly what you're paying for.
Want a second opinion on your architecture?
We audit IoT platforms — vending, fleet, agriculture, smart buildings, industrial monitoring. Two weeks, fixed scope, written report with concrete recommendations and the cost model behind them. No obligation to engage further.
Bengaluru-based, working with clients across India and globally.
Get in touch · See our IoT work · WhatsApp: +91 9677749648
