Component Overview
NervesHub Server
The core Phoenix/Elixir web application. It exposes the management UI, a REST API for automation, and a Phoenix Channels WebSocket endpoint that devices connect to. The server tracks device state, manages deployment groups, enforces their conditions (tags, version constraints, concurrency limits), and proxies remote console sessions.
Object Storage
Firmware
.fw files are stored in S3-compatible object storage (AWS S3 on NervesCloud; any compatible store when self-hosting). The server holds only metadata — devices download firmware artifacts directly from object storage, keeping large binary transfers off the server and making the architecture highly scalable.nerves_hub_link
The device-side Elixir library added to your Nerves project. It establishes and maintains a Phoenix WebSocket channel to the NervesHub server, handles update notifications, coordinates the firmware download and fwup application, reports health metrics, and multiplexes remote console sessions — all over a single persistent connection.
CLI — nh
The
nh binary used by engineers and CI systems to upload firmware, manage signing keys, create and activate deployment groups, and interact with devices. It communicates with the NervesHub REST API using a token obtained via nh user auth.fwup
The firmware packaging and application tool. fwup creates ZIP-based
.fw archives, signs them at build time, and applies updates atomically on the device using a dual-partition A/B scheme. fwup runs on both the build host (packaging) and the device (application).NervesKey (Optional)
An optional hardware security module based on the ATECC508A/608A secure element. NervesKey stores the device’s private key in tamper-resistant hardware, so the private key material never exists in software. It integrates transparently with the mTLS handshake performed by
nerves_hub_link.fwup (
.fw) is the production firmware path. NervesHub can also ingest ESP-IDF application images (.bin), AtomVM packbeam archives (.avm), and RAUC bundles (.raucb), but that support is experimental — ESP-IDF is gated behind a server setting, and the AtomVM and RAUC integrations currently cover the server side only.How a Firmware Update Flows
When a deployment group is activated, the following sequence occurs:- The NervesHub server evaluates which connected devices match the group’s tag and version conditions.
- Matching devices receive an update notification over their Phoenix WebSocket channel.
nerves_hub_linkon the device downloads the firmware.fwfile directly from object storage using a pre-signed URL provided by the server.nerves_hub_linkpasses the downloaded file to fwup, which verifies the signature and atomically writes the new firmware to the inactive partition.- The device reboots into the new partition. On successful boot, it reports back to the server, which marks the update as applied.
Delta updates follow the same flow but the server generates a binary diff between the current firmware on the device and the target firmware — xdelta3 for fwup firmware. Only the diff is downloaded, dramatically reducing transfer size on constrained links.
Deployment Options
- NervesCloud (Managed)
- Self-Hosted (Open Source)
NervesCloud is the fully managed NervesHub service operated at manage.nervescloud.com. Devices connect to devices.nervescloud.com.With NervesCloud you get:
- No infrastructure to provision or maintain
- Managed PostgreSQL, object storage, and TLS termination
- Automatic upgrades to the latest NervesHub server version
- A free tier suitable for development and small deployments
- The same open-source server code — nothing proprietary runs on your devices
host: "devices.nervescloud.com" in your nerves_hub_link configuration and authenticate your devices with your NervesCloud credentials.Security Model
NervesHub’s security architecture is built around two independent guarantees: connection authenticity (only legitimate devices can connect) and firmware integrity (only signed firmware can be applied).Connection Security — mTLS
Devices connect to the NervesHub WebSocket endpoint over TLS. For device certificate and NervesKey authentication modes, mutual TLS (mTLS) is used: the device presents its X.509 client certificate during the TLS handshake, and the server validates it against a trusted CA certificate you register with NervesHub.Your private keys never leave your infrastructure. NervesHub stores only the public CA certificate you register. Device private keys are generated and stored on the device itself (or in a NervesKey hardware element) and are never uploaded to the server.
Firmware Integrity — Signed Images
Every firmware file is signed with fwup at build time. The signing private key lives on your build machine or in your CI secrets store. NervesHub stores and distributes the public key. When a device applies a firmware update, fwup verifies the signature against the registered public keys before writing a single byte to flash. A firmware image that fails verification is discarded and the update is aborted — the device continues running its current firmware safely.Summary of Security Boundaries
Scale and Reliability
NervesHub’s architecture is proven at 400,000+ devices per instance. Several design decisions contribute to this scale:- Firmware is served from object storage, not the NervesHub server, so large binary downloads don’t consume server resources.
- Phoenix Channels provide efficient, long-lived WebSocket connections with low per-connection overhead.
- The server is a standard horizontally scalable Elixir application — add nodes to the cluster to increase connection capacity.
- Concurrency limits on a deployment group allow you to roll out updates gradually, reducing the risk of overloading your backend with simultaneous device reboots.

