surrealctl instance manages instances: the databases themselves. It is the largest group in the CLI, and covers provisioning, scaling, observability, credentials, capabilities and backups.
surrealctl instance <COMMAND> [OPTIONS]surrealctl instances <COMMAND> [OPTIONS]| Verb | Purpose | Alias |
|---|---|---|
list | List the instances in an organisation | ls |
get | Show one instance | |
create | Create an instance | |
update | Change an instance's type, size, or version | |
delete | Delete an instance and everything in it | rm |
pause | Pause a running instance | |
resume | Resume a paused instance | |
watch | Watch an operation that was started elsewhere | |
status | Show an instance's deployment phase and restorable snapshots | |
endpoint | Print the endpoint a client connects to | |
token | Mint a database token for an instance | |
jwks | Fetch the key set that verifies an instance's tokens | |
sql | Open a SurrealQL session against an instance | |
import | Import a file into an instance | |
export | Export an instance to a file | |
metrics | Show an instance's resource metrics | |
logs | Show an instance's logs | |
usage | Show what an instance has consumed | |
estimate | Estimate what an instance would cost | |
capabilities get | Show an instance's capability configuration | |
capabilities set | Change an instance's capability configuration | |
backup list | List the snapshots an instance can be restored from | ls |
backup create | Take a backup of an instance now | |
backup policy get | Show the backup retention policy | |
backup policy set | Change the backup retention policy |
Naming an instance
Four spellings are accepted: the id, the slug, the name, or org/name. Only a bare id avoids a lookup against the organisation. A slug always contains a hyphen, so it can never be mistaken for an id.
surrealctl instance get production
surrealctl instance get production-6xk2
surrealctl instance get acme/production
surrealctl instance get 67upif0m8sh1cn1p2c8tOmit the reference entirely and, on a terminal, you get a picker. Elsewhere it is a usage error, exit 2, listing what was available:
No instance was given and this session cannot prompt.
Name one, or pass --org to change which organization is searched.
Available:
production
stagingThere is deliberately no instance use. A sticky implicit target is fine for a noun whose verbs are mostly reads, and wrong for one whose verbs include delete.
surrealctl instance list
List the instances in an organisation.
surrealctl instance list [OPTIONS]This command takes no positional argument, deliberately: a positional here would read as an instance. The organisation comes from --org and the precedence chain.
Accepts the list presentation flags and nothing else. Column ids are name, state, type, version, region, compute_units and storage, with id, slug, host, access_type and organization_id under --wide.
surrealctl instance listNAME STATE TYPE VERSION REGION UNITS STORAGE
production ready production-2 3.2.4 aws-euw1 4 100 GB
staging paused shared-1 3.2.4 aws-euw1 1 10 GBsurrealctl instance list --json | jq -r '.[] | select(.state == "ready") | .name'surrealctl instance get
Show one instance.
surrealctl instance get [OPTIONS] [INSTANCE]This command has no options of its own.
surrealctl instance get productionsurrealctl instance get production --json | jq -r .statesurrealctl instance create
Create an instance.
surrealctl instance create [OPTIONS] --type <SLUG> --region <SLUG> <NAME>--access-type value | Meaning |
|---|---|
public | Reachable over the public internet. The API's own default |
private | Reachable over PrivateLink only. Needs PrivateLink on the organisation |
dual | Reachable both ways |
surrealctl instance create api --type shared-1 --region aws-euw1surrealctl instance create production \
--type production-2 \
--region aws-euw1 \
--compute-units 4 \
--storage 100surrealctl instance create staging \
--type shared-1 \
--region aws-euw1 \
--restore-from production/rsnapshot-20260811-150405With the wait, the command reports progress and then emits a fresh detail view. With --no-wait it emits the accepted request and hints at surrealctl instance watch <name>.
Refusals, all exit 2 and all before any request:
A name outside 1 to 30 characters, with the length it counted.
--compute-unitsbelow 1, or--storagebelow 1.A malformed
--restore-from, which is split on the last/:
`prod-snap-1` is not a snapshot reference. Use <instance>/<snapshot>, for example
production/rsnapshot-20250128-150405.
Run `surrealctl instance status <instance>` to list the snapshots an instance can be restored from. The create route accepts no idempotency key, so a retried create is a second instance and a second bill. surrealctl never retries it after a 502 for exactly that reason. If a create times out, run instance list before running it again.
surrealctl instance update
Change an instance's type, size, or version.
surrealctl instance update [OPTIONS] [INSTANCE]There is no single update route on the API — each field has its own — so one invocation is several requests. They are applied in a fixed order and stop at the first failure:
--type--compute-units--storage--version--access-type
Every one of these restarts the instance. A single instance update that changes three fields restarts it once per field, in the order above.
surrealctl instance update production --compute-units 8surrealctl instance update production --version 3.2.4surrealctl instance update production --type production-4 --storage 250Refusals, all exit 2:
No flags at all:
Nothing to update. Pass at least one of --type, --compute-units, --storage, --version, or --access-type.--compute-unitsor--storagebelow 1.A storage cool-off still in force, naming the interval and, when known, when storage was last changed.
--compute-unitsoutside the current type's range, when--typeis not also being changed:
`shared-1` accepts 1–2 compute units; 8 is outside that.surrealctl instance delete
Delete an instance and everything in it.
surrealctl instance delete [OPTIONS] [INSTANCE]surrealctl instance delete stagingsurrealctl instance delete staging --force --jsonThe confirmation names the instance, its slug and its region, so the wrong terminal tab is caught before the request. Declining prints Nothing was deleted. and exits 0 with no document. In a non-interactive session without --force or --yes, it exits 2 having sent nothing.
The delete route answers with no body, so the emitted document is synthesised:
{
"id": "67upif0m8sh1cn1p2c8t",
"name": "staging",
"slug": "staging-4jd1",
"state": "deleted"
}While waiting, a 404 is the success condition — there is nothing left to fetch.
surrealctl instance pause
Pause a running instance.
surrealctl instance pause [OPTIONS] [INSTANCE]surrealctl instance pause stagingPausing something already paused prints a note and still emits a document, exit 0. The shape of the answer does not change with remote state, so a script does not need to know which case it hit.
surrealctl instance resume
Resume a paused instance.
surrealctl instance resume [OPTIONS] [INSTANCE]surrealctl instance resume stagingResuming something already ready behaves like pausing something already paused: a note, a document, exit 0.
surrealctl instance watch
Watch an operation that was started elsewhere.
surrealctl instance watch [OPTIONS] [INSTANCE]There is no --wait or --no-wait here, because a watch is nothing but a wait.
--until value | Finishes when |
|---|---|
ready | The instance is running and healthy |
paused | The instance is deliberately stopped |
deleted | The instance is gone — a 404 while polling is what finishes this one |
surrealctl instance watch apisurrealctl instance watch staging --until paused This is the one command where --json writes to stdout continuously. The transitions are the answer, so the newline-delimited stream goes to stdout and nothing else is emitted. In text mode the run ends with a fresh detail view, except under --until deleted, where there is nothing left to fetch.
surrealctl instance watch api --json | jq -r '.event + " " + (.state // "")'surrealctl instance status
Show an instance's deployment phase and restorable snapshots.
surrealctl instance status [OPTIONS] [INSTANCE]Also accepts the list presentation flags, which arrange the snapshot table. Column ids are snapshot_id, started_at, tiers and on_demand, with valid_versions under --wide.
surrealctl instance status productionThe answer is one composite document: a phase, then the snapshots the instance can be restored from. In plain mode the phase is written as phase<tab><Phase> before the table, so grep ^phase works the same way it does on instance get. An instance with no restorable snapshots gets a note on stderr rather than an empty table with no explanation.
Snapshot ids from here are what instance create --restore-from expects.
surrealctl instance endpoint
Print the endpoint a client connects to.
surrealctl instance endpoint [OPTIONS] [INSTANCE]This command has no options of its own.
The output is the bare endpoint plus a newline, byte-identical in rich and plain output, so $(…) captures exactly the value with no label and no styling.
ENDPOINT=$(surrealctl instance endpoint production)
surreal sql --endpoint "$ENDPOINT" --namespace app --database mainsurrealctl instance endpoint production --json{
"endpoint": "wss://production-6xk2.aws-euw1.surreal.cloud",
"host": "production-6xk2.aws-euw1.surreal.cloud",
"private_host": null,
"access_type": "public"
}A private-only instance produces a warning on stderr rather than a refusal — the endpoint is still correct, it is simply not reachable from where you are.
surrealctl instance token
Mint a database token for an instance.
surrealctl instance token [OPTIONS] [INSTANCE]This is a database token — the credential a SurrealDB client authenticates with. It is not a personal access token, which authenticates against the control plane.
surrealctl instance token production | pbcopySURREAL_TOKEN=$(surrealctl instance token production) \
surreal sql --endpoint "$(surrealctl instance endpoint production)" --namespace app --database mainRefusals. Printing a credential into a terminal's scrollback is refused, exit 2, and the check happens before the token is minted — so a forgotten --reveal never costs a credential nobody can recover:
Refusing to print a database token to a terminal, where it would stay in your scrollback.
Pipe it: surrealctl instance token production | pbcopy
Or pass --reveal if you meant to see it.Under --json the answer is a one-field document carrying the instance id and the token.
surrealctl instance jwks
Fetch the key set that verifies an instance's tokens.
surrealctl instance jwks [OPTIONS] [INSTANCE]Also accepts the list presentation flags. Column ids are the JWK member names — kid, kty, alg and use, with crv under --wide — so a member the key type does not carry renders as missing rather than empty.
surrealctl instance jwks productionsurrealctl instance jwks production --json > jwks.jsonUnder --json the whole key set is emitted, keys wrapper included, so it can be handed straight to a JWT library.
surrealctl instance sql
Open a SurrealQL session against an instance.
surrealctl instance sql [OPTIONS] [INSTANCE] [-- <ARGS>...]This command does not speak SurrealQL. It resolves the instance, mints a database token, and becomes surreal sql. Everything after -- is forwarded to that command verbatim, because the sibling's flag surface is large and moves independently.
surrealctl instance sql production --namespace app --database mainsurrealctl instance sql production -- --ns app --db main --prettyecho "SELECT count() FROM person GROUP ALL;" \
| surrealctl instance sql production --namespace app --database main--namespace and --database are optional here, because surreal sql accepts a session without them. See the surreal handoff for how the binary is located and what is passed in the child's environment.
Warnings, neither of which stops the handoff: a private-only instance, and an instance that is not in a ready phase.
surrealctl instance import
Import a file into an instance.
surrealctl instance import [OPTIONS] [INSTANCE] [-- <ARGS>...]surrealctl instance import production --namespace app --database main -- ./seed.surqlRefusals. surreal import requires both a namespace and a database, so this command does too. The check fires before a token is minted:
`surrealctl instance import` needs both --namespace and --database; `surreal import` requires them.See surreal import for the flags available after the --.
surrealctl instance export
Export an instance to a file.
surrealctl instance export [OPTIONS] [INSTANCE] [-- <ARGS>...]surrealctl instance export production --namespace app --database main -- ./backup.surqlsurrealctl instance export production --namespace app --database main -- - | gzip > backup.surql.gzLike import, this refuses a missing namespace or database before minting anything. See surreal export for the flags available after the --.
For a managed snapshot rather than a SurrealQL dump, use instance backup create.
surrealctl instance metrics
Show an instance's resource metrics.
surrealctl instance metrics [OPTIONS] --metric <METRIC> [INSTANCE]Also accepts the list presentation flags. Summary rows carry series, last, min, mean, max and unit, with samples and gaps under --wide; sample rows carry timestamp, series and value, with unit under --wide.
--metric is a free-form string rather than a fixed set, because the platform's metric vocabulary is not published anywhere the CLI can read it.
surrealctl instance metrics production --metric cpusurrealctl instance metrics production \
--metric memory \
--from 2026-08-11T10:00:00Z \
--to 2026-08-11T12:00:00Z \
--samplesTimestamps are validated locally and forwarded byte-for-byte, never reformatted:
Ensure `11-08-2026` is an RFC3339 timestamp, such as 2026-08-11T10:00:00Z--samples chooses a table, not a payload: --json carries the whole document either way. A note on stderr states the metric, its unit and the window.
surrealctl instance logs
Show an instance's logs.
surrealctl instance logs [OPTIONS] [INSTANCE]Also accepts the list presentation flags. Column ids are timestamp, level and message, with pod under --wide.
surrealctl instance logs productionsurrealctl instance logs production --level error,warnsurrealctl instance logs production --follow --json | jq -r '.timestamp + " " + .message'--level is a display filter applied on this side, and a note reports how many lines were hidden. --json still carries every line the API sent. --limit takes from the start of the window, matching its meaning elsewhere.
--follow polls with a moving start time at a fixed five-second interval — there is no streaming endpoint and no interval flag. Under --follow --json, each new line is written as newline-delimited JSON on stdout; in text mode a table is printed per batch, with the header only on the first.
surrealctl instance usage
Show what an instance has consumed.
surrealctl instance usage [OPTIONS] [INSTANCE]Accepts the list presentation flags and nothing else — this route takes no query parameters at all. Column ids are instance_id, metric_type, compute_hours, disk_used_bytes, period_start and period_end, with instance_type and source under --wide.
surrealctl instance usage productionFor every instance in the organisation at once, use org usage.
surrealctl instance estimate
Estimate what an instance would cost.
surrealctl instance estimate [OPTIONS] --type <SLUG> --region <REGION>This command takes no positional argument: it prices a hypothetical instance, so there is nothing to name.
surrealctl instance estimate --type production-4 --region aws-euw1 --units 8 --storage 250Flags you omit are left out of the request rather than sent as null, so the platform's own defaults for that type apply.
Refusals, exit 2:
An instance has at least 1 compute unit; 0 was given.
An instance has at least 1GB of storage; 0 was given.This is the one place the API does not use integer minor units — the cost is a number in a named currency — and --json keeps the raw value.
surrealctl instance capabilities get
Show an instance's capability configuration.
surrealctl instance capabilities get [OPTIONS] [INSTANCE]This command has no options of its own.
surrealctl instance capabilities get productionUnder --json the nested capabilities object is emitted, not the whole instance — so it can be diffed against another instance directly.
diff <(surrealctl instance capabilities get staging --json) \
<(surrealctl instance capabilities get production --json)surrealctl instance capabilities set
Change an instance's capability configuration.
surrealctl instance capabilities set [OPTIONS] [INSTANCE]The capabilities route is a full replacement, so this command reads the current configuration, applies the flags given here, shows what would change, and asks before writing. A list flag replaces that list rather than adding to it, and anything not named is left exactly as it is — including capabilities this build does not know about.
surrealctl instance capabilities set production --deny-scriptingsurrealctl instance capabilities set production --allow-funcs "array,string,time"surrealctl instance capabilities set production --deny-funcs "http::*" --forceThe diff is printed on stderr in every mode, --json included, then confirmed unless --force is given. Declining prints Nothing was changed. and exits 0.
Refusals and short-circuits. No flags at all is a usage error, exit 2, before any request:
Nothing to set. Pass at least one capability flag, such as --allow-scripting or --deny-funcs http::*.
Run `surrealctl instance capabilities get` to see the current configuration.Flags that would change nothing produce a note and exit 0 without a write:
`production` already has those capabilities. Nothing was changed.surrealctl instance backup list
List the snapshots an instance can be restored from.
surrealctl instance backup list [OPTIONS] [INSTANCE]Accepts the list presentation flags and nothing else. Column ids are snapshot_id, started_at, tiers and on_demand, with valid_versions under --wide.
surrealctl instance backup list productionsurrealctl instance backup list production --sort started_at --reverse --limit 1 \
--columns snapshot_id --no-headerThere is no backup collection route on the API, so this reads the snapshots off the instance's status route. --json carries the snapshot array rather than the whole status document. instance status shows the same snapshots alongside the deployment phase.
surrealctl instance backup create
Take a backup of an instance now.
surrealctl instance backup create [OPTIONS] [INSTANCE]This command has no options of its own, and carries no --wait or --no-wait.
surrealctl instance backup create productionThe route answers with no body, so the document is synthesised:
{
"instance_id": "67upif0m8sh1cn1p2c8t",
"status": "accepted"
}A replayed request is a second snapshot, so this call is never retried automatically. Requesting a backup while one is already queued is reported as a conflict, exit 6, rather than as a rate limit — the condition is "one is already running", not "you are asking too often".
Poll instance backup list to see the snapshot appear.
surrealctl instance backup policy get
Show the backup retention policy.
surrealctl instance backup policy get [OPTIONS] [INSTANCE]This command has no options of its own.
surrealctl instance backup policy get productionThe answer reports each retention tier, how often snapshots are taken, and which tiers this organisation's plan allows you to change — which is what backup policy set will accept.
surrealctl instance backup policy set
Change the backup retention policy.
surrealctl instance backup policy set [OPTIONS] [INSTANCE]The three retention flags also accept the literal default, which restores this organisation's own value for that tier. --frequency-hours has no default form, because the platform gives it no resettable value.
--frequency-hours is an allow-list, not a range: the plan publishes the intervals it offers, and a value sitting between two of them is refused rather than rounded. Run backup policy get to see which intervals this plan offers.
surrealctl instance backup policy set production --daily 14surrealctl instance backup policy set production --frequency-hours 6surrealctl instance backup policy set production --monthly defaultConfirmation. Only a reduction asks. Lengthening a retention cannot lose a snapshot, so it is applied without a prompt. Declining prints The policy was not changed. and exits 0.
Refusals, exit 2:
No flags at all:
Nothing to set. Pass --daily, --weekly, --monthly or --frequency-hours.
Each retention flag also takes the literal `default`, which restores this organization's own value for that tier.A tier the plan does not allow changing:
This organization's plan does not allow changing the monthly retention on `production`.
Run `surrealctl instance backup policy get` to see which tiers are editable.A value outside the plan's bounds, naming the bound it broke:
Daily retention must be between 1 and 30 days on this plan; 90 was given.A
--frequency-hoursthe plan does not offer, listing the intervals it does:
A backup every 5 hours is not offered on this plan. Choose one of: 6, 12, 24.Related pages
Long-running operations —
--wait,--no-wait, polling and exit code10orgcommands — the organisation that owns these instancescatalogcommands — the type, region and version slugscreateandupdateexpectInstallation — how
sql,importandexportfind thesurrealbinaryOverview — the rest of the reference
SurrealDB CLI — the data plane:
surreal sql,surreal import,surreal export