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

> Understand Home Assistant backup and restore architecture. Learn how Backup Reader/Writer and Restore Core manage archives, validation, and atomic configuration replacement for seamless data management.

- Repository: [Home Assistant/core](https://github.com/home-assistant/core)
- Tags: architecture
- Published: 2026-02-28

---

**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:

- **Backup Reader/Writer** ([`homeassistant/components/backup/backup.py`](https://github.com/home-assistant/core/blob/main/homeassistant/components/backup/backup.py)) – Handles creation, encryption, uploading, downloading, and validation of backup archives.
- **Restore Core** ([`homeassistant/backup_restore.py`](https://github.com/home-assistant/core/blob/main/homeassistant/backup_restore.py)) – Manages the destructive restoration process including extraction, compatibility checks, directory cleaning, and atomic data replacement.

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`](https://github.com/home-assistant/core/blob/main/homeassistant/backup_restore.py)) to the configuration directory:

```json
{
  "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`](https://github.com/home-assistant/core/blob/main/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:

```json
{
  "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:

```python
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:

```python
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):

```python
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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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.