# Import and export

Move data in and out of an instance with surreal export and surreal import, including size limits and partial-import behaviour.

Export and import move data as SurrealQL text, so you get a portable copy of a database.

Use them for four cases:

- Migrating from a self-hosted server.
- Seeding a local development database.
- Moving data between instances or regions.
- Keeping an archive outside the platform.

[Backups](/docs/manage/instances/backups.md) cover the recover-this-instance case instead, and you cannot download them.

Both commands come from the [SurrealDB CLI](/docs/reference/cli/surrealdb-cli/overview.md), which you install once and point at any instance. The connection URL, namespace, and database are on the **Connect** menu of the instance in [SurrealDB Studio](https://app.surrealdb.com).

## Exporting

[`surreal export`](/docs/reference/cli/surrealdb-cli/commands/export.md) writes the contents of one database to a `.surql` file:

```bash title="Export a database to a file"
surreal export \
  --conn wss://<endpoint> \
  --user root --pass <password> \
  --ns main --db main \
  ./api-production.surql
```

The file contains the SurrealQL statements needed to rebuild the schema and the records. It is therefore readable, diffable, and safe to store in an artefact repository.

An export covers a single namespace and database. Export each one you need separately.

## Importing

[`surreal import`](/docs/reference/cli/surrealdb-cli/commands/import.md) replays that file into a target database:

```bash title="Import a file into an instance"
surreal import \
  --conn wss://<endpoint> \
  --user root --pass <password> \
  --ns main --db main \
  ./api-production.surql
```

The target namespace and database do not have to match the source. That is how you promote a staging dataset into a differently named database.

## Size limits

An import is accepted up to **4 GiB per request**. The limit applies to the whole request rather than to each statement, so you must split a larger file and import the parts in sequence.

The other endpoints have lower caps: 1 MiB on `/sql` and 4 MiB on `/rpc`. That is why bulk loading goes through import rather than through a large query. See [request size limits](/docs/reference/rest-api/http-protocol.md#request-size-limits) for the full table.

A self-hosted server sets these caps with environment variables. Instances run the defaults.

## Partial imports

An import is applied statement by statement as the file is parsed, and each statement commits as it goes. No single transaction wraps the file, so **a failure partway through leaves the statements that already ran in place**.

That matters for retries. Rerunning the same file against a half-populated database can produce duplicate records or conflicting definitions.

Import into a fresh namespace or database, verify the result, then switch the application over. If something fails, drop the target and start again from a known-empty state.

## Related pages

- **[Backups and recovery](/docs/manage/instances/backups.md):** snapshots and in-platform restore.
- **[Migrating to SurrealDB](/docs/build/migrating.md):** moving from another database.
- **[surrealctl instances](/docs/manage/surrealctl/instances.md):** `surrealctl instance import` and `surrealctl instance export` wrap the same operations against an instance.
