Enterprise IoT Cloud Platform Migration
Zero-downtime move of a live consumer IoT backend off Xively onto GCP after Google acquired Xively and later discontinued it. Same platform now serving 70,000+ devices and 10,000+ accounts at 99.999% uptime.

Technologies
- Google Cloud Platform
- Kubernetes
- Firebase
- IoT Core
- PubSub
- PostgreSQL
- Redis
- MQTT
- TypeScript
- React
- Redux
- Express
- Fastify
- Docker
- Cloud Build
- Cloud Storage
- Cloud Monitoring
- Cloud Trace
- Cloud Functions
Key Achievements
- Zero-downtime live migration from Xively to GCP
- Platform now serving 70,000+ devices and 10,000+ user accounts at 99.999% uptime
- Apps, devices, and voice integrations kept working through the cutover
Project Links
From 2017 I was the full-stack and cloud engineer for Bluekey’s (later Zimi’s) smart-electrical platform. The first backend sat on Xively: device identity, MQTT, a way to ship. Google later acquired Xively and then discontinued it. I designed the GCP replacement, built the services, and moved a live fleet off that PaaS before it went away. That GCP system is still what the field talks to.
The PaaS under the fleet was going away
This was not a greenfield “let’s try Kubernetes” project. Xively was the IoT contract — broker, device identity, the path from a home gateway to the cloud — and that contract was ending. Staying meant betting a product already in people’s walls on a discontinued platform.
Moving meant owning MQTT, identity, and storage ourselves, on a deadline we did not set. The devices were already installed. Gateways in homes, mobile apps in pockets, voice skills already linked. A weekend cutover was not an option. Data had to stay consistent. MQTT sessions had to keep working. Alexa and Google Home could not quietly break.
What changed
I built a service-oriented backend on GCP and moved traffic onto it in batches rather than in one freeze.
The replacement had to cover everything Xively had been doing for us:
- MQTT between home gateways and the cloud
- Device identity and registry
- APIs for apps and the admin console
- Device metadata and the latest snapshot
- Event fan-out for telemetry and commands
- Auth for customers, installers, and operators
- File storage (firmware images, exports, other blobs)
On GCP that became TypeScript/Node services on Kubernetes. IoT Core was the device registry and MQTT path that replaced Xively’s broker — not a logo on a slide. Gateways authenticated to that channel; traffic was encrypted. We owned the topic contract and the credentials instead of inheriting a PaaS default.
Firestore held document state, PostgreSQL history, Redis hot paths, Pub/Sub events, Cloud Storage files. Firebase Auth handled user identity. Cloud Monitoring and Trace were how we watched the cutover, not a post-launch extra. I put shared MQTT, auth, and domain code in libraries so the new services did not each invent a protocol.
The React/Redux admin console was built in the same effort: operators needed a place to see the new backend while devices were still moving. CI ran through Docker and Cloud Build.
Staging ran load against simulated device traffic and the existing voice integrations before any household moved. Cutover was gradual: batches of devices, watching connectivity and error rates, coordinating with the mobile and firmware teams so field software and cloud moved in step.
The current shape of that system — containers, telemetry pipeline, voice, data, deployment — is in the C4 model.
Cut over in batches without a freeze
A big-bang DNS flip would have been simpler to describe and harder to survive. If the new broker, the new stores, and the new APIs were even slightly wrong, every silent device would have been a support call.
Batching meant the blast radius of a mistake was a slice of the estate, not the estate. It also forced the new stack to run next to the old one: same app versions, same firmware, two backends, until we were willing to stop the old one. That is slower than a rewrite-and-launch. It is how you move a live IoT product.
The unglamorous work was the contract with the field: what a gateway publishes, what it expects back, how a missed message is retried. Cloud diagrams do not matter if a dimmer stops reporting.
After
The platform left Xively without a customer-facing outage, before the discontinued PaaS could take the fleet with it. It now serves 70,000+ devices and 10,000+ accounts, handles 100+ events/s, and runs at 99.999% uptime. Once we owned the stack we could also size compute and storage ourselves, which brought cost and request latency down — that was a consequence of having to leave, not the reason we left.
I still operate this backend. Later work on the same system — voice, admin dashboard, partner API, CI/CD, data lifecycle — is evolution of this cutover, not a second platform.