HeliosDB Nano is an embedded SQL engine that speaks the PostgreSQL wire protocol, so PostgreSQL clients, drivers and ORMs connect to it, but it is not a full semantic replacement for PostgreSQL. It runs in-process or as a server and builds HNSW vector search, branching and time-travel queries into the engine. Row-level security is not enforced for wire or REST clients. Licensed Apache 2.0.
Last updated
Choose HeliosDB Nano when you want PostgreSQL clients and SQL in an embedded library or a single server binary, with vector search, branching and time-travel queries built into the engine; keep PostgreSQL when you need full semantic compatibility, row-level security enforced for network clients, PL/pgSQL procedures, extensions or foreign data wrappers, or its long production record.
PostgreSQL is the gold standard for relational databases. HeliosDB Nano brings the PostgreSQL wire protocol and a large documented subset of its SQL to embedded and single-binary server deployments. That is client compatibility, not semantic parity: read the known limitations before you migrate.
| Feature | PostgreSQL | HeliosDB Nano |
|---|---|---|
| Deployment | Server process | Embedded library or server |
| Configuration | postgresql.conf and tuning | Command-line flags or a TOML file |
| Operations | Server administration | Embedded: no server to run; server mode: auth, TLS and dump-based backups |
| SQL Compatibility | Native | Large documented subset, not semantic parity |
| Wire Protocol | Native | Compatible |
| Vector Search | pgvector extension | Built-in HNSW (default build) |
| Encryption | pgcrypto extension | AES-256-GCM at rest, off until enabled with a key |
| Database Branching | No | Yes |
| Time-Travel | No | Yes, within retention |
| Row-Level Security | Yes, for every client | Embedded API and REPL only; SQL CREATE POLICY and wire/REST enforcement planned |
| JSONB | Yes | Yes |
| Window Functions | Yes | Yes |
Client compatibility and a large SQL subset — not full semantic parity (FAQ):
->, ->> and @>-- These queries run on both (collation and NULL ordering can differ):
-- CTEs
WITH active_users AS (
SELECT user_id FROM orders
WHERE order_date > NOW() - INTERVAL '30 days'
GROUP BY user_id
)
SELECT * FROM users WHERE id IN (SELECT user_id FROM active_users);
-- Window functions
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS rank
FROM products;
-- JSONB
SELECT data->'address'->>'city' FROM users WHERE data @> '{"active": true}';
-- Not yet on both: SQL CREATE POLICY is planned in Nano. Today RLS
-- policies are defined through the embedded API or the REPL and are
-- not enforced for wire or REST clients
// PostgreSQL requires:
// - Install PostgreSQL
// - Configure postgresql.conf
// - Create database
// - Manage connections
// - Handle upgrades
// HeliosDB Nano, embedded (a persistent data directory):
let db = EmbeddedDatabase::new("./myapp-data")?;
| Task | PostgreSQL | HeliosDB Nano |
|---|---|---|
| Installation | Package manager + config | cargo add heliosdb-nano |
| Backup | pg_dump + storage | heliosdb-nano dump / restore --verify (a copied live directory is not a backup) |
| Upgrades | Careful migration | Dump first; upgrade separately from any mode change |
| Monitoring | External tools | System views such as pg_stat_activity |
| Scaling | Replicas, pg_bouncer | Warm standby; pooling via the separate HeliosProxy |
-- PostgreSQL: Install and configure pgvector extension
CREATE EXTENSION vector;
-- HeliosDB Nano: vector type and HNSW in the default build
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(768) -- Native type
);
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- Product Quantization, also in the default build
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (quantization = 'product');
Product Quantization is in Nano's default build: add WITH (quantization='product') to an HNSW index. Indexes are unquantized unless you ask, and durable restart-surviving PQ-HNSW indexes need the vector-persist build (Product Quantization guide). Memory savings and recall for Product Quantization are measured on representative fixtures on the benchmarks page.
Copy-on-write branches of the whole database, created with SQL. A merge is last-writer-wins with no conflict detection, so for anything conflict-sensitive, discard the branch and re-apply the validated SQL (merging branches):
-- Create an isolated environment for testing
CREATE DATABASE BRANCH staging FROM main;
USE BRANCH staging;
-- Make changes, run tests
ALTER TABLE users ADD COLUMN preferences JSONB;
-- Merge (last-writer-wins, no conflict report)
MERGE DATABASE BRANCH staging INTO main;
-- Or discard
DROP DATABASE BRANCH staging;
-- Read past versions within the retention window (not a backup)
SELECT * FROM orders
AS OF TIMESTAMP '2026-01-25 09:00:00'
WHERE status = 'pending';
-- Compare versions
SELECT
current.balance,
historical.balance,
current.balance - historical.balance AS change
FROM accounts current
JOIN accounts AS OF TIMESTAMP '2026-01-01' historical
ON current.id = historical.id;
// One engine; the mode is chosen when you open or start it
// Development: embedded, persistent data directory
let db = EmbeddedDatabase::new("./dev-data")?;
// Tests: in-memory, discarded when the process exits
let db = EmbeddedDatabase::new_in_memory()?;
// Production: stop the embedded process, then serve the same directory
// $ heliosdb-nano start --data-dir ./dev-data --port 5432
// and connect with any PostgreSQL client (embedded calls become client calls)
Moving from embedded to server is a stop-then-start handoff with real code changes, not a configuration flip (embedded to server).
PostgreSQL might be better if you need:
NULLS FIRST/LAST, a setval() that does not move the sequence and rejected expression indexes. FAQ · Known limitationsSERIALIZABLE as snapshot isolation, which permits write skew. Isolation levelsUPDATE … SET n = n + 1 on one row can lose increments under READ COMMITTED without raising a serialization error. Known limitations: concurrencyCREATE POLICY and enforcement for REST and wire clients are planned, and SET ROLE is refused. Deployment modes · Security hardeningBEFORE INSERT row rewrites) are planned. PL/pgSQL compatibility · Known limitations: SQL behaviourMost PostgreSQL DDL loads unchanged, but compatibility is not total, so test rather than assume (migration guide):
-- This PostgreSQL schema loads in HeliosDB Nano
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
data JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
items JSONB NOT NULL,
total DECIMAL(10,2),
status TEXT DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_orders_user ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
-- Accepted as DDL; GIN is not consulted at runtime
CREATE INDEX idx_orders_data ON orders USING gin(items);
# Export schema and data from PostgreSQL
pg_dump -s -h postgres-server -U postgres mydb > schema.sql
pg_dump -a -h postgres-server -U postgres mydb > data.sql
# Remove the pg_catalog.set_config() calls pg_dump emits
# (Nano does not implement set_config yet), then load
heliosdb-nano init ./mydb
heliosdb-nano repl --data-dir ./mydb < schema.sql
heliosdb-nano repl --data-dir ./mydb < data.sql
# PostgreSQL
engine = create_engine("postgresql://user:pass@server:5432/db")
# HeliosDB Nano server: the same PostgreSQL dialect and driver
engine = create_engine("postgresql://user:pass@localhost:5432/db")
# There is no HeliosDB SQLAlchemy dialect; for in-process use,
# call the embedded binding (import heliosdb_nano) directly
| Requirement | PostgreSQL | HeliosDB Nano |
|---|---|---|
| Multi-tenancy | RLS + manual isolation | Enforce in the application; RLS is not applied to wire or REST clients |
| Development staging | Clone database (slow) | Copy-on-write branch (nearly instant) |
| Audit trail | Custom triggers | Built-in audit logging; time travel within retention |
| Encryption | pgcrypto extension | AES-256-GCM at rest, off until enabled with a key |
| Connection pooling | PgBouncer (separate) | HeliosProxy (separate, Apache 2.0) |
| Requirement | PostgreSQL | HeliosDB Nano |
|---|---|---|
| Vector storage | pgvector extension | Native |
| Vector compression | No Product Quantization in pgvector | Product Quantization (default build) |
| Hybrid search | Complex setup | Single query |
| Requirement | PostgreSQL | HeliosDB Nano |
|---|---|---|
| Deployment | Server installation | Embed in app |
| User setup | Required | None |
| Data portability | Export/import | Dump and restore |
| Offline support | No | Yes |
| Update process | Complex | Dump first, then upgrade the library |
We do not publish throughput figures for this pairing. The benchmarks page compares Nano with PostgreSQL 16 across 35 query categories, measured on representative fixtures: Nano runs embedded with no network hop, PostgreSQL runs over local TCP, the dataset is small and single-node, and PostgreSQL wins several categories. Its caveats also note that write-heavy OLTP benchmarks show PostgreSQL's maturity advantage. Reproduce the suite on your own workload and hardware before deciding.
# docker-compose.yml for PostgreSQL
services:
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
pgbouncer:
image: pgbouncer/pgbouncer
environment:
DATABASE_URL: postgresql://postgres:secret@postgres/db
ports:
- "6432:6432"
app:
image: myapp
environment:
DATABASE_URL: postgresql://pgbouncer:6432/db
depends_on:
- pgbouncer
volumes:
pgdata:
# docker-compose.yml for HeliosDB Nano (embedded in the app)
services:
app:
image: myapp
volumes:
- ./data:/data
# Database is embedded, no separate service needed
Or simply:
// No Docker, no separate service: the engine runs in your process
use heliosdb_nano::EmbeddedDatabase;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = EmbeddedDatabase::new("./data")?;
// Your application code
Ok(())
}
No. Nano implements the PostgreSQL wire protocol and a large subset of PostgreSQL SQL, so clients, drivers and ORMs connect, but wire compatibility is not semantic parity. Collation is byte-order only and row-level security is not enforced for wire clients. Test your queries rather than assume they behave identically. See the Nano FAQ.
No. In the stock Nano server, row-level security is enforced through the embedded API and the REPL; SQL CREATE POLICY and enforcement for clients over the PostgreSQL wire, the MySQL wire or REST are planned. SET ROLE is refused and no privilege decision is made from the role, so enforce per-user access in your application for server deployments. See security hardening.
Locale-aware collation, row-level security over the wire, ENUM and custom types, PostgreSQL extensions, LISTEN/NOTIFY, SQL CREATE POLICY, PL/pgSQL control flow, and trigger bodies beyond simple BEFORE INSERT row rewrites. Expression indexes are rejected and NULLS FIRST/LAST is ignored. The known limitations page lists workarounds.
No. Nano serves SERIALIZABLE as snapshot isolation, which does not prevent write skew. By default the transaction runs and the client receives a warning; setting storage.serializable_policy to "error" rejects SERIALIZABLE requests instead. See isolation levels.
No. The VECTOR(n) type, HNSW indexes and the <->, <=> and <#> distance operators are part of the engine in the default build, and so is Product Quantization: add WITH (quantization='product') to an HNSW index. Durable restart-surviving PQ-HNSW indexes need the vector-persist build. See the Nano page.
No. AES-256-GCM transparent encryption is compiled into the default build but disabled at runtime until you enable it in the configuration with a key source: an environment variable or a key file (cloud KMS key sources are planned). Key rotation is not implemented yet, and offline tools cannot open an encrypted data directory. See the Nano FAQ.
Export schema and data with pg_dump, load both through the Nano REPL into a new data directory, then compare row counts and run your application's tests. An unmodified pg_dump script stops at pg_catalog.set_config(), which Nano does not implement yet, so remove those calls first. See the migration guide.
Yes, in server mode. The server gives every PostgreSQL or MySQL connection its own session and transaction state. The embedded API is different: one process owns a data directory and explicit transactions share one slot per process, so independent callers should connect to the server. See concurrency and transactions.
Use heliosdb-nano dump and heliosdb-nano restore --verify, or the embedded dump_full and restore_from_dump calls. Copying a live data directory is not a backup, and time-travel queries do not replace backups because they only reach versions still retained in the same store. See backups.
It depends on the workload. The benchmarks page compares Nano with PostgreSQL 16 across 35 query categories, measured on representative fixtures with Nano embedded and PostgreSQL over local TCP on a small dataset, and PostgreSQL wins several categories. Reproduce the suite on your own workload before deciding. See the benchmarks.
Postgres's extension story is excellent. These capabilities are at the database-engine level, not extension territory — native in HeliosDB Nano (code-graph, graph-RAG, MCP and code-embed as build-from-source features), not buildable on Postgres without forking the engine.
CREATE AST INDEXSQL-callable LSP — lsp_definition, lsp_references, lsp_call_hierarchy, helios_lsp_rename_apply — with predicate pushdown through FilteredScan. Postgres has no AST table type and no extension delivers an integrated ON BRANCH + AS OF code-search surface.
WITH CONTEXT SQL clauseSeed rows from any SQL query (vector or keyword pre-filter) + BFS expansion over typed edges, expressed as a single SQL clause; applying RERANK BY in SQL is planned. _hdb_graph_nodes and _hdb_graph_edges are ordinary, queryable tables. No Postgres extension exposes graph-aware retrieval as a SQL clause.
Three transports (POST /mcp, WebSocket, SSE) with bearer-token auth, sixteen tools with the mcp-endpoint build (more with code-graph), streaming progress events; stdio MCP comes from the HeliosDB CodeKB MCP binary (MCP tutorial). Postgres needs a wrapper service to surface MCP; HeliosDB serves the protocol natively.
ON BRANCH + AS OF on every callBranch creation is O(1) copy-on-write at the storage layer. Every lsp_*, WITH CONTEXT, and ordinary SELECT accepts both refs in either order. Postgres branching tools (Neon, etc.) operate above the engine, not inside it.
Build with --features code-embed and Nano ships fastembed-rs + BGESmallENV15 (384-dim, ~30 MB cache). Embedding is a function call, not a network round-trip. Postgres has no embedded ML inference path.
REST, auth and realtime (known issue: realtime events are not delivered in the current release; tracked by the Nano team) + branching + time-travel + vector search with Product Quantization + BM25, in one binary of about 36-44 MB, depending on platform. Code-graph, graph-RAG, MCP and code-embed are build-from-source features that the prebuilt binaries and the container image do not include.
Get started with HeliosDB in minutes. Open source, free to use.