> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instapods.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Backups

> Automatic daily backups of your pod's files and databases, plus manual snapshots, restore, download, and import.

Every pod is backed up automatically. When a pod is created, InstaPods turns on a **daily backup schedule** for it - you don't have to enable anything. Backups capture your application files *and* dump any database the pod is running, so a restore brings back your data, not just your code.

Open the **Backups** tab on any pod to see its backups, take one by hand, or restore.

## What gets backed up

InstaPods backs up your data, not the whole container. The base operating system and installed packages are rebuilt from the preset image, so backups stay small and restores stay fast.

| Pod type     | What's included                                                                 |
| ------------ | ------------------------------------------------------------------------------- |
| Static, PHP  | `/home/instapod/app`                                                            |
| Node.js      | `/home/instapod/app`, excluding `node_modules`, `.next` and `dist`              |
| Python       | `/home/instapod/app`, excluding `venv`, `.venv` and `__pycache__`               |
| Go           | `/home/instapod/app`, including the compiled binary                             |
| 1-Click Apps | The app's own data directory (for example `/opt/beszel/beszel_data` for Beszel) |

On top of that, any database found in the pod is dumped into the archive first - a managed [MySQL, PostgreSQL or Redis service](/services/overview), a database bundled with a 1-Click App, or one you installed yourself. The dump is restored back into the running database when you restore the backup.

<Note>
  Dependency directories are excluded on purpose - they are reinstalled from your lockfile and would otherwise dominate the size of every backup. After restoring a Node.js or Python pod, run `instapods pods reload my-app` to reinstall dependencies.
</Note>

## How many backups you keep

Retention is per plan, and it's a count of stored backups per pod. When a new backup pushes a pod over its limit, the oldest one is deleted.

| Plan   | Backups kept per pod |
| ------ | -------------------- |
| Launch | 1                    |
| Build  | 5                    |
| Grow   | 10                   |
| Scale  | 15                   |
| Turbo  | 30                   |

Once you're at the limit, a manual backup is rejected with a `403` until you delete an old one or move up a plan. Scheduled backups aren't rejected - they roll the oldest one off automatically.

## The automatic schedule

The default schedule runs **every 24 hours** and keeps as many backups as your plan allows. Open **Automatic Backups** on the Backups tab to change it: **Enable auto-backups** turns the schedule on or off, **Frequency** switches between daily and weekly, and **Keep last** sets how many to retain.

Two behaviours worth knowing:

* **Stopped pods are skipped.** A backup has to run commands inside a live container, so a stopped pod is passed over rather than failing every night. Its existing backups are frozen - nothing is added, and nothing is deleted to make room - so your recovery points survive for as long as the pod is off.
* **A backup that captures nothing fails loudly.** If a database dump comes back empty or a directory the app was supposed to write to doesn't exist, the backup is marked failed instead of being recorded as a successful, empty archive.

## Taking a backup by hand

<Tabs>
  <Tab title="Dashboard">
    Open the pod, go to the **Backups** tab and click **Create Backup**. Type a short note in the **Note (optional)** field first ("before the v2 upgrade") to find it again later.

    The backup runs in the background; the row shows its status and final size when it finishes.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -X POST https://app.instapods.com/api/pods/my-app/backups \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"note": "before the v2 upgrade"}'
    ```

    Returns `202 Accepted` with the backup record. Poll `GET /api/pods/my-app/backups/{backupId}` until `status` is `completed`.
  </Tab>
</Tabs>

## Restoring

Restoring rewinds the pod's data to the moment the backup was taken.

<Warning>
  **A restore is destructive and cannot be undone.** Every directory covered by the backup is emptied before the archive is extracted, so anything created since the backup is lost. Take a fresh backup first if the current state is worth keeping.
</Warning>

<Tabs>
  <Tab title="Dashboard">
    On the **Backups** tab, find the backup and click **Restore**. Confirm the warning. The pod's services are stopped, the data is replaced, databases are re-imported, and the services are restarted.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -X POST https://app.instapods.com/api/pods/my-app/backups/BACKUP_ID/restore \
      -H "Authorization: Bearer YOUR_TOKEN"
    ```

    Returns `202 Accepted` and runs in the background. Watch the pod's **Events** tab for `restore_started`, `restore_completed` or `restore_failed`.
  </Tab>
</Tabs>

A restore only reports success when the databases came back too. If the files were restored but a database dump could not be re-imported, the restore is marked **failed** and the dump file is deliberately left inside the pod (under `/tmp`) so you can import it by hand rather than losing it. The pod's Events tab names the file.

## Downloading a backup

You can pull any completed backup out of InstaPods as a `.tar.gz`, for off-site storage or to inspect it locally.

<Tabs>
  <Tab title="Dashboard">
    On the **Backups** tab, use the **Download** action on any completed backup.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -L https://app.instapods.com/api/pods/my-app/backups/BACKUP_ID/download \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -o my-app-backup.tar.gz
    ```
  </Tab>
</Tabs>

## Importing a backup

You can upload a backup archive you downloaded earlier and register it against a pod, then restore from it like any other backup. This is how you move data between two pods, or bring back a pod you rebuilt.

On the **Backups** tab, click **Import** and pick the `.tar.gz`. Or over the API:

```bash theme={null}
curl -X POST https://app.instapods.com/api/pods/my-app/backups/import \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@my-app-backup.tar.gz" \
  -F "note=Imported from staging"
```

Uploads are capped at 2 GB and count against your plan's retention limit.

<Note>
  Import the archive into a pod of the same shape as the one it came from. A backup only carries the paths its source pod used, so restoring a Node.js backup into a 1-Click App pod puts files where nothing will read them.
</Note>

## API reference

| Method   | Path                                           | Description                         |
| -------- | ---------------------------------------------- | ----------------------------------- |
| `GET`    | `/api/pods/{name}/backups`                     | List backups, with the plan's limit |
| `POST`   | `/api/pods/{name}/backups`                     | Take a backup now                   |
| `GET`    | `/api/pods/{name}/backups/{backupId}`          | Get one backup                      |
| `DELETE` | `/api/pods/{name}/backups/{backupId}`          | Delete a backup                     |
| `POST`   | `/api/pods/{name}/backups/{backupId}/restore`  | Restore from a backup               |
| `GET`    | `/api/pods/{name}/backups/{backupId}/download` | Download the archive                |
| `POST`   | `/api/pods/{name}/backups/import`              | Upload an archive as a new backup   |
| `GET`    | `/api/pods/{name}/backups/schedule`            | Get the automatic schedule          |
| `PUT`    | `/api/pods/{name}/backups/schedule`            | Change or disable the schedule      |
