Backing Up Home Assistant Properly: Restore-Tested
This article may contain affiliate links. If you make a purchase through these links, we may earn a small commission at no extra cost to you. This helps us keep creating free content.
A Home Assistant backup is a single .tar archive, and most people never open one until the day they need to restore from it, which is exactly the wrong time to discover it's incomplete. This covers what's actually inside that archive, what a restore genuinely gives back, and the one test almost everyone skips.
What actually sits inside a backup archive
A full backup bundles your configuration files, the recorder database (home-assistant_v2.db by default on SQLite installs), installed add-on data, and the Supervisor's own settings if you're running Home Assistant OS or Supervised. The archive itself is a compressed tarball, and each add-on's data is nested inside as its own tar within the tar, which is why extracting one manually takes more than a single unzip step.
Full backups versus partial backups
A full backup includes everything: core config, every add-on, the database, and media if it's stored locally. A partial backup lets you pick specific add-ons or folders, which produces a much smaller file and a faster backup job, at the cost of needing to remember exactly what you excluded when restore day arrives. Automatic scheduled backups default to full unless you've specifically configured a partial job.
Where the recorder database keeps growing
The recorder logs every state change for every entity, and on a house with 300 to 400 entities that adds up fast, commonly reaching 200 to 500 MB within 2 to 3 months on the default SQLite backend. The recorder: integration's purge_keep_days setting defaults to 10 days and controls how far back history is retained; dropping it to 5 or 7 days can cut the database size by 30 to 50 percent on a busy install.
Automatic backup schedules and how many to keep
Home Assistant's built in backup scheduling can run daily, weekly, or on a custom interval, and it keeps a configurable number of copies before deleting the oldest. Three to seven kept backups is a reasonable range for most single home setups: enough to roll back a few days if a bad update goes unnoticed, not so many that a 32 GB SD card or a 16 GB eMMC install fills up. At 300 to 500 MB per full backup, seven kept copies alone can claim 2 to 3.5 GB, which is roughly a fifth of a 16 GB eMMC board once the operating system and add-ons have taken their share.
| Backup type | Typical size driver | Restore scope |
|---|---|---|
| Full | Recorder database, media, all add-ons | Entire instance |
| Partial (config only) | YAML files, small | Automations and settings, no history |
| Partial (add-on) | Whatever that add-on stores | Single service only |
Encrypting a backup before it leaves the house
Home Assistant supports password protected backups, which encrypt the archive's contents so a copy sitting in cloud storage isn't readable without the password even if that storage account is compromised. This matters specifically because a backup contains long lived API tokens and integration credentials in plain text inside the config files, not just automations and dashboard layouts. A typical Home Assistant install stores 10 to 30 separate long lived access tokens across its integrations by the time it's a year old. The password is the entire protection, so it has to live somewhere that outlives the machine it protects: a password manager on another device, or a written note in a drawer, never only inside the Home Assistant instance being backed up. There is no recovery path for a forgotten backup password, and an archive nobody can open counts for exactly as much as no archive at all.
Getting a copy off the physical box
A backup stored only on the same SD card or drive as the running instance doesn't protect against the two most common failure modes: SD card corruption and the drive failing outright. Add-ons for Google Drive, Samba shares, and Nextcloud sync backups off the device automatically after each scheduled run, and a simple alternative is an automation that copies the newest backup file to network storage on a schedule.
The restore test that most people skip
A backup you've never restored is a theory, not a safety net. The only way to know a backup actually works is to restore it, ideally onto separate hardware or a throwaway virtual machine rather than the production instance, and confirm the dashboard, automations, and history all come back correctly. Doing this once after setting up a new backup schedule catches configuration mistakes before they matter.
- Spin up a spare Raspberry Pi, VM, or container with a fresh Home Assistant install.
- Restore the most recent scheduled backup onto it.
- Confirm entities, automations, and dashboards all appear as expected.
- Check that history graphs show data, proving the recorder database restored too.
- Note anything missing and adjust what the backup job includes.
What a restore does not bring back
A restore returns Home Assistant to the exact state captured at backup time, which means anything that changed since then is gone, including new automations, updated device firmware pairings, and any Z-Wave or Zigbee network changes made after the backup ran. Device radios (a Zigbee coordinator or Z-Wave stick) keep their own network state independently of the backup file, so a restore doesn't rewind the mesh network itself, only Home Assistant's record of it.
Backing up add-on data separately
Some add-ons, particularly ones running their own database like a Zigbee2MQTT instance or a Node-RED flow store, keep state that a full backup captures but that's worth understanding independently. If an add-on's data grows large, for example a media server's library metadata, excluding it from the scheduled full backup and handling it with a separate, less frequent backup job keeps the routine backup fast without losing anything important.
Version mismatches between backup and restore target
Restoring a backup made on an older Home Assistant Core version onto a much newer install usually works because of the project's migration system, but restoring a newer backup onto an older Core version does not, since the database schema and config format can include fields the older version doesn't understand. When rebuilding on new hardware, update Core to match or exceed the backup's version before restoring, not after.
Backup size creep and what to trim
A backup archive that quietly grows month over month is usually the recorder database, locally stored camera snapshots, or a media library being included in a full backup unnecessarily. A single camera recording continuous snapshots can add 50 to 100 MB per day on its own. Run that out over a month and it is 1.5 to 3 GB inside every full backup, multiplied again by however many copies the schedule keeps, so seven retained backups can carry the same month of snapshots seven times over. That makes a camera folder the first thing to exclude from the scheduled full backup rather than the last. Checking the archive size after each scheduled run and comparing it against the previous month makes creep obvious early, before a 32 GB SD card runs out of room mid backup and produces a corrupted file instead of a clean failure.
Recovering from a failed automatic backup
A scheduled backup can fail silently if the target storage is full or unreachable, and unless notifications are configured for backup failures specifically, the first sign of trouble is often discovering there's no recent backup during an actual emergency. An automation that checks the timestamp of the most recent successful backup and sends a notification if it's older than the expected interval catches this before it becomes a problem instead of after.
What the .storage folder holds that configuration.yaml doesn't
A surprising amount of Home Assistant's state lives outside the YAML files entirely, inside the .storage directory as JSON: entity registry entries, area assignments, dashboard layouts built through the UI, and integration config entries set up through the UI flow instead of YAML. A backup captures this folder along with everything else, but anyone trying to reconstruct a setup by hand from just configuration.yaml will find that most of a modern install isn't in that file at all.
Moving the recorder off SQLite before it becomes a backup problem
SQLite is the default recorder backend and works fine for smaller installs, but as entity count and history retention grow, database writes can start to compete with backup jobs for disk I/O, occasionally causing a slow or failed backup on constrained hardware like a Raspberry Pi with an SD card. Pointing the recorder at an external MariaDB or PostgreSQL instance, both of which listen on their own default ports (3306 and 5432), moves that write load off the same storage the backup process is reading from, and shrinks what the local backup archive needs to include by removing a multi-hundred-megabyte database file from it entirely. That shrinkage has a cost, and it has to be handled in the same step rather than discovered on restore day: once the recorder lives outside Home Assistant, the Home Assistant backup no longer contains any history at all, and a restore brings entities, automations, and dashboards back with empty graphs behind them. The external database needs its own scheduled dump, stored next to the Home Assistant archives, and step four of the restore test moves with it, verifying that the MariaDB or PostgreSQL dump restores alongside the tarball.
Testing restores again after a major Core upgrade
A restore test done once when the backup schedule was set up doesn't stay valid forever, because major Home Assistant Core releases occasionally change the backup format or the database schema migration path. Repeating the restore test after any major version jump, not just minor updates, confirms that an older backup would still restore cleanly onto the newer Core version if you actually needed it.
Restoring onto different hardware than the backup was made on
A backup made on a Raspberry Pi and restored onto an x86 mini PC generally carries the config and database over fine, since both run the same Core codebase, but any add-on that ships architecture specific binaries can fail to start until it re-downloads the correct build for the new hardware. Budget extra time for the first boot after a cross-hardware restore: a same-hardware restore typically finishes in 2 to 5 minutes, while a cross-hardware restore with 10 or more add-ons rebuilding their containers at once can run 20 to 30 minutes before everything reports healthy.
β‘Disclaimer: This article is for informational purposes only. Smart home installations may involve electrical wiring and must comply with local building codes. Electrical work should only be performed by a licensed electrician.
Published by the SmartHome Automate editorial team. Published November 13, 2026.
Editorial responsibility: see Imprint.
Spotted an error or have something to add? corrections@smarthomeautomate.com
Explore more
All articles on SmartHome Automate β
Smart Home Tips, Delivered
New guides, device reviews, and automation ideas β every week in your inbox.
π Free bonus: Smart Home Starter Checklist (PDF)
You might also like
Local vs Cloud Smart Home: What Breaks When the Internet Goes Down
Your internet drops. Do your lights still work? Your locks? Your cameras? The answer depends entirely on whether your smart home runs locally or in the cloud.
Home Assistant vs SmartThings vs Apple Home: Which Hub Is Right for You?
The hub you choose determines how flexible, reliable, and future-proof your smart home will be. Here's an honest comparison of the three most popular options.