SurrealDB: The Multi-Model Database That Wants to Replace Your Entire Backend
Hook
Most databases solve one problem well. SurrealDB attempts to replace your database, API layer, authentication service, and real-time infrastructure with a single Rust binary. Ambitious? Absolutely. But the architecture suggests they might actually pull it off.
Context
The modern web application stack has become absurdly complex. You start with PostgreSQL for relational data, add Redis for caching, bolt on Elasticsearch for full-text search, introduce Neo4j when you need graph queries, implement Firebase or Supabase for real-time subscriptions, layer on Auth0 or similar for authentication, and wrap everything in a REST or GraphQL API. Each component requires configuration, monitoring, and expertise.
SurrealDB emerged from this complexity with a radical premise: what if a single database engine could handle all these use cases natively? Not through plugins or extensions, but as first-class features in the core architecture. Built in Rust and released in 2022, it combines document, graph, relational, time-series, geospatial, and key-value models with built-in authentication, permissions, and WebSocket-based real-time subscriptions. The promise is compelling—simplify your stack dramatically without sacrificing capabilities. But the real question is whether this consolidation creates new problems while solving old ones.
Technical Insight
SurrealDB's architecture centers on SurrealQL, a SQL-like query language that seamlessly handles multiple data models. Unlike databases that force you to choose between relational and document paradigms, SurrealQL lets you work with both simultaneously. Here's a practical example showing how it handles graph relationships alongside structured data:
-- Create a person with structured fields
CREATE person:john SET
name = 'John Doe',
email = 'john@example.com',
metadata = {
preferences: ['rust', 'databases'],
location: { latitude: 51.5074, longitude: -0.1278 }
};
-- Create a relationship (graph model)
RELATE person:john->follows->person:jane SET since = time::now();
-- Query with graph traversal and document filtering
SELECT name, ->follows->person.name AS following
FROM person
WHERE metadata.preferences CONTAINS 'rust';
-- Real-time subscription to changes
LIVE SELECT * FROM person WHERE metadata.location.latitude > 50;
Notice how the same query language handles structured fields (name, email), nested documents (metadata), graph relationships (->follows->), geospatial data, and real-time subscriptions. This isn't syntactic sugar over separate engines—SurrealDB's storage layer natively understands these patterns.
The deployment flexibility is where architecture meets pragmatism. SurrealDB compiles to a single binary with zero runtime dependencies, but more impressively, it compiles to WebAssembly for in-browser execution. You can start development with an embedded instance, prototype in the browser, deploy to edge functions, then scale to a distributed cluster—all using identical query syntax. The in-memory mode is particularly elegant for testing:
use surrealdb::engine::local::Mem;
use surrealdb::Surreal;
#[tokio::main]
async fn main() -> surrealdb::Result<()> {
let db = Surreal::new::<Mem>(()).await?;
db.use_ns("test").use_db("test").await?;
// This exact code works with engine::remote::ws::Ws for production
let person: Option<Person> = db
.create(("person", "john"))
.content(Person {
name: "John Doe".into(),
company: "Acme Inc".into(),
})
.await?;
Ok(())
}
The row-level permissions system deserves special attention because it replaces what you'd typically implement in application middleware. You define permissions directly in table schemas:
DEFINE TABLE article SCHEMAFULL
PERMISSIONS
FOR select WHERE published = true OR $auth.id = author
FOR create WHERE $auth.id != NONE
FOR update, delete WHERE $auth.id = author;
DEFINE FIELD title ON article TYPE string;
DEFINE FIELD author ON article TYPE record<user>;
DEFINE FIELD published ON article TYPE bool DEFAULT false;
The $auth variable represents the authenticated session, and these permissions enforce at the database layer—not in your API code. This is powerful because your permissions logic lives with your data schema, versioned and migrated together. Multiple client applications can connect directly to SurrealDB without reimplementing authorization logic.
For AI and semantic search workloads, SurrealDB includes native vector search alongside full-text indexing. The implementation uses HNSW (Hierarchical Navigable Small World) graphs for approximate nearest neighbor searches, letting you store embeddings and perform similarity searches without external vector databases:
DEFINE INDEX embedding_idx ON document FIELDS embedding MTREE DIMENSION 1536;
SELECT * FROM document
WHERE embedding <|2,1536|> [0.1, 0.2, ...]
LIMIT 10;
The <|2,1536|> operator performs cosine similarity search with 1536 dimensions (matching OpenAI's embedding size). Combined with traditional SQL filtering, you can implement hybrid search—semantic similarity constrained by metadata filters—in a single query. This architectural decision to include vector search natively rather than relegating it to plugins reflects SurrealDB's philosophy: common modern patterns should be first-class features.
Gotcha
The BSL 1.1 license creates a real tension for organizations with strict open-source policies. While the code is source-available and becomes Apache 2.0 after four years, you cannot offer SurrealDB as a managed service without a commercial license. For most users this is fine, but enterprises often have blanket policies against non-OSI licenses. More pragmatically, you're betting on a young company's longevity—if SurrealDB pivots or shutters, your migration path isn't as clear as with PostgreSQL or MongoDB where multiple vendors offer support.
Production operational maturity is the bigger concern. Documentation covers basic deployment but lacks depth on cluster sizing, backup strategies, performance tuning, and monitoring best practices. The distributed mode uses a Raft-based consensus protocol, but there's limited guidance on node configuration, network partitioning scenarios, or capacity planning. Query optimization tools are minimal—no EXPLAIN plans showing index usage, no slow query logging infrastructure. You're pioneering rather than following established patterns, which means more discovery work and potentially expensive mistakes. The community is helpful but small compared to established databases, so Stack Overflow won't bail you out at 2 AM. Migration tooling from existing databases is nascent; you'll likely write custom scripts to move data from PostgreSQL or MongoDB. For greenfield projects this is manageable, but retrofitting existing systems requires significant investment.
Verdict
Use if: You're building a modern application from scratch that needs multiple data models, real-time features, or edge deployment; you want to eliminate middleware by pushing authentication and permissions to the database layer; you're comfortable with Rust tooling and can contribute back when you hit undocumented edge cases; you're building AI-powered applications that benefit from native vector search alongside traditional queries; or you value deployment simplicity and want a single binary without runtime dependencies. Skip if: You require battle-tested enterprise support with multiple vendor options; you have strict OSI open-source license requirements; you need extensive third-party integrations and tooling ecosystems; you're migrating a large existing system and need proven migration paths; or your organization is risk-averse and unwilling to debug database internals. SurrealDB represents the future of database consolidation, but adopting it today means accepting pioneering responsibilities alongside its architectural elegance.