Where Firmware Ends and Networking Begins: MQTT QoS, LoRa Duty Cycles, and the Convergence Problem
Srihari Maddula • Founder & Technical Lead, Eurth Techtronics Pvt Ltd
Category: Firmware Architecture & RTOS
Estimated Reading Time: 6 min
For most of embedded systems' history, firmware engineers and network engineers could work in adjacent lanes without much friction. Firmware owned the device; the network was a pipe it wrote bytes into. That separation is breaking down, and not because either discipline changed — it's breaking down because the constraints each discipline was built to solve now interact directly, and neither side's default mental model accounts for the other's failure modes. Two concrete cases show exactly where this bites: MQTT quality-of-service levels, and LoRa duty-cycle regulation. Both look like pure networking concerns. Both are, in practice, firmware architecture decisions.
MQTT QoS Is a Firmware Resource Commitment, Not a Config Flag
MQTT offers three quality-of-service levels, and the temptation is to treat the choice as a one-line configuration decision made once and forgotten. QoS 0 is fire-and-forget — no acknowledgment, no retry, no duplicate protection. QoS 1 guarantees at-least-once delivery via acknowledgment and retry, which means duplicates are possible and the receiving system must be idempotent to messages it may see more than once. QoS 2 guarantees exactly-once delivery via a four-part handshake, which is the most reliable and by a wide margin the most expensive in both round trips and, critically, in the state the publishing device has to maintain per in-flight message.

That last point is the one firmware teams underweight. QoS 1 and QoS 2 both require the publishing device to retain the message — and, for QoS 2, retain multiple handshake states — until acknowledgment completes. On a resource-constrained microcontroller publishing many concurrent readings, that's real RAM committed per in-flight message, not a free reliability upgrade. Choosing QoS 2 broadly because “it's more reliable” without sizing the retained-message buffer against actual concurrent publish rates is exactly the kind of decision that works fine in bench testing at low message rates and fails under field load when publish rates spike — a sensor storm during an actual event, for instance, which is usually the worst possible moment for a firmware buffer to overflow.
THE RULE: QoS is a memory allocation decision wearing a networking reliability costume.
The practical default worth adopting: QoS 0 for high-frequency telemetry where an occasional dropped reading is tolerable and the next reading arrives shortly anyway; QoS 1 with idempotent message handling on the receiving end for anything that represents a discrete event (an alert, a state change) where loss is unacceptable but duplicate delivery is a manageable inconvenience; QoS 2 reserved for the narrow set of messages where duplicate delivery itself would cause harm — a command that triggers a physical actuation, for example, where executing it twice is worse than executing it once, late.
LoRa Duty Cycle Is a Regulatory Constraint That Shapes Firmware State Machines
Sub-GHz ISM band regulations in most regions that use LoRa impose a duty cycle limit on transmit time — commonly around 1% in the EU868 band, meaning a node can transmit for at most roughly 36 seconds per hour on a given sub-band, with the exact allowance varying by channel and region. This is not a soft guideline; it's regulatory, enforced by spectrum authorities, and violating it is a compliance failure, not a performance tuning miss.
The firmware consequence is that a node's transmit scheduling logic has to actively track cumulative airtime per sub-band and defer or drop non-critical transmissions once the budget is exhausted, and it has to do this correctly under all the conditions that make correct tracking hard — clock drift over long uptimes, transmissions that fail and get retried (which consume duty-cycle budget even though the payload never arrived), and multiple logical message types sharing the same radio and therefore the same budget. A firmware architecture that treats “send this message” as an unconditional action, with duty-cycle compliance handled as an afterthought exception case, will pass every bench test — because bench tests rarely run long enough or generate enough traffic to hit the limit — and then either violate the regulation in the field or, if a naive hard-stop is bolted on, silently drop exactly the messages that matter most during a high-traffic event, because those are precisely the conditions under which the duty-cycle budget gets exhausted first.
This is where the same escalation-under-anomaly logic from sensor mesh design applies directly: a well-architected node reserves duty-cycle budget for high-priority messages by design, spending routine-telemetry budget more conservatively so that budget remains available when an anomaly needs to be reported urgently. That's a scheduling decision made in firmware, informed by a regulatory constraint that lives, on paper, entirely in the networking domain.
THE RULE: A duty cycle limit isn't a networking spec. It's a budget the firmware's transmit scheduler has to actively manage, especially during the exact high-traffic moments the system exists to handle.
Why Edge AI Makes This Worse, Not Better
The instinct is that pushing more intelligence to the edge should reduce networking pressure — fewer, smarter messages instead of a raw data firehose. That's often true in aggregate bandwidth terms and often false in scheduling-complexity terms, because an edge inference result isn't a fixed-size, fixed-priority payload anymore; it's a variable-confidence, variable-urgency event whose transmission requirements depend on the inference outcome itself. A model that just flagged a high-confidence anomaly needs its result transmitted with different QoS, different priority within the duty-cycle budget, and potentially different retry behavior than the routine low-confidence heartbeat the same node sends every other cycle. The firmware's transport logic now has to make decisions that are informed by application-layer semantics — what did the model actually conclude — which used to live entirely on the other side of a clean separation between “what the device thinks” and “how the device talks.” That separation was never architecturally necessary; it was just convenient while the two concerns didn't need to interact. They interact now.
The Organizational Fix Mirrors the Technical One
Teams that keep firmware and networking as separate specialisms with a clean interface between them are optimizing for an organizational structure that made sense when the technical boundary was actually clean. It no longer is, at least not for edge-AI-adjacent products. The practical fix isn't necessarily merging the roles — deep RF and deep RTOS expertise are each still genuinely deep — it's making sure both disciplines understand the other's constraints well enough to recognize when a decision that looks purely local (this ISR's duration, this QoS level, this duty-cycle margin) has a cross-domain consequence. The bugs that survive to production are, almost without exception, the ones that fell exactly into that gap — technically correct in isolation, and wrong only in combination, which is precisely the kind of wrong that no unit test written from within a single domain will ever catch.
EurthTech delivers AI-powered embedded systems, IoT product engineering, and smart infrastructure solutions — Hyderabad, India. www.eurthtech.com




Comments