OTA and A/B updates explained
Updating a device you cannot reach physically is one of the riskiest things you will do. The goal of a good update design is simple: a failed update must never leave the device unusable.
The A/B idea
The device holds two system slots, A and B.
- You are running from slot A.
- The new image is downloaded and verified (checksum and, ideally, a digital signature).
- It is written to the inactive slot B — the running system is untouched.
- The bootloader is told to try B once.
- After reboot, a health check confirms the new system works (network up, key service running).
- If healthy, B is marked good. If it fails to boot or fails the check, the watchdog or bootloader falls back to A.
Because the working system is never overwritten, a power cut in the middle of step 3 costs you nothing.
Keep data separate
User data and settings live on their own partition, outside both slots, so switching slots does not lose them. Plan for data-format changes between versions: an update that migrates data must remain readable by the fallback version, or the rollback is not real.
Make it safe at scale
- Sign images and verify them on the device so only your releases install.
- Stage rollouts. Update a small canary group first, watch health, then widen.
- Retry sensibly. Devices that lose the connection mid-download should resume, not start over or give up.
- Cover the bootloader. Updating the bootloader itself is the hardest case; treat it separately and rarely.
Alternatives
Some platforms update by replacing container images on top of a fixed host OS, as balenaOS does with containers. Appliances like Home Assistant OS offer their own one-click update flow. Build systems such as Yocto have layers and tools for A/B schemes, but you assemble the design yourself.
Whatever you choose, test the failure paths on purpose: unplug the power mid-update, ship a deliberately broken image and confirm it rolls back.