Two Pipes, One Device: Separating Firmware From Configuration in OTA Architecture
Photo: Ordercrazy, CC0, via Wikimedia Commons
The Binary Is Not the Behavior
When a fleet of thermostats in Phoenix starts short-cycling compressors during a July heat wave, the instinct is to ship a patch. That instinct is expensive. A firmware rebuild means recompiling, retesting, re-signing, and pushing megabytes to hundreds of thousands of devices — all to change what may amount to a single threshold value.
The root cause of this inefficiency is architectural: most OTA pipelines are built as a one-way street. The server pushes, the device receives, and the only mechanism for changing anything is a full binary swap. It does not have to be this way. Increasingly, mature device teams are splitting their update infrastructure into two distinct channels — one for firmware, one for configuration — and discovering that a large share of their "patches" never needed to be firmware at all.
Why One Channel Fails at Fleet Scale
Firmware updates carry inherent cost and risk. Binary payloads consume bandwidth and egress budget, particularly for cellular-connected devices where every megabyte is metered. They require reboots or at minimum a safe swap window, which means coordinating with the device's operational rhythm. And they demand the full cryptographic and staged-rollout ceremony that any responsible pipeline requires: signing, canary cohorts, health monitoring, rollback plans.
None of that ceremony is justified when the change is "adjust the reporting interval from 60 seconds to 300 seconds." Yet in a single-channel architecture, that is exactly the machinery you invoke. The result is predictable: teams batch small behavioral fixes into large firmware releases, releases grow riskier, and the interval between fixes stretches out. The device becomes rigid precisely when the product needs to be adaptive.
The Two-Channel Model
The alternative treats firmware and configuration as fundamentally different artifacts with fundamentally different delivery requirements.
The firmware channel handles infrequent, large, immutable payloads. Images are signed, versioned, and deployed through progressive rollout with full validation. Change is deliberate and slow by design.
The configuration channel handles frequent, small, mutable state. A config document — typically a few kilobytes of structured data — describes tunable behavior: polling intervals, sensor thresholds, logging verbosity, feature toggles, retry backoff parameters. Devices fetch or receive these documents on their own schedule, validate them against a schema and signature, and apply them without a reboot.
The critical design decision is that configuration must be declarative and versioned, not a side door around firmware discipline. Each config document carries a version number, a signature from the same key infrastructure as firmware, and a schema the device can validate. A device that receives config version 41 knows exactly what changed relative to version 40, and can reject anything malformed without falling into a bad state.
Feature Flags for the Embedded World
Feature flags are routine in web engineering; they translate to embedded systems with a few important constraints.
First, flags must be bounded. A web service can tolerate an unbounded set of toggles; a microcontroller cannot. Config schemas should be explicitly versioned, with the device firmware declaring which schema versions and maximum payload sizes it accepts. A 2019-vintage device on the floor of a distribution center in Ohio should gracefully ignore flags it does not understand rather than fail to parse the document at all.
Second, flags must degrade safely. If a device loses connectivity, it should continue operating on its last-known-good configuration indefinitely — the same principle that governs firmware rollback. Configuration is an optimization of behavior, never a precondition for it.
Third, the two channels must be able to talk to each other. Firmware declares capability ("this image supports config schema v3 and the adaptive_throttle flag"); configuration expresses intent ("enable adaptive_throttle at aggressiveness 2"). This separation means a single firmware image can serve many behavioral profiles across a fleet, and a single config document can mean different validated things on different hardware revisions.
What This Buys You in Practice
Teams that adopt this split report a consistent pattern: the majority of post-launch changes turn out to be configuration-shaped. Thresholds tuned after real-world telemetry arrives. A noisy sensor reading filtered by adjusting a debounce window. A feature rolled out to 5% of the fleet by tag, then widened, then reversed in minutes when the dashboards look wrong.
The economics are equally direct. A config sync might cost a few hundred bytes over a coarse interval — negligible even on an LTE-M connection with a monthly data cap. Compare that to a 2 MB firmware push across a million devices, and the bandwidth argument alone justifies the architecture.
Most importantly, the blast radius shrinks. A bad config document can be superseded by a good one in the next sync cycle. A bad firmware image requires the full rollback apparatus. Reserving that heavy machinery for changes that genuinely require it is what disciplined OTA engineering looks like.
Getting Started Without a Rewrite
The good news is that this does not demand a ground-up rebuild. A pragmatic path:
- Inventory your constants. Audit the current firmware for hardcoded values that field experience has already forced you to change. Those are your first config keys.
- Define a versioned schema. Start small — a dozen keys, strict types, a documented range for each.
- Sign config like firmware. Reuse the existing signing infrastructure and verification code paths. A config channel without cryptographic validation is an attack surface, not an architecture.
- Sync on the device's schedule. piggyback on existing check-ins rather than inventing a new connection pattern.
- Reserve the firmware channel for firmware. Enforce this culturally. If a change can be expressed in config, it does not go in the binary.
One Device, Two Contracts
The deepest shift here is conceptual. A device under this model has two contracts with the fleet: a slow contract about what it is (firmware), and a fast contract about how it behaves (configuration). Conflating them makes products brittle; separating them makes fleets operable.
The update that listens back is not a push at all. It is the quiet, continuous alignment of device behavior with what the data says the device actually needs — delivered in kilobytes, not megabytes, and reversed just as quickly when the data says otherwise.