Powering 300 EV Chargers with AWS IoT Core: Our OTA Firmware Journey
- Nishadil
- July 07, 2026
- 0 Comments
- 3 minutes read
- 2 Views
- Save
- Follow Topic
From prototype to production – building over‑the‑air update pipelines for electric‑vehicle chargers on AWS IoT Core
A behind‑the‑scenes look at how we designed, secured, and scaled OTA firmware pipelines for a network of 300 physical EV charging stations using AWS IoT Core.
When we first imagined a city‑wide network of electric‑vehicle chargers, the biggest question wasn’t how many ports we could fit into a box – it was how we’d keep that hardware alive, safe, and up‑to‑date once it was out in the wild.
Early on we tried manual flashing, hand‑carrying SD cards, even sending field engineers with laptops. The process was messy, error‑prone, and frankly, a nightmare for a fleet that quickly grew beyond a handful of units.
That’s when we turned to AWS IoT Core. The service promised a managed, secure conduit between the cloud and our edge devices, and, more importantly, a way to automate firmware rolls without ever stepping foot on a charger.
Our first hurdle was device identity. Each charger needed a unique, immutable certificate so that the cloud could trust it, and the device could verify it wasn’t talking to a rogue endpoint. We leveraged AWS IoT’s Just‑In‑Time (JIT) provisioning – a mouthful, but essentially a way to issue certificates the moment a device first connected, based on a pre‑shared enrollment token baked into the firmware.
Once identity was sorted, we built the actual OTA pipeline. Source code lives in a Git repo, CI/CD runs unit and integration tests, then produces a signed firmware binary. The binary is uploaded to an S3 bucket, and a Lambda function stamps it with a version number, updates a DynamoDB manifest, and notifies AWS IoT Jobs.
AWS IoT Jobs then becomes the orchestrator. It pushes a job document to every charger that matches our “production” thing‑type, telling it where to download the new image, how to verify the signature, and when to reboot. The chargers, running a lightweight Linux and a custom OTA agent, pull the file over HTTPS, verify the RSA signature, and swap the partition atomically – all while reporting progress back to IoT Core.
Security was never an afterthought. We used AWS KMS to encrypt the firmware at rest, enforced TLS 1.2 for all transfers, and turned on fleet‑wide revocation so a compromised device could be quarantined instantly. Auditing logs flow into CloudWatch and then into an Elasticsearch dashboard, giving us real‑time visibility into success rates, failure reasons, and latency.
Scaling to 300 chargers felt surprisingly painless. IoT Core handles millions of concurrent connections, and because our jobs are throttled per‑thing‑type, we never flooded the network. Still, we added a simple back‑off retry in the agent to cope with flaky cellular links, and a “roll‑back” job that can revert any device to the previous known‑good version with a single API call.
What did we learn? First, automate everything you can – even certificate rotation. Second, never trust a single point of failure; a broken OTA agent should still let you push a hot‑fix via a minimal fallback path. Third, keep humans in the loop – a short‑hand dashboard with a “panic button” saved us during a rare edge‑case where a bad build tried to flash a device with an incompatible partition map.
Today, those 300 chargers receive nightly health checks, monthly firmware upgrades, and occasional emergency patches, all without a technician leaving the office. The system isn’t perfect, but it’s far more reliable than the manual slog we started with, and it scales – ready for the next thousand.
Editorial note: Nishadil may use AI assistance for news drafting and formatting. Readers can report issues from this page, and material corrections are reviewed under our editorial standards.