SurrealDB on a VPS: Multi-Model Database for Graph, Document, and SQL in One Service

SurrealDB on a VPS: Multi-Model Database for Graph, Document, and SQL in One Service

SurrealDB is a multi-model database that combines SQL, graph traversal, and document storage in one engine — you can run SQL queries, traverse graph relationships, and store schema-optional JSON documents, all on the same data with one query language (SurrealQL). A single binary handles what would otherwise require PostgreSQL (SQL), Neo4j (graph), and MongoDB (documents). It’s built in Rust, extremely fast, and includes built-in authentication, permissions, and real-time live queries.

When SurrealDB Shines

  • Social networks: Combines user profiles (documents) with friendship graphs (graph) and activity feeds (SQL)
  • Knowledge graphs: Documents linked with typed relationships traversable in single queries
  • Real-time apps: Live queries push changes to clients over WebSocket automatically
  • Rapid prototyping: Schema-optional — add fields without migrations during development
  • Embedded auth: Built-in user authentication, tokens, and permissions

Step 1: Install SurrealDB

<code"># Download and install (single binary)
curl -sSf https://install.surrealdb.com | sh

# Or download directly:
wget https://github.com/surrealdb/surrealdb/releases/latest/download/surreal-linux-amd64
chmod +x surreal-linux-amd64 && sudo mv surreal-linux-amd64 /usr/local/bin/surreal

# Verify
surreal version
<code">sudo nano /etc/systemd/system/surrealdb.service
<code">[Unit]
Description=SurrealDB
After=network.target

[Service]
Type=simple
User=ubuntu
ExecStart=/usr/local/bin/surreal start \
    --log info \
    --user ${SURREAL_USER} \
    --pass ${SURREAL_PASS} \
    --bind 127.0.0.1:8000 \
    file:/opt/surrealdb/data.db
Restart=on-failure
Environment=SURREAL_USER=admin
Environment=SURREAL_PASS=StrongSurrealPassword!

[Install]
WantedBy=multi-user.target
<code">mkdir -p /opt/surrealdb
sudo systemctl daemon-reload
sudo systemctl enable surrealdb
sudo systemctl start surrealdb

Step 2: Nginx Reverse Proxy

<code">sudo nano /etc/nginx/sites-available/surrealdb
<code">server {
    listen 443 ssl http2;
    server_name db.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/db.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/db.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 300s;
    }
}
<code">sudo certbot --nginx -d db.yourdomain.com
sudo systemctl reload nginx

Step 3: SurrealQL Queries

<code"># Connect via CLI:
surreal sql --conn https://db.yourdomain.com \
    --user admin --pass StrongSurrealPassword! \
    --ns myapp --db production

# Or use the web REPL: https://surrealist.app
<code"># Create namespace and database
USE NS myapp DB production;

-- ── Document-style records ─────────────────────────────
-- Schema-less, like MongoDB:
CREATE user SET
    name = "Alice Chen",
    email = "alice@example.com",
    age = 30,
    skills = ["Python", "Go", "Kubernetes"],
    address = { city: "San Francisco", country: "US" };

-- ── Graph relationships ──────────────────────────────────
-- Create users and relate them:
CREATE person:alice SET name = "Alice";
CREATE person:bob SET name = "Bob";
CREATE person:charlie SET name = "Charlie";

-- Create typed graph edges:
RELATE person:alice -> knows -> person:bob
    SET since = "2020-01-01", strength = 0.9;
RELATE person:bob -> knows -> person:charlie
    SET since = "2022-06-01", strength = 0.7;

-- Graph traversal: who does Alice know transitively?
SELECT ->knows->person AS connections
FROM person:alice;

-- Traverse 2 hops (friends of friends):
SELECT ->knows->person->knows->person AS fof
FROM person:alice;

-- ── SQL-style queries ─────────────────────────────────────
SELECT name, email
FROM user
WHERE age > 25
ORDER BY name ASC
LIMIT 10;

-- SQL with graph traversal combined:
SELECT name, ->knows->person.name AS friends
FROM person
WHERE array::len(->knows->person) > 2;

Step 4: JavaScript SDK

<code">npm install surrealdb.js
<code">import Surreal from 'surrealdb.js';

const db = new Surreal();

// Connect to SurrealDB
await db.connect('https://db.yourdomain.com/rpc', {
    namespace: 'myapp',
    database: 'production',
    auth: {
        username: 'admin',
        password: 'StrongSurrealPassword!',
    },
});

// Create a record
const user = await db.create('user', {
    name: 'David Lee',
    email: 'david@example.com',
    tags: ['new', 'enterprise'],
});
console.log(user[0].id);   // user:xyz123abc

// Query with SurrealQL
const results = await db.query(
    'SELECT * FROM user WHERE email = $email',
    { email: 'david@example.com' }
);

// Real-time subscription (live queries)
const subscription = await db.live('user', (action, result) => {
    if (action === 'CREATE') console.log('New user:', result.name);
    if (action === 'UPDATE') console.log('Updated:', result.id);
    if (action === 'DELETE') console.log('Deleted:', result.id);
});

// When done:
await db.kill(subscription);

Step 5: Built-in Authentication

<code"># SurrealDB has built-in user authentication — no separate auth service needed:

-- Define a scope (user authentication namespace)
DEFINE SCOPE account SESSION 14d
    SIGNIN ( SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(password, $password) )
    SIGNUP ( CREATE user CONTENT {
        name: $name,
        email: $email,
        password: crypto::argon2::generate($password),
    });

-- User signup (from application):
db.signup({
    namespace: 'myapp',
    database: 'production',
    scope: 'account',
    email: 'newuser@example.com',
    password: 'securepassword',
    name: 'New User',
});

-- User signin:
const token = await db.signin({
    namespace: 'myapp',
    database: 'production',
    scope: 'account',
    email: 'user@example.com',
    password: 'theirpassword',
});
// token is a JWT for subsequent requests

Getting Started

SurrealDB is a single Rust binary — 50–200 MB RAM at idle. A 1 GB Ubuntu VPS at VPS.DO handles SurrealDB for small to medium applications. For production workloads, 2–4 GB provides comfortable headroom. NVMe storage significantly improves write throughput since SurrealDB persists to disk.

Conclusion

SurrealDB consolidates SQL queries, graph traversal, and document storage into one database with one query language — eliminating the need for separate PostgreSQL, Neo4j, and MongoDB services for applications that benefit from all three paradigms. Built-in authentication, live queries, and a schema-optional document model make it particularly well-suited for real-time applications with complex data relationships. The single binary deployment is as simple as PocketBase while offering significantly more query power.

4 Comments

  • nutrients for eye health
    October 16, 2026

    Clear information about discussing supplements with a healthcare professional helps readers ask better questions.

  • https://myspace.com/
    October 16, 2026

    References:

    Osko pokies video https://myspace.com/

  • http://creativespace.biz/discuss/forum/home.php?mod=space&uid=237406
    October 16, 2026

    References:

    Live dealer casino bank transfer australia http://creativespace.biz/discuss/forum/home.php?mod=space&uid=237406

  • https://m.novoporno.cc
    October 16, 2026

    Greetings from Carolina! I’m bored to death at
    work so I decided to browse your site on my iphone during lunch break.
    I love the knowledge you present here and can’t wait to take a
    look when I get home. I’m surprised at how quick your blog loaded on my mobile ..

    I’m not even using WIFI, just 3G .. Anyhow, excellent blog!
    xnxx

Post Your Comment

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!