How Home Assistant's Backup and Restore Functionality Works: Core Architecture Explained

Home Assistant's backup and restore functionality operates through a two-layer architecture where the Backup Reader/Writer manages archive creation and storage while the Restore Core handles extraction, version validation, and atomic replacement of configuration data via instruction files.

Home Assistant's backup and restore functionality, maintained in the home-assistant/core repository, provides atomic restoration capabilities that protect your configuration directory while ensuring version compatibility. The system separates concerns between high-level backup management and low-level restore operations, using JSON instruction files to persist restore intent across application restarts.

Two-Layer Architecture

The backup and restore system comprises two distinct layers working in tandem:

This separation ensures that the complex logic for safely replacing running configuration data remains isolated from the backup management interface.

The Restore Workflow

When you initiate a restore from the UI (Settings ▶ System ▶ Backups), Home Assistant follows a rigorous sequence to ensure data integrity.

Step 1: Triggering via Instruction Files

The UI does not immediately restore data. Instead, it writes a JSON instruction file named .HA_RESTORE (defined as RESTORE_BACKUP_FILE in homeassistant/backup_restore.py) to the configuration directory:

{
  "path": "/config/backups/backup_2024-03-01.tar",
  "password": "optional-password",
  "remove_after_restore": true,
  "restore_database": true,
  "restore_homeassistant": true
}

On the next startup, the core imports homeassistant.backup_restore.restore_backup, which immediately reads this file via restore_backup_file_content() and deletes it to prevent infinite boot loops.

Step 2: Compatibility Validation

Inside _extract_backup() (lines 98-104), the system parses the embedded backup.json metadata and compares the backup's Home Assistant version (backup_meta["homeassistant"]["version"]) against the current running version (HA_VERSION). If the backup originates from a newer version, the system raises a ValueError and aborts the restore, preventing incompatible data from corrupting your instance.

Step 3: Atomic Directory Replacement

The _clear_configuration_directory() function (lines 64-73) performs a surgical cleanup of the configuration folder:

  • Removes all entries except the backups directory (protected via KEEP_BACKUPS = ("backups",))
  • Optionally preserves SQLite database files (home-assistant_v2.db*) if restore_database is false (using KEEP_DATABASE)

After extraction to a temporary directory, the system either:

  • Restores full configuration: Copies tempdir/homeassistant/data into the config folder while respecting the keep list (lines 124-134)
  • Restores database only: Deletes existing DB files and copies archived databases back (lines 135-148)

Step 4: Result Reporting

Upon completion, _write_restore_result_file() (lines 151-165) writes a .HA_RESTORE_RESULT file containing:

{
  "success": true,
  "error": null,
  "error_type": null
}

Home Assistant reads this file after restart to display the outcome in the UI. If remove_after_restore was set to true, the original archive is deleted before the final restart.

Programmatic Backup and Restore

You can interact with the backup system programmatically from custom components.

Scheduling a Restore

Write the instruction file manually to trigger a restore on next boot:

from homeassistant.backup_restore import RESTORE_BACKUP_FILE
import json
from pathlib import Path

def schedule_restore(hass, backup_path: Path, password: str | None = None):
    instruction = {
        "path": str(backup_path),
        "password": password,
        "remove_after_restore": True,
        "restore_database": True,
        "restore_homeassistant": True,
    }
    (Path(hass.config.path()) / RESTORE_BACKUP_FILE).write_text(
        json.dumps(instruction), encoding="utf-8"
    )

Checking Restore Results

Inspect the outcome after restart:

from homeassistant.backup_restore import RESTORE_BACKUP_RESULT_FILE
import json
from pathlib import Path

def read_restore_result(hass):
    result_path = Path(hass.config.path()) / RESTORE_BACKUP_RESULT_FILE
    if result_path.is_file():
        return json.loads(result_path.read_text(encoding="utf-8"))
    return None

Using the Manager API

For immediate restoration without restart (used internally by agents):

await manager.async_restore_backup(
    backup_id="20240301-1234",
    agent_id="local",
    password=None,
    restore_addons=None,
    restore_database=True,
    restore_folders=None,
    restore_homeassistant=True,
)

Summary

  • Home Assistant uses a two-layer architecture separating backup management from restore operations.
  • Restore operations require an instruction file (.HA_RESTORE) that persists intent across application restarts.
  • The system performs strict version validation, refusing to restore backups from newer Home Assistant versions.
  • Configuration directory cleaning preserves the backups folder and optionally database files to prevent data loss.
  • Results are written to .HA_RESTORE_RESULT for UI consumption after restart.

Frequently Asked Questions

What happens if I try to restore a backup from a newer Home Assistant version?

The restore aborts immediately. In homeassistant/backup_restore.py, the _extract_backup() function compares backup_meta["homeassistant"]["version"] against the current HA_VERSION. If the backup version is newer, the system raises a ValueError to prevent incompatible data structures from corrupting your instance.

How does Home Assistant prevent data loss during restore?

The _clear_configuration_directory() function protects critical data by maintaining a KEEP_BACKUPS tuple that excludes the backups directory from deletion. Additionally, if you choose not to restore the database, the system preserves home-assistant_v2.db* files via the KEEP_DATABASE constant, ensuring your historical sensor data survives the restoration process.

Can I restore only the database without configuration files?

Yes. Set restore_database: true and restore_homeassistant: false in the instruction file. The restore logic branches at lines 135-148 in homeassistant/backup_restore.py to handle database-only restoration, deleting existing DB files and copying only the archived database files back to the configuration directory.

Where does Home Assistant store restore instructions between restarts?

The system writes a JSON file named .HA_RESTORE (defined as RESTORE_BACKUP_FILE) directly into your configuration directory. This file contains the backup path, optional password, and restoration flags. The core reads and immediately deletes this file on startup to prevent restore loops, then writes results to .HA_RESTORE_RESULT for post-restart status reporting.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →