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.


Quick Comparison

Feature PostgreSQL HeliosDB Nano
DeploymentServer processEmbedded library or server
Configurationpostgresql.conf and tuningCommand-line flags or a TOML file
OperationsServer administrationEmbedded: no server to run; server mode: auth, TLS and dump-based backups
SQL CompatibilityNativeLarge documented subset, not semantic parity
Wire ProtocolNativeCompatible
Vector Searchpgvector extensionBuilt-in HNSW (default build)
Encryptionpgcrypto extensionAES-256-GCM at rest, off until enabled with a key
Database BranchingNoYes
Time-TravelNoYes, within retention
Row-Level SecurityYes, for every clientEmbedded API and REPL only; SQL CREATE POLICY and wire/REST enforcement planned
JSONBYesYes
Window FunctionsYesYes

What You Keep

Client compatibility and a large SQL subset — not full semantic parity (FAQ):

  • SQL dialect -- Most DDL and queries run unchanged; test rather than assume
  • Wire protocol -- psql, pgAdmin, DBeaver and most PostgreSQL drivers and ORMs
  • JSONB -- JSON operators such as ->, ->> and @>
  • Window functions -- OVER, PARTITION BY, etc.
  • CTEs -- WITH queries
-- 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

What You Gain

1. Embedded Deployment

// 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")?;

2. Operations Compared

Task PostgreSQL HeliosDB Nano
InstallationPackage manager + configcargo add heliosdb-nano
Backuppg_dump + storageheliosdb-nano dump / restore --verify (a copied live directory is not a backup)
UpgradesCareful migrationDump first; upgrade separately from any mode change
MonitoringExternal toolsSystem views such as pg_stat_activity
ScalingReplicas, pg_bouncerWarm standby; pooling via the separate HeliosProxy

3. Built-in Vector Search

-- 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.

4. Database Branching

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;

5. Time-Travel Queries

-- 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;

6. Embedded, In-Memory or Server

// 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).


When to Choose PostgreSQL

PostgreSQL might be better if you need:

  • Stored procedures (PL/pgSQL, PL/Python)
  • Foreign data wrappers (query external databases)
  • Table inheritance (native support)
  • Language-aware full-text search (stemming, phrase queries, GIN indexes used at runtime)
  • Row-level security for network clients (Nano enforces RLS only for embedded and REPL callers)
  • Proven large-scale operation (HeliosDB's published benchmarks are single-node, on a small dataset)
  • Existing PostgreSQL ecosystem (extensions, tools)

When HeliosDB is not the right fit

  • You need PostgreSQL semantics, not just its protocol. Wire compatibility is not semantic parity: collation is byte-order (C) only, and open issues include ignored NULLS FIRST/LAST, a setval() that does not move the sequence and rejected expression indexes. FAQ · Known limitations
  • Your correctness depends on true SERIALIZABLE isolation. Nano serves SERIALIZABLE as snapshot isolation, which permits write skew. Isolation levels
  • You run concurrent read-modify-write updates on hot rows. Concurrent UPDATE … SET n = n + 1 on one row can lose increments under READ COMMITTED without raising a serialization error. Known limitations: concurrency
  • Network clients rely on row-level security or role privileges. In the stock Nano server, row-level security is enforced through the embedded API and the REPL; SQL CREATE POLICY and enforcement for REST and wire clients are planned, and SET ROLE is refused. Deployment modes · Security hardening
  • You keep business logic in stored procedures or triggers. Nano runs plain-SQL DO blocks and simple SQL/plpgsql functions; PL/pgSQL control flow and trigger bodies (beyond simple BEFORE INSERT row rewrites) are planned. PL/pgSQL compatibility · Known limitations: SQL behaviour
  • You depend on extensions, custom types or language-aware full-text search. Extensions and custom types need built-in equivalents; full-text search has no stemming or phrase queries yet (both are planned), and GIN indexes are accepted but not used at runtime. Migrating from PostgreSQL · Full-text search compatibility

Migration Path

Schema Migration

Most 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);

Data Migration

# 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

Connection String Change

# 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

Feature Comparison: Real-World Scenarios

Scenario 1: SaaS Application

Requirement PostgreSQL HeliosDB Nano
Multi-tenancyRLS + manual isolationEnforce in the application; RLS is not applied to wire or REST clients
Development stagingClone database (slow)Copy-on-write branch (nearly instant)
Audit trailCustom triggersBuilt-in audit logging; time travel within retention
Encryptionpgcrypto extensionAES-256-GCM at rest, off until enabled with a key
Connection poolingPgBouncer (separate)HeliosProxy (separate, Apache 2.0)

Scenario 2: AI Application

Requirement PostgreSQL HeliosDB Nano
Vector storagepgvector extensionNative
Vector compressionNo Product Quantization in pgvectorProduct Quantization (default build)
Hybrid searchComplex setupSingle query

Scenario 3: Desktop Application

Requirement PostgreSQL HeliosDB Nano
DeploymentServer installationEmbed in app
User setupRequiredNone
Data portabilityExport/importDump and restore
Offline supportNoYes
Update processComplexDump first, then upgrade the library

Performance Comparison

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.


Deployment Comparison

PostgreSQL Deployment

# 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:

HeliosDB Nano Deployment

# 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(())
}

Straight Answers

Is HeliosDB Nano a drop-in replacement for PostgreSQL?

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.

Does row-level security work the same as in PostgreSQL?

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.

Which PostgreSQL features do not carry over to HeliosDB Nano?

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.

Is SERIALIZABLE isolation the same as in PostgreSQL?

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.

Do I need pgvector for vector search in HeliosDB Nano?

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.

Is data encrypted at rest by default?

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.

How do I move a PostgreSQL database to HeliosDB Nano?

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.

Can several applications share one HeliosDB Nano database like a PostgreSQL server?

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.

How do I back up a HeliosDB Nano database?

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.

Is HeliosDB Nano faster than PostgreSQL?

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.

Where Postgres Can't Follow

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.

Code-Graph

CREATE AST INDEX

SQL-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.

Graph-RAG

WITH CONTEXT SQL clause

Seed 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.

Native MCP

Coding agents speak the engine

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.

Branch + Time-Travel

ON BRANCH + AS OF on every call

Branch 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.

In-process embedder

No external embedding service

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.

One binary

One binary, default features

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.

Code-Graph & Graph-RAG → Release notes

Ready to try HeliosDB?

Get started with HeliosDB in minutes. Open source, free to use.

Get Started Contact Sales