SurrealDB overview: a multi-model database for modern applications
SurrealDB stores documents, graphs, vectors, time-series and table data in one ACID transaction. So one database can stand in for four specialist tools.
SurrealDB overview: what is unified data storage?#
SurrealDB is a multi-model database that stores documents, graphs, vectors, time-series, and relational data in one ACID-compliant engine, queryable in a single transaction. One database can stand in for the specialist tools teams often run side by side: MongoDB for documents, Pinecone for vectors, Neo4j for graphs, and InfluxDB for time-series data. So what used to need four specialist databases can live on one platform that developers manage through one interface.
For instance, most teams deploy databases for each data type. MongoDB holds documents. Pinecone holds vectors. Neo4j holds links between records. InfluxDB holds time-series data. PostgreSQL holds table data. When you run a separate database for each, every one needs its own setup, monitoring, backups and connection pool. So this multiplies your running work. Because each database runs separately, a change in one may not appear in another for seconds or minutes. This creates gaps and bugs. Syncing data between them is the hardest part.
Per SurrealDB's docs as of September 2026, the platform supports seven data model types: documents, graphs, vectors, time-series, relational, geospatial and key-value storage. All seven are queryable through a single interface and accessible in one transaction.
| Data model | Separate database this post names |
|---|---|
| Documents | MongoDB |
| Vectors | Pinecone |
| Graphs | Neo4j |
| Time-series | InfluxDB |
| Relational | PostgreSQL |
| Geospatial | None named in this post |
| Key-value | None named in this post |
The one approach cuts duplicate work in both directions. You don't sync between MongoDB and Pinecone using jobs that can fail. For example, you don't rebuild event counts when Neo4j links change. Because one database holds all data, ACID guarantees ensure consistency. When you query, one transaction means all data comes from the same moment in time.
How can you query multiple data models in one transaction?#
One query joins documents, traverses edges, searches vectors, and scans events, all in one transaction. Define links across all data models in a single schema and transaction. Create a customer record as a document with embedded vector fields for semantic search. Link customers using graph edges for partnerships or trees. When you query all three models in one SELECT statement with vector match filters and time-series aggregations, it all happens in the same ACID transaction. So there's no trust delay, no lag between databases drifting out of sync.
Case: semantic search for similar customers. The old way requires querying Pinecone for matches, fetching records from MongoDB, looking up links in Neo4j, and counting events in InfluxDB. Then you join all results in app code. Each API call adds latency. Because each call can fail, your app must handle failures from any database. Often, one database returns stale data while another is current, so your result mixes values from other moments. SurrealDB does the same work in one statement within one transaction. As a result, all data comes from the same moment in time, and each value is guaranteed consistent.
SurrealQL syntax mirrors SQL but adds graph operators like the -> arrow for edge traversal and vector functions like vector::match for embedding search. A customer can write SELECT * FROM customer WHERE vector::match(embedding, my_vector) > 0.85 to find similar customers by embedding. The same query can traverse edges to find partners and count events, all in one SELECT. So learning SurrealQL is faster than mastering four other systems. The syntax stays the same whether you run embedded or in a cluster.
What deployment options does SurrealDB support?#
You can run SurrealDB embedded in your application, as a single server, or as a distributed cluster across regions. You can switch deployment without changing your code. Four production-ready options exist: embedded mode, WebAssembly browser, single-node backend, and cluster. Embedded mode runs SurrealDB as a library inside your app with no network calls or server overhead, ideal for serverless functions. WebAssembly browser runtime runs SurrealDB in browsers for offline-first and real-time sync patterns. Single-node backend runs as a server with REST, WebSocket and driver connections. Cluster mode adds backups, load balancing and replication globally.
| Mode | Where it runs | What it suits |
|---|---|---|
| Embedded | As a library inside your app, with no network calls or server | Serverless functions, offline-first web apps and single-page apps |
| WebAssembly | In the browser | Offline-first and real-time sync patterns, client apps and mobile web |
| Single-node | As a server with REST, WebSocket and driver connections | Backend needs |
| Cluster | Across regions, with backups, load balancing and replication | High-scale workloads that need failover and scale |
Runtime patterns remain identical across all setups. Define your schema once, write calls once, and your code connects whether SurrealDB runs embedded, on a server, or in a cluster. Scale from laptop to live systems without rewriting app code.
Embedded setup suits serverless jobs, offline-first web apps and single-page apps by cutting network latency. You have no server to run, and query via calls instead of HTTP requests. When you need client-side setup, WebAssembly runs SurrealDB in browsers for client apps and mobile web. For backend needs, run single-node as a server. For high-scale workloads, cluster mode adds failover and scale.
When is SurrealDB the wrong tool for the job?#
SurrealDB is not a fit when your data is purely relational, when old tools need real SQL, or when your host offers managed services only. SurrealDB wins when you query many data shapes in one transaction; it loses when you need only one shape or when setup simplicity isn't a priority for your team.
When your workload is pure relational data, PostgreSQL is a better choice. It has decades of tuning, a wider ecosystem, and more talent available. If you need only tables and don't touch graphs or vectors or time-series, PostgreSQL's focus on that one job is an advantage. If your team is already deep in Microsoft SQL Server or Oracle, retraining costs might outweigh SurrealDB's gains. Also, Amazon RDS and Google Cloud SQL don't host SurrealDB yet. So if your procurement team requires a managed database from a major vendor, SurrealDB's open-source path doesn't fit. You'll need to run it yourself or find a third-party managed host. When you can't afford the operations weight of running your own database, a managed SQL database is the simpler choice.
Self-managed databases need runtime expertise to run, watch, copy and scale under load. So the bringing win is real for teams running many systems. When you now run MongoDB, Milvus, Neo4j and TimescaleDB, one SurrealDB instance removes four setups, four copy systems, four watching surfaces and cuts sync logic between stores. Because you no longer need sync jobs between systems, you remove a source of data corruption and fails. Your setup becomes simpler and your runtime work drops.
What real-world patterns benefit from multi-model queries?#
SurrealDB unifies embeddings, documents, events and links in AI search, analytics dashboards and access control patterns. Vector search queries improved 8x in 3.0, dropping from 35 seconds to 4.5 seconds for HNSW indexes. The CRM pattern (documents plus edges plus vectors plus items) shows why bringing it together on one database cuts sync logic between four stores and removes the risk of divergence during fails.
Show data table
| Item | Value |
|---|---|
| Before the 3.0 optimisation | 35 seconds |
| After the 3.0 optimisation | 4.5 seconds |
Vector search queries improved 8x in 3.0, dropping from 35 seconds to 4.5 seconds for HNSW indexes.
An AI-powered customer relationship care system stores customer documents with embedded vectors for semantic search. Opportunities link to customers via graph edges for account trees. Each touch (email, call, proposal) records as a time-series event. So one query finds customers like a target, checks industry match, and counts activity items per customer, in ACID. Because the data is fresh in one transaction, you know the match score matches the engagement count at that same moment in time.
The old way uses four databases: MongoDB for documents, Pinecone for embeddings, Neo4j for links, and TimescaleDB for events. Your backend makes four API calls and combines the results in code. Because one API call can be slow, your whole request slows down. If one database returns stale data, your result is wrong. SurrealDB does the same work in one query. So you eliminate join logic in your app, prevent sync lag between stores, and have one source of truth.
Real-time analytics dashboards gain from multi-model calls too. So store items as time-series, profiles as documents, count rolling averages inside SurrealDB, and filter by graph-traversal team trees. Because SurrealDB's live calls stream updates to browsers when underlying data changes, dashboards refresh without polling. So you can build a dashboard that shows a user their top contacts (via graph traversal), their recent items (time-series), and similar accounts (vector search) on one screen, all updated in real time.
Fine-grained access control binds to graph links and org structure. Define access policies that traverse customer trees in SurrealDB using graph traversal. Store permission scopes as graph edges, so a sales director's edge connects to all subordinate salespeople. Enforce these access policies inside the query engine itself, not in app middleware or a different authorization tool. When an org change occurs and you update the graph edges, every linked query result and access decision updates. You don't need to invalidate caches or rebuild permission indexes manually. If you promote a manager to a new role, update one graph edge and their access changes instantly system-wide. This is impossible with databases that distribute permission checks across app code and other systems.
How do you start migrating from separate databases to SurrealDB?#
Start with the SurrealQL reference to learn the query syntax, then the embedding guide for your language, then build your first multi-model schema. Official-docs tools in build order for SurrealDB mastery:
Model the core documents
Define tables for the core documents you need with all needed fields.
Add graph edges
Model the links between customer records, product records and order records.
Add vector fields
Semantic search can then find similar customers or products by meaning.
Prove one multi-model query
Join documents, edges and vectors in one query, and test it in a single transaction.
Port the remaining calls
Move your app calls one by one from MongoDB, Neo4j, Pinecone and InfluxDB into SurrealQL.
- SurrealQL reference covers SELECT, CREATE, UPDATE, DELETE, graph traversal and vector search functions.
- Live calls guide shows streaming updates to browsers when data changes in SurrealDB.
- security and permissions guide shows how to bind access policies to app identity and enforce them inside the database.
- deployment guide explains when to run SurrealDB embedded, as a server or as a cluster.
Start with a small multi-model schema in development. Define tables for the core documents you need with all needed fields. Add graph edges to model links between customer records, product records, and order records. Add vector fields to documents for semantic search so your model can find similar customers or products by meaning. Write one query joining documents, edges and vectors. Test that query in a single transaction to confirm it returns the data you need. Once that works, port your remaining app calls one by one from MongoDB, Neo4j, Pinecone and InfluxDB into SurrealQL. Test that the multi-model version returns the same results as your original separate-database calls returned. For each query you port, run both the old code and the new code on the same test data and compare the results row by row. Because the calls are independent, you can test each one in isolation before you move to the next. This keeps changes small and lets you catch mistakes early. Once you're confident a query is right, move it to live code.
As a result, the rewrite is methodical, not painful. Each query port is one discrete step. Most teams migrate a moderate-size app in weeks, not months. Because SurrealQL resembles SQL, developers who know SQL start writing SurrealQL calls on day one. The learning curve is gentle compared to learning Pinecone, Neo4j, and InfluxDB all at once. When you finish migration, retire four database clusters and streamline your production setup. You'll drop the sync jobs between stores, which removes a whole class of bugs. You'll cut four connection pools down to one and manage one set of backups instead of four. Your app code gets simpler because you don't route queries to four different systems anymore.
What operational benefits does consolidation on one database bring?#
Once you consolidate, you run one database instead of four: less to run, simpler backup, one observability plane.
| What you run | Four separate databases | One SurrealDB instance |
|---|---|---|
| Setups | Four | One |
| Monitoring systems | Four | One |
| Backup plans | Four | One |
| Restore procedures to test | Four | One |
| Connection pools | Four | One |
Four databases multiply the work and create many failure modes. Each needs setup, watching, alerting, backup plans and fix steps. When sync jobs between stores fail, you debug failures across system boundaries. So corruption in one database can spread to others. Each sync job becomes another place where failures can start. You maintain four backup plans, four fix procedures, and four runbooks for other failure scenarios.
Backups and restores get simpler with SurrealDB. Instead of coordinating snapshots across four databases, restoring consistency across four stores, and rebuilding state after partial data loss, you fix a single backup snapshot because SurrealDB uses one transaction. ACID guarantees ensure consistency across all data models at restore time. So you restore one backup instead of four and test one restore procedure instead of four.
Networking also eases because one connection pool replaces four pools. So your app uses one database connection instead of managing four others. One set of credentials replaces four. One firewall rule replaces four inbound rules. Because SurrealDB has one client, your code doesn't need to handle other connection behaviors from four other systems. MongoDB's connection pool works differently from InfluxDB's pool, so developers must tune each one. With SurrealDB, you tune one connection pool instead of four.
How does a multi-model query in SurrealDB replace separate single-model queries?#
One query creates documents, links them via edges, searches vectors and aggregates time-series data. A single SurrealQL statement that creates documents, traverses graph edges, searches embeddings and scans time-series replaces three calls against three other databases in traditional apps.
-- Define customer table with permissions
DEFINE TABLE customer SCHEMAFULL
PERMISSIONS
FOR select WHERE owner == $auth.id;
-- Create customer record with embedding vector
CREATE customer:alice SET
name = 'Alice Corp',
industry = 'SaaS',
embedding = [0.1, 0.2, 0.3];
-- Create graph edge between customers
CREATE account_link FROM customer:alice TO customer:bob
SET relationship = 'partner';
-- Query documents, traverse edges, search by embedding
SELECT
name,
industry,
->account_link->customer AS partners,
(SELECT VALUE count() FROM items WHERE id = customer:alice) AS event_counts
FROM customer
WHERE vector::match(embedding, $vector) > 0.85; This sequence shows how SurrealDB joins five different jobs in one place. The DEFINE TABLE statement creates a table and locks down who can read it. Only users logged in as themselves get to see their own records. CREATE customer:alice builds a record with a name, an industry tag and an embedding vector. CREATE account_link makes an edge from Alice to Bob and marks what kind of link they share. The SELECT at the end reaches into customer records, finds ones with embeddings close to a target vector, and counts events for each match, all in one go. You get back customers sorted by match score plus their event counts on the same row. All of this happens in one transaction, so when the query finishes, you know the match score matches the event count at that exact same moment.
In the old way, this work spreads across four systems. Vector search runs in Pinecone, documents live in MongoDB, graph links stay in Neo4j, and events record in InfluxDB. Your app code makes four API calls and tries to join the results. Because each call can fail or timeout, you need retry logic in app code. If Pinecone returns matches but Neo4j is slow, you have to choose: wait for both, use partial data, or fail the whole request. Worse, one database might return fresh data while another is stale, so your result mixes values from other moments in time. SurrealDB does it in one query in one ACID transaction, so trust is built in and timing is certain. If the query runs, all values come from the same moment and all are complete.
The setup needs learning SurrealQL syntax, which resembles SQL but adds graph traversal using the -> operator and vector functions like vector::match. The arrow operator -> reaches into edges. So ->account_link->customer traverses from the current customer via their account links to the linked customers on the other side. Official docs give examples for each data type. Because SurrealQL is faster than mastering four other database syntaxes, developers learn it quickly. The one syntax reduces confusion and bugs in query logic. Developers write less code, test fewer code paths, and deploy fewer dependencies than when using four different systems.
What are your next steps for building with SurrealDB?#
Explore API design, system architecture choices and database tuning strategies.
API types and architectures covers the design patterns that connect frontend and backend systems, essential for choosing how to expose your SurrealDB queries. Microservices vs monolith explores architectural patterns that affect how you deploy SurrealDB across your setup. Common MySQL performance bottlenecks identifies tuning strategies that apply to any database system including multi-model databases like SurrealDB.
For build support after this SurrealDB overview, consult build and launch if you need architecture and coding help for SurrealDB systems. Use scale and tune if your SurrealDB overview app runs live and needs multi-model schema redesign or query tuning guidance.
SurrealDB's docs at surrealdb.com/docs are complete and up to date. Use them as your reference as you build your first multi-model calls with SurrealDB. This SurrealDB overview is your starting point.