SurrealDB

A multi-model cloud-native database with a SQL-like query language, real-time subscriptions, and a single binary that runs embedded or as a server.

Screenshot of SurrealDB

SurrealDB is a multi-model database written in Rust that can run as a standalone server, be embedded directly into your application, or deployed to the cloud. It supports document, graph, relational, and time-series data in a single engine, queried with SurrealQL — a familiar SQL-like language extended with graph traversal, geospatial queries, and real-time change feeds.

Features

  • Multi-model — store and query documents, related records (graph edges), and time-series data all in one database, without stitching together multiple systems
  • SurrealQL — a rich query language that looks like SQL but adds record links, graph traversal (->, <-), destructuring, and first-class support for nested objects and arrays
  • Real-time subscriptionsLIVE SELECT queries push changes to connected clients over WebSocket as they happen
  • Single binary — the surreal CLI starts a full database server, runs an embedded in-process database, or launches an interactive REPL — no separate installation steps
  • Schemaless or schemafull — define strict schemas with DEFINE TABLE ... SCHEMAFULL or go fully schemaless; mix both in the same database
  • Fine-grained permissions — row-level access control defined directly in the schema using SurrealQL expressions
  • Multi-tenancy — first-class namespaces and databases allow clean separation of tenants within a single server instance
  • Embedded mode — embed SurrealDB directly into a Rust application using the surrealdb crate, with the same query API as the server
  • Multiple storage backends — in-memory, RocksDB (persistent), TiKV (distributed), and SurrealKV

Installation

Download a pre-built binary from the official website:

# Debian / Ubuntu / Fedora
# No apt or dnf package is available. Use the official install script (works on all Linux distributions):
curl -sSf https://install.surrealdb.com | sh

# macOS (Homebrew alternative — install script)
curl -sSf https://install.surrealdb.com | sh

# macOS (Homebrew)
brew install surrealdb/tap/surreal

# Windows (scoop)
scoop bucket add surrealdb https://github.com/surrealdb/scoop.git
scoop install surreal

# cargo
cargo install surrealdb-cli

Starting a server

# Start an in-memory server (data lost on restart — good for development)
surreal start --log debug --user root --pass root memory

# Start a persistent server backed by RocksDB
surreal start --log info --user root --pass root file:///data/mydb

# Start on a custom bind address and port
surreal start --bind 0.0.0.0:8000 --user root --pass root memory

Interactive REPL

# Connect to a running server and open an interactive SQL shell
surreal sql --conn http://localhost:8000 --user root --pass root --ns myns --db mydb

SurrealQL Examples

-- Create a record (document-style)
CREATE person:alice SET
  name = 'Alice',
  age  = 30,
  tags = ['rust', 'databases'];

-- Select with filtering
SELECT name, age FROM person WHERE age > 25 ORDER BY age;

-- Graph relationships — connect two records with an edge
RELATE person:alice -> knows -> person:bob
  SET since = time::now();

-- Traverse the graph
SELECT ->(knows)->person.name AS friends FROM person:alice;

-- Live query — subscribe to real-time changes
LIVE SELECT * FROM orders WHERE status = 'pending';

-- Define a schemafull table with permissions
DEFINE TABLE post SCHEMAFULL
  PERMISSIONS
    FOR select WHERE published = true OR author = $auth.id
    FOR create, update WHERE author = $auth.id
    FOR delete WHERE author = $auth.id;

DEFINE FIELD title   ON post TYPE string;
DEFINE FIELD body    ON post TYPE string;
DEFINE FIELD author  ON post TYPE record(person);
DEFINE FIELD published ON post TYPE bool DEFAULT false;

Embedded usage in Rust

use surrealdb::Surreal;
use surrealdb::engine::local::Mem;

#[tokio::main]
async fn main() -> surrealdb::Result<()> {
    // Open an in-process in-memory database
    let db = Surreal::new::<Mem>(()).await?;

    db.use_ns("myapp").use_db("production").await?;

    // Insert a record
    let _: Vec<serde_json::Value> = db
        .create("person")
        .content(serde_json::json!({ "name": "Alice", "age": 30 }))
        .await?;

    // Query it back
    let people: Vec<serde_json::Value> = db
        .query("SELECT * FROM person WHERE age > 25")
        .await?
        .take(0)?;

    println!("{people:#?}");
    Ok(())
}

Export and import

# Export a database to a SurrealQL file
surreal export --conn http://localhost:8000 --user root --pass root \
  --ns myns --db mydb backup.surql

# Import a SurrealQL file into a database
surreal import --conn http://localhost:8000 --user root --pass root \
  --ns myns --db mydb backup.surql