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.
nutrients for eye health
October 16, 2026Clear information about discussing supplements with a healthcare professional helps readers ask better questions.
https://myspace.com/
October 16, 2026References:
Osko pokies video https://myspace.com/
http://creativespace.biz/discuss/forum/home.php?mod=space&uid=237406
October 16, 2026References:
Live dealer casino bank transfer australia http://creativespace.biz/discuss/forum/home.php?mod=space&uid=237406
https://m.novoporno.cc
October 16, 2026Greetings 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