BETA — Open to testers. Tell us what to fix on @vomehome or via a tester code.

Out of the house first

We moved an established Home Assistant out of a Swedish house and onto hosted infrastructure while the house kept heating itself. 83 of 101 integrations came back — and the 18 that didn't sorted into a pattern worth knowing.

Updated 19 August 2026 migrationhome-assistantnetworkinghomelink


1,410entities moved
4.14 GiBbackup archive
83 of 101integrations back
25problems logged

GamlaBio runs a Swedish house: heating, lighting, a boiler, presence detection, a media library. 1,410 entities, 96 automations, years of accumulated logic — some of it carried through more than one house move.

It needed to move off an installation type Home Assistant no longer supports. The usual answer is an afternoon of downtime and hoping you remember how it was all set up. We did something more awkward on purpose: out of the house first, onto a hosted VM, before bringing it home again later. That is the path someone escaping ageing hardware actually walks, and it puts every assumption about "the brain can reach the devices" under maximum stress.

Your home ESPHome sensors Bluetooth proxies Lights, boiler, media VomeHome Home Assistant Backups, monitoring Always on encrypted tunnel
One encrypted link, carrying traffic both ways: commands out to the house, sensor readings back. No ports opened on your router.

Before anything moved

Every migration begins with a question nobody enjoys: is this actually going to work? The importer answers it before touching anything — reading the archive and comparing it against the target machine.

The pre-flight report listing its checks against the backup
Pre-flight against the real archive. Every check here is one the restore would otherwise have discovered the expensive way, halfway through.

It immediately blocked the migration for lack of disk — on a server with 31.9 GB free. Home Assistant reports disk in gigabytes; our code divided by 1024 as though megabytes, so every figure rounded to 0.0. The unit test had encoded the bug, feeding it numbers Home Assistant never sends.

That is the first of twenty-five, and the pattern starts there. We fixed the units, pre-flight went from BLOCKED to a warning on the same backup and the same server, and the migration could start.

Three attempts

It did not work first time. Or second.

The first restore reported that Home Assistant never came back. It had. The snapshot was taken, the archive copied, the restore ran, and Home Assistant came up perfectly — while our code sat watching for a health value that nothing in the system has ever produced. It waited out its full thirty minutes and declared a success a failure. Worse, it then offered to roll the machine back, which would have destroyed half an hour of work that had gone right.

The second attempt got further and failed differently. After the snapshot, the four-gigabyte copy and the upload had all completed, Home Assistant refused the restore: "216d3222 is only a partial backup!" A backup becomes "partial" the moment you deselect anything, and we had deliberately dropped two unused Z-Wave add-ons when taking it. The importer only ever asked for a full restore. That fact is written in plaintext inside the archive and could have been checked before a single byte moved.

The third worked. Home Assistant restarted on the version the backup carried, and the verification report ran itself.

Both failures were ours, both were the same kind of mistake — code that had been read but never run — and both are now impossible: the health check tests the value the system actually emits, and a partial backup is restored as a partial backup, with pre-flight saying so up front.

What came back

83 of 101 integrations loaded. All ten ESPHome devices connected — from a datacentre to boards in a Swedish house — along with MQTT, Matter's own entry and nine Bluetooth proxies. Automations 96 of 96. Areas 17 of 17.

The 18 that did not load sorted into three groups, and the shape of that split is the useful part:

Class Result Why
Talking to a known address Works ESPHome, MQTT, Bluetooth proxies
Relying on discovery Cannot work broadcasts are designed never to leave your network
Cloud services Needs re-auth the restore replaces stored credentials
The verification report comparing the restored system against the backup
The report generated after every restore: version, entities, automations, scripts, scenes, devices, areas, integrations, configuration and system health, each compared against what the backup said it held.

The bit that cannot be fixed by a faster connection

Device discovery works by broadcasting a question to everything on the local network and listening for replies. Those broadcasts are designed never to leave the network they were sent on — routers must not pass them along. A Home Assistant that is not on the same network segment will never hear them, however good the link between them is.

Your devices Router Hosted HA "who is out there?" stops here "device at 192.168.1.31, are you there?" — works fine
Broadcasts stop at the router by design. Asking a device you can name passes straight through, which is why ESPHome and MQTT were unaffected.

The fix is not a faster tunnel. It is to stop the connection behaving like a road between two places and make it behave like a cable: extend the home network itself, so both ends share one broadcast domain. Within minutes of doing that, the hosted machine was receiving the house's own router advertisements and its Google speakers announcing themselves.

Two that are worth the detour

A restore that reported failure while succeeding The first restore said Home Assistant never came back. An overnight rehearsal of that single step told a different story: **178 polls over 1,806 seconds, every one of them seeing a healthy Home Assistant answering HTTP 200** — and the function returned false anyway. It tested a health value against `'serving'`, `'running'` or `'ok'`. Nothing in the codebase emits any of those; the real vocabulary is `'healthy'`. The comparison had never once been true. It shipped because every test mocked the function out, so the real one had never run. Worse than the bug: the page then offered a rollback that would have destroyed thirty minutes of successful work.
Three theories about a slow build, two of them wrong Builds took sixteen minutes, and the test timings showed a flat ~4.2 second floor across 159 tests. First suspect: database rebuilds. Second: coverage instrumentation. A faithful replica — clean checkout, the pipeline's own environment, same flags, same machine — ran those tests in **17 seconds**, killing both theories. The answer was in the console header all along: the workspace was named `portal-ci@2`. Every push started **two identical builds of the same commit**, which then fought over one machine. A flat per-test tax is contention, not work. Genuinely slow code has a shape; a uniform floor does not.

What it cost us

Twenty-five problems were logged, most of them self-inflicted, and one pattern runs through nearly all of them: code that had been read but never run.

A restore that reported failure while quietly succeeding — it compared a status against three values nothing in the codebase ever emits, and every test had mocked the function out, so the real one had never executed. A retry button that returned an error on its first real click, "tested" by asserting its address appeared in a template. A network profile in every template we ship that was bound to nothing at all, which nobody had noticed because no VM had ever had two network cards.

We found all of it on our own house, before anyone else was on it. That is the entire argument for migrating yourself first.

The hosted server overview showing a running Home Assistant and an encrypted tunnel home
Where it ended up: Home Assistant running on hosted infrastructure, still on the Core version the backup carried, with an encrypted tunnel back to the home network it looks after.

Next time

The harder half is bringing it home again — onto fresh hardware with no downtime at all, using failover rather than a maintenance window. Everything above was, in a sense, the rehearsal.

What actually came next was one IKEA bulb that would not pair over Thread, on this same hosted instance. That is a three-part series of its own, starting with A bulb that would not join.


Fancy trying it?

VomeHome hosts Home Assistant properly: your own instance, backed up, monitored, and connected to the devices in your house over an encrypted tunnel with no ports opened on your router. If you already run Home Assistant, the import above is the same one you would use — pre-flight checks first, a rollback point taken before anything changes, and a report at the end telling you exactly what came across.

Take a look at VomeHome — it is open to testers, and we would rather hear what breaks than be told it is fine.

Rather not do this alone?
The Vome assistant will walk you through this guide a step at a time, and can do some of it for you.
Sign in for AI help

Something wrong or missing here? Tell us — these pages are written from real work, so corrections are welcome.