How to Use SurrealDB: The Beginner's Guide (First Server, Namespaces, SurrealQL, and the Backup Rule)
CodexFuse Team · 2026-11-01T08:58:13.957Z · 16 min read
Install SurrealDB with Docker, start your first server, create namespaces and databases, write SurrealQL, link graph edges, subscribe to live queries, and back up — one beginner guide.
Learning how to use SurrealDB takes an afternoon: install one binary or Docker container, start your first server on port 8000, land in the default namespace and database, and write your first SurrealQL queries — the same language handles documents, graph edges, and live subscriptions, so one engine replaces a document store, a graph database, and a pub/sub channel. SurrealDB is a source-available, multi-model database built in Rust that unifies document, relational, graph, time-series, geospatial, vector, and key-value data in one engine, queried with SurrealQL inside single ACID transactions. One clarification before you start: SurrealDB is the database, SurrealQL is its query language, Surrealist is the official GUI client, and SurrealML is the machine-learning side — four names from one family, and this surrealdB tutorial covers the three you will touch as a beginner. If you have never run a container before, our Docker beginner guide gets you to the one-command install in minutes.
What Is SurrealDB?
SurrealDB is a multi-model database written in Rust that stores documents, relations, graph edges, time series, geospatial points, vectors, and key-values in a single engine, queried with one SQL-like language — SurrealQL — so a query can touch every data model inside one ACID transaction. It exists to end the three-database glue: instead of syncing MongoDB-style documents, a graph store, and a relational system (plus the sync code between them), you model the documents, link them with typed graph edges, and traverse them with one language. The project is actively maintained: the 3.3.x stable line is current (3.3.4, released October 13, 2026), the 3.0 GA landed in February 2026, and a 4.0 beta is in testing. On GitHub the repository holds more than 33,000 stars and 1,398 forks (checked this week).
SurrealDB is source-available, not OSI open source: it ships under the Business Source License 1.1, which lets you use, modify, and self-host it in production for free — the one restriction is running SurrealDB itself as a database service for third parties. Each version converts to Apache 2.0 no later than four years after release, and the storage engines SurrealKV and SurrealMX are Apache 2.0 already. For a beginner that distinction matters once, at this point: self-hosting on your own server or VPS is fully covered, so carry on.
How Do You Use SurrealDB? The 10-Step First-Run Arc
Using SurrealDB is a short arc: start a server, land in a namespace and database, write records, link them, and watch them live. The whole thing, from zero to your first graph query, looks like this:
- Install it. One install script or one Docker pull — your choice below.
- Start a server in memory. One command boots the engine for the afternoon's learning.
- Land in main/main. SurrealDB 3.0+ auto-creates a default namespace and database.
- Connect. The Surrealist GUI or the
surreal db sqlshell — both speak to port 8000. - Create a record. One CREATE statement writes your first document, schemaless.
- Query it. SELECT across tables with one WHERE, no joins needed yet.
- Link two records. RELATE creates a typed graph edge between them.
- Subscribe live. LIVE SELECT streams changes over WebSocket as they happen.
- Lock it down. Set a root user and define access rules before any remote exposure.
- Back it up. Export the database to a replayable .surql file.
Steps 1–4 take about ten minutes; steps 5–8 are where the multi-model idea clicks. The remaining sections of this guide walk every step in detail, with the version gotchas that waste beginners' time.
What Do You Need Before You Start?
You need a machine that runs the SurrealDB binary or Docker — a home server, a laptop, or a VPS — plus a browser for the Surrealist client. A first server is light: any modern machine handles the in-memory mode comfortably, and port 8000 must be free on the host. If the machine is a rented server, our what is VPS hosting explainer covers what you are actually buying. The only other prerequisite is a terminal: SurrealDB's tooling is command-line first, with the GUI layered on top. Decide where data will live before you start — memory is fine for learning, but a real setup needs a storage path, covered in the backends section.
How Do You Install SurrealDB?
Install SurrealDB with the official install script or your platform's package route, pinning the 3.3.x stable line. Linux uses the launcher script, macOS uses Homebrew, Windows uses the PowerShell one-liner:
# Linux (installs the surreal launcher)
curl --proto '=https' --tlsv1.2 -sSf https://install.surrealdb.com | sh
# macOS
brew install surrealdb/tap/surreal
# Windows (PowerShell)
iwr https://windows.surrealdb.com -useb | iex
The Docker path skips the install entirely — the official image is surrealdb/surrealdb, and the docs only ever name latest plus beta-style tags like v4.0.0-beta.1, so beginners should stick with latest on the stable line:
docker pull surrealdb/surrealdb:latest
Choose your install path with this decision:
| If you... | Use... | Why |
|---|---|---|
| Just want to try SurrealDB this afternoon | The binary + memory mode | Zero setup; nothing persists, nothing to clean up |
| Run it permanently on a server | Docker + a SurrealKV volume | One container, one volume, survives restarts |
| Build an app against it | The launcher + an official SDK | SDKs for JavaScript, Python, and more are Apache 2.0 |
One staleness warning that saves real time: the install script gives you the surreal launcher, so every command in this guide starts surreal db ... — blog posts from the 2.x era that type bare surreal start or surreal sql are outdated and will fail.
How Do You Start Your First SurrealDB Server?
Start your first SurrealDB server in memory with a root user and password set at creation. The modern command is surreal db start, with the storage path as the final argument:
surreal db start memory --user root --pass root
The --user and --pass flags create the root user (OWNER role) on the first start of a new datastore only — the credentials are stored in the datastore itself, so re-running with different values changes nothing; to rotate them later you ALTER or DEFINE the user. The server binds to 127.0.0.1:8000 by default, which keeps your first afternoon local-only by design; --bind changes that when you are ready for remote access, and --log info (the default) narrates startup. Say this once: those demo credentials are not production — the security section below teaches access rules before you ever expose the port.
The Docker equivalent names the container, maps port 8000, and runs the same start command. For a first look, run it in memory exactly like the binary:
docker run --rm --pull always --name surrealdb \
-p 8000:8000 surrealdb/surrealdb:latest start \
--log info --user root --pass root memory
A persistent first server swaps memory for SurrealKV with a volume mount, so the database survives container restarts:
mkdir mydata
docker run --rm --pull always -p 8000:8000 \
--user $(id -u) \
-v $(pwd)/mydata:/mydata \
surrealdb/surrealdb:latest start \
surrealkv:/mydata/mydatabase.db
And a persistent server with a root user sets the credentials before the storage path:
docker run --rm --pull always -p 80:8000 \
-v /mydata:/mydata \
surrealdb/surrealdb:latest start \
--user root --pass secret surrealkv:/mydata/mydatabase.db
One port note: the official docs document only port 8000 for HTTP/RPC traffic. If an old tutorial mentions 8080, it is stale — trust 8000 everywhere in 2026.
What Are Namespaces and Databases in SurrealDB?
SurrealDB organizes data in four nesting levels: ROOT, then Namespace, then Database, then Table, then Field. A namespace is the outer container — it holds databases and nothing else, which makes it the multi-tenancy boundary (one namespace per tenant, per project, per environment). A database holds the tables. Since 3.0, surreal db start auto-defines a default namespace and database named main and main, and the SQL shell connects to them by default.
Creating your own is two statements, and switching context is two more:
DEFINE NAMESPACE ns;
DEFINE DATABASE db;
USE NS ns;
USE DB db;
The surrealdB namespaces question comes up mostly in migrations: if your queries land in the wrong place, you are in the wrong namespace — check USE NS before debugging the query itself. Keep the default main/main for learning, and carve real namespaces when you host more than one project on a server.
How Do You Create Records and Query Them?
SurrealDB tables are schemaless by default: a schemaless table accepts any record, which suits early development, while a SCHEMAFUL table stores only defined fields with types enforced on write. You never declare a table to start writing — the first CREATE makes it exist. Records get table-scoped IDs like user:alice, and one statement can target several tables at once.
The core SurrealQL every beginner needs is four statements:
-- Create two records
CREATE user:alice SET name = 'Alice', email = '[email protected]', age = 30;
CREATE user:bob SET name = 'Bob', email = '[email protected]', age = 28;
-- Read across tables in one query
SELECT * FROM article, post WHERE name CONTAINS 'SurrealDB';
-- Update with expressions
UPDATE employee SET salary = salary * 1.10 WHERE dept = 'Engineering';
-- Move a person into a company (record link, not a foreign key)
UPDATE person:tobie SET company = company:surrealdb;
Notice the last line: a field can hold a record link — a pointer to another record — which is the document-model side of the multi-model story. In the surrealql tutorial lane, the next concept is edges: links become queryable relationships instead of just pointers.
How Do Graph Edges Work in SurrealDB?
Graph edges in SurrealDB are typed, data-carrying relationships created with RELATE and traversed with arrow syntax — no JOINs, no lookup pipelines. The classic first edge is a follow:
-- Alice follows Bob, with data ON the edge
RELATE user:alice->follows->user:bob SET since = time::now();
-- Who does Alice follow?
SELECT ->follows->user.name AS following FROM user:alice;
-- Traverse a record link without RELATE
SELECT company.name FROM person:tobie;
Edges are records too, so they carry their own fields (since above), and traversal recurses — you can walk ->follows->user->follows->user in one query. This is the part of the multi-model engine that document-only databases bolt on afterward: in SurrealDB the graph is native, transactional, and written in the same language as the CRUD. If your data is mostly documents with occasional relationships, record links are enough; if relationships are the data (social graphs, networks, recommendations), RELATE is the tool.
What Are Live Queries?
Live queries are real-time subscriptions: LIVE SELECT returns a UUID and then pushes every create, update, and delete matching the query over WebSocket. One statement turns any table into an event stream:
-- Subscribe to everything on person
LIVE SELECT * FROM person;
-- Subscribe with a filter, or to diffs only
LIVE SELECT * FROM person WHERE age > 18;
LIVE SELECT DIFF FROM person;
-- Stop a subscription with its UUID
KILL "1986cc4e-340a-467d-9290-de81583267b";
The surrealdB live queries story has one caveat worth knowing early: in the community edition, a live query only receives changes made on the node holding its subscription, which is invisible on a single node and only matters when you scale out. Beginners get the full experience on one server — a dashboard that updates itself the moment a record changes is the standard first demo. The Surrealist GUI shows active subscriptions with their UUIDs, so you rarely type KILL by hand.
How Do You Secure SurrealDB for Remote Access?
Define access rules before you expose SurrealDB to anything beyond localhost, because the demo root credentials get you in but were never meant to face the internet. Say it once: --user root --pass root is a learning credential, not a production one. SurrealDB 3.x handles application users with DEFINE ACCESS ... TYPE RECORD — users authenticate against your own tables, replacing the old DEFINE SCOPE from the 2.x era. A minimal record-based login looks like this:
DEFINE ACCESS account ON DATABASE TYPE RECORD
SIGNUP ( CREATE user SET email = $email, pass = crypto::argon2::generate($pass) )
SIGNIN ( SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(pass, $pass) )
DURATION FOR TOKEN 15m, FOR SESSION 12h;
Your app then hits the built-in /signup and /signin HTTP endpoints, and passwords are hashed with argon2 inside the engine — never stored plain. Two more rules: never start a public-facing server with --unauthenticated (it makes every guest the root OWNER), and put TLS in front of port 8000 with a reverse proxy before remote clients connect. Our Caddy beginner guide walks the proxy-plus-HTTPS setup in a few lines. If you reach for an ORM instead of SurrealQL on the client side, Prisma covers the client-library lane on traditional SQL databases — SurrealDB is the database engine, the ORM is the client layer, and the two never compete.
How Do You Back Up SurrealDB?
Back up SurrealDB with surreal db export, which writes one namespace and database to a replayable .surql file containing the schema and records; surreal db import restores it. The backup rule is simple and it is the title promise of this guide:
surreal db export \
--endpoint http://localhost:8000 \
--user root --pass secret \
--ns main --db main export.surql
surreal db import \
--endpoint http://localhost:8000 \
--user root --pass secret \
--ns main --db main export.surql
The surrealdB backup story has two details that matter: exports are per namespace+database (back up each one you care about), and imports are committed statement-by-statement with a 4 GiB per-request ceiling. One staleness correction: there is no surreal backup or is-backup command in the current tooling — tutorials that mention them predate the export/import commands, so do not go looking for a binary that no longer exists. For a persistent Docker server, the volume holding your SurrealKV path deserves the same snapshot treatment as any database directory — the .surql export is your logical backup, the volume snapshot your physical one.
Which Storage Backend Should You Pick?
Pick the storage backend by answering one question: can this data disappear on restart? SurrealDB's backends moved around in the 3.x era, so pin your mental model to what ships now, not to 2024 tutorials. The decision:
| Backend | When to pick it | The catch |
|---|---|---|
memory (SurrealMX since 3.0) | Learning, tests, throwaway demos | Gone on restart; since 3.3, versioned (time-travel) queries are removed from the memory backend — mem:// with ?versioned=true fails to start |
surrealkv | Any real single server — this is the 2026 default on-disk engine | Time-travel needs explicit URL params (?versioned=true&retention=30d) |
tikv | Distributed clusters | You are running TiKV, which is a bigger decision than SurrealDB |
rocksdb | Never pick it new. Removed in 4.0 | rocksdb:// and indxdb:// are kept only as deprecated spellings of surrealkv:// — starting on a RocksDB directory auto-converts with a warning |
Since 3.0, backend options move after the path as URL params — surrealkv://path/to/db?versioned=true&sync=every&retention=30d — and the old 2.x surrealkv+versioned:// prefix form is gone. The surrealdB docker lane follows the same rule: the Docker command's final argument is the storage path, memory or SurrealKV, exactly like the binary.
SurrealDB vs MongoDB: What's Actually Different?
SurrealDB vs MongoDB is the comparison every evaluator asks, and the answer is architectural: SurrealDB is a multi-model engine where one language covers documents, graph, relations, time series, vectors, and key-values in one ACID transaction; MongoDB is a document database where graph, relational, and vector workloads need additional systems and the sync code between them. The head-to-head:
| Capability | SurrealDB | MongoDB |
|---|---|---|
| Data models | Document, graph, relational, time-series, geospatial, vector, key-value — one engine | Document-first; graph/relational/vector via other systems |
| Query language | SurrealQL across all models | MongoDB Query Language for documents |
| Relationships | Typed graph edges (RELATE) with recursive traversal | $lookup joins between collections |
| Real-time | LIVE SELECT over WebSocket, native | Change streams on top of the oplog |
| App-user auth | Record users with DEFINE ACCESS in the engine | Application-layer auth, roles on database users |
| Transactions | Single ACID transaction across models | Multi-document transactions within the document model |
| License | BSL-1.1 (source-available; converts to Apache 2.0) | SSPL |
Two honest draw-the-lines, because "database" is a wide word. If your workload is embedded analytics inside a single process — crunching Parquet files in Python, not serving a cluster — our DuckDB beginner guide covers the embedded lane: DuckDB is an in-process OLAP engine, SurrealDB is a server multi-model database, and the two never compete. And if you specifically need the MongoDB wire protocol on top of Postgres, our FerretDB beginner guide covers that translation layer — FerretDB speaks MongoDB's protocol, SurrealDB speaks SurrealQL. This comparison table and the storage-backend decision above are original syntheses for this guide.
What Are the Beginner Mistakes to Avoid?
Six mistakes account for most SurrealDB troubleshooting threads, and all six are version confusion or skipped security:
- Exposing port 8000 to the internet with demo credentials. Root
rootplus a public IP is a gift to scanners — define access rules and add TLS first. - Following 2.x tutorials verbatim.
surreal start,rocksdb://,DEFINE SCOPE, and the old surrealist.app era are all stale; the 3.x forms aresurreal db start,surrealkv://, andDEFINE ACCESS ... TYPE RECORD. - Requesting time-travel on the memory backend. Since 3.3,
mem://with?versioned=truerefuses to start — versioned queries need SurrealKV. - Forgetting the volume on Docker. A persistent server without
-vkeeps its SurrealKV data inside the container — updates wipe it. - Using
--unauthenticatedon any shared host. It disables auth entirely and hands every guest the root OWNER role. - Never exporting. The .surql export is cheap; run it on a schedule, because storage backends are not backups.
Sources
Every fact in this guide was verified on 2026-11-01 — making this SurrealDB tutorial current as of November 1, 2026: the latest stable release (3.3.4, released October 13, 2026; 3.0 GA February 2026; 4.0 in beta) on the releases page at surrealdb.com/releases; the star and fork counts (33,256 stars, 1,398 forks) and the install lines (Linux curl launcher, macOS Homebrew, Windows PowerShell) at github.com/surrealdb/surrealdb; the license terms (Business Source License 1.1 — free to use, modify, and self-host including in production, with the restriction on running it as a database service for third parties; conversion to Apache 2.0 no later than four years after release; SurrealKV and SurrealMX Apache 2.0) at surrealdb.com/license and the official open-source commitment post; the storage-backend story (memory default powered by SurrealMX since 3.0; SurrealKV as the on-disk engine; RocksDB and indxdb removed in 4.0 and kept as deprecated spellings of surrealkv:// with auto-conversion; FoundationDB removed in 3.0; URL params after the path since 3.0; versioned queries removed from the memory backend in 3.3; the --query-timeout flag in 3.3) at surrealdb.com/docs/reference/cli/db/commands/start and the SurrealMX launch post; the Docker commands (official image surrealdb/surrealdb, port 8000 in all interfaces, --user/--pass creating the root OWNER user on first start of a new datastore, --bind default 127.0.0.1:8000, --log levels, --unauthenticated) at surrealdb.com/docs/running/docker; the CLI syntax (surreal db start [OPTIONS] [PATH], datastore params as URL params, the 2.x prefix form gone) at surrealdb.com/docs/reference/cli and the start-command reference; the namespace/database model (ROOT → namespace → database → table → field; namespace as the multi-tenancy outer container; main/main auto-defined since 3.0; DEFINE NAMESPACE / DEFINE DATABASE / USE NS / USE DB) at surrealdb.com/learn/data-models/architecture and the sql-command reference; schemaless-by-default tables (SCHEMAFUL enforcing defined fields) at surrealdb.com/docs/surrealdb/start/install; the SurrealQL CRUD, RELATE, and traversal examples (CREATE user:alice, RELATE user:alice->follows->user:bob, SELECT ->follows->user.name) at surrealdb.com/surrealdb/features; the live-query syntax (LIVE SELECT, LIVE SELECT DIFF, KILL with the returned UUID, WebSocket push, the single-node subscription caveat in Community) at surrealdb.com/docs/reference/query-language/statements/live-select and the Learn book chapter 12; the access model (DEFINE ACCESS account ON DATABASE TYPE RECORD with SIGNUP/SIGNIN and crypto::argon2, the /signup and /signin endpoints, RECORD/JWT/BEARER types, replacing DEFINE SCOPE) at surrealdb.com/docs/reference/query-language/statements/define/access/record and the fundamentals security pages; the backup tooling (surreal db export / surreal db import with --endpoint/--user/--pass/--ns/--db, replayable .surql files, imports committed statement-by-statement with a 4 GiB per-request ceiling; no surreal backup/is-backup command) at surrealdb.com/docs/manage/instances/import-and-export and the export CLI reference; the multi-model-vs-MongoDB differentiator (one engine for documents, graph, relations, time series, geospatial, vectors, and key-values in a single ACID transaction) in the GitHub README and the install docs page; and the 2026 benchmark figures (141k ops/s mixed CRUD, full-table scans 164x faster than 2.x, measured May 2026 on a Threadripper 9970X with 128 GiB RAM and NVMe) on the official "3.x by the numbers" blog post. The storage-backend decision table, the SurrealDB-vs-MongoDB comparison table, and the 10-step first-run arc are original syntheses for this guide.
Frequently Asked Questions
Is SurrealDB free?
Yes. SurrealDB is free to use, modify, and self-host — including in production — under the Business Source License 1.1. The one restriction is offering SurrealDB itself as a database service to third parties. Each version converts to Apache 2.0 within four years of release, and the SurrealKV and SurrealMX storage engines are Apache 2.0 already.
Is SurrealDB open source?
Not in the OSI sense: it is source-available under BSL-1.1, which means the code is public and you can run and modify it freely, but it is not an OSI-approved open-source license. For a self-hoster that distinction rarely matters — your own server or VPS is fully covered. The client SDKs are Apache 2.0 or MIT, and Surrealist, the official GUI, is the companion you will use most.
What is SurrealQL?
SurrealQL is SurrealDB's query language: SQL-like, but extended for the multi-model world. The same language creates documents, relates graph edges, subscribes to live queries, and defines access rules and namespaces — so one syntax covers CREATE, SELECT, UPDATE, DELETE, RELATE, LIVE SELECT, and DEFINE statements. If you know SQL, you will read it immediately; the graph and live-query parts are the new vocabulary.
Does SurrealDB work with Docker?
Yes — Docker is the recommended server path. The official image surrealdb/surrealdb runs start as its command, listens on port 8000, and takes the storage path (memory or surrealkv:/path) as its final argument. Mount a host volume for any data you want to survive container restarts, and set a real root password with --user/--pass instead of the demo pair.
How do I back up SurrealDB?
Run surreal db export with your endpoint, credentials, namespace, and database — it writes a replayable .surql file you restore with surreal db import. Export each namespace+database you care about, on a schedule, and treat the export as your logical backup alongside volume snapshots. There is no surreal backup command in the current tooling — guides that mention one are stale.