# Convex (/docs/databases/convex)

backupd runs Convex's own export on your schedule, with file storage included. The result is the same ZIP snapshot Convex produces, compressed and encrypted. It works with Convex Cloud and with self-hosted Convex backends.

## Connect a Convex deployment [#connect-a-convex-deployment]

In **Add database**, choose **Convex**, then pick the **Hosting** tab.

<Tabs items={["Convex Cloud", "Self-hosted"]}>
<Tab value="Convex Cloud">

| Field | Where to find it |
| --- | --- |
| **Deployment URL** | Convex dashboard → **Settings → URL & Deploy Key**. It looks like `https://happy-otter-123.convex.cloud`. |
| **Deploy key** | Same page. Use a **production** deploy key. It looks like `prod:happy-otter-123\|…`. |

</Tab>
<Tab value="Self-hosted">

| Field | Where to find it |
| --- | --- |
| **Backend URL** | The value of `CONVEX_SELF_HOSTED_URL`, for example `https://convex.example.com`. |
| **Admin key** | Generate one with `generate_admin_key.sh`. It looks like `convex-self-hosted\|…`. |

</Tab>
</Tabs>

The deployment must be reachable over HTTPS from the internet. A self-hosted backend must resolve to a public address. The key is encrypted at rest.

## What is backed up [#what-is-backed-up]

- Every table's documents.
- Your file storage.

Files are named with the `.zip.zst.age` extension: the Convex export ZIP, compressed with zstd and encrypted with age.

## How Convex backups are checked [#how-convex-backups-are-checked]

There is no temporary Convex deployment to restore into, so Convex backups don't get a full restore test. Instead, every Convex backup gets an integrity check: the ZIP is tested end to end, and the documents in each table are counted from the export. The counts are stored in the backup's manifest. Tables whose names start with an underscore are not counted.

## Restoring [#restoring]

In-app restores go back into the deployment the backup came from. To restore into another deployment, download the backup and use `npx convex import`. See [Restore without backupd](/docs/restoring/without-backupd).

In the app, tick **Replace tables that already exist in the target** to replace the deployment's existing data with the backup.

## Limitations [#limitations]

- No full restore test, as described above.
- In-app restores only go back to the original deployment.
- No point-in-time recovery or incremental backups. Every backup is a full copy.
