Choose HeliosDB Nano when you want a self-hosted backend in one binary, with PostgREST-style REST, built-in auth, a realtime WebSocket, native vector search, a MySQL listener, branching and time travel; keep Supabase when you need edge functions or S3-backed file storage (both on the HeliosDB roadmap), a dashboard, a PostgREST table API or realtime event delivery today, or tenancy enforced by row-level security on API requests, which Nano does not do over REST today.

Supabase is a popular open-source Backend-as-a-Service built on PostgreSQL. HeliosDB Nano covers the database, REST API, auth and vector search parts of that stack, plus a realtime WebSocket (known issue: realtime events are not delivered in the current release; tracked by the Nano team), in one self-hosted binary of about 36-44 MB, depending on platform, with no cloud dependency.


Quick Comparison

Feature Supabase HeliosDB Nano
HostingCloud (or self-hosted)Self-hosted (single binary)
DatabasePostgreSQLPostgreSQL wire + a documented SQL subset; optional MySQL wire
AuthGoTrue (email, OAuth, magic links)Built-in (email, OAuth, JWT)
REST APIPostgREST (auto-generated)PostgREST-style filters (eq, neq, gt, gte, lt, lte, like, ilike, is, in, not.); table routes a known issue in the current release
RealtimeWebSocket (postgres_changes)WebSocket in the Supabase message shape (Known issue: realtime events are not delivered in the current release; tracked by the Nano team)
StorageS3-backed bucket APIPlanned (buckets and signed URLs); database data persists in a data directory
Vector Searchpgvector extensionNative HNSW + Product Quantization (no extension)
BranchingBranching add-on ($$$)Built-in copy-on-write (merge is last-writer-wins)
Time TravelN/ABuilt-in (AS OF TIMESTAMP, within retention)
EncryptionOptionalAES-256-GCM, off until enabled with a key
MySQL ProtocolN/AOpt-in MySQL wire listener (trust-only)
WordPressN/ADocumented on the MySQL listener
Binary SizeN/A (cloud service)One binary of about 36-44 MB, by platform
PricingFree tier + usage-basedFree to self-host (Apache 2.0); Nano Cloud from $0/mo

Same Client API, No Cloud Required

HeliosDB Nano's @heliosdb/client package offers the same fluent API as supabase-js, over REST and WebSocket. It is not published on npm: build it from the HeliosDB SDKs source (see the TypeScript SDK page), then point it at your own server. Re-test each query, because Nano's SQL is a documented subset of PostgreSQL's rather than a semantic match.

Known issue in the current release: the client's table queries go through the /rest/v1 table routes, which return 404, so .from(...) calls fail until a fixed release; until then, query the same tables with the pg driver over the PostgreSQL wire protocol. Nano's REST filters support eq, neq, gt, gte, lt, lte, like, ilike, is and in, with not. negation; cs, cd, ov, full-text and or/and filters are planned.

// Supabase
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://xyz.supabase.co', 'your-anon-key')

// HeliosDB Nano -- same fluent API, self-hosted (built from source, not npm)
import { createClient } from '@heliosdb/client'
const db = createClient('http://localhost:8080', 'your-anon-key')

Query Data

// The same fluent query shape on both platforms
const { data, error } = await db
  .from('users')
  .select('id, name, email')
  .eq('active', true)
  .order('created_at', { ascending: false })
  .limit(10)

Insert with Returning

const { data, error } = await db
  .from('posts')
  .insert({
    title: 'Hello World',
    body: 'My first post',
    author_id: user.id
  })
  .select()

Realtime Subscriptions

// Subscribe to changes -- same API. Known issue: realtime events are not
// delivered in the current release; tracked by the Nano team
const channel = db
  .channel('messages')
  .on('postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'messages' },
    (payload) => {
      console.log('New message:', payload.new)
    }
  )
  .subscribe()

Auth

// Sign up -- same flow
const { data, error } = await db.auth.signUp({
  email: 'user@example.com',
  password: 'securepassword'
})

// Sign in with OAuth
const { data, error } = await db.auth.signInWithOAuth({
  provider: 'github'
})

Row-level security does not protect these requests. In the stock Nano server, row-level security is enforced through the embedded API and the REPL; SQL CREATE POLICY and enforcement for REST, realtime WebSocket and wire clients are planned, so a Nano backend must enforce per-user access in your service layer. See access-mode differences and security hardening.


What HeliosDB Adds Beyond Supabase

1. Database Branching (Built-in)

HeliosDB Nano includes copy-on-write branching at the storage layer. A merge is last-writer-wins with no conflict detection, so for anything conflict-sensitive, test on a branch, discard it and re-apply the validated SQL to main (merging branches):

-- Create an isolated copy-on-write branch for testing
CREATE DATABASE BRANCH staging FROM main;
USE BRANCH staging;

-- Run migrations, test schema changes
ALTER TABLE users ADD COLUMN preferences JSONB DEFAULT '{}';

-- Discard the branch, then re-apply the validated SQL to main.
-- (MERGE DATABASE BRANCH staging INTO main is last-writer-wins
--  and reports no conflicts.)
USE BRANCH main;
DROP DATABASE BRANCH staging;

2. Time-Travel Queries

Query earlier states of your data without restoring a backup, as far back as versions are retained (storage.version_retention; by default Nano keeps all history). Time travel lives in the same store, so it is not a substitute for backups (how far back you can query):

-- Read the table as it was at an earlier time (within retention)
SELECT * FROM orders
AS OF TIMESTAMP '2026-04-14 09:00:00'
WHERE status = 'pending';

-- Compare current vs historical
SELECT
    c.balance AS current_balance,
    h.balance AS yesterday_balance,
    c.balance - h.balance AS change
FROM accounts c
JOIN accounts AS OF TIMESTAMP '2026-04-14' h
    ON c.id = h.id;

3. Native Vector Search (No Extension)

Supabase relies on the pgvector extension. HeliosDB Nano has HNSW indexing in the engine's default build, and Product Quantization is in the default build too: 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; memory savings and recall are measured on representative fixtures on the benchmarks page:

-- Native vector type, no CREATE EXTENSION needed
CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content TEXT,
    embedding VECTOR(768)
);

-- HNSW index; add WITH (quantization = 'product') for Product Quantization
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

-- Semantic search
SELECT content, embedding <=> $1::vector(768) AS distance
FROM documents
ORDER BY distance
LIMIT 10;

4. MySQL Wire Protocol

Supabase is PostgreSQL-only. HeliosDB Nano can also open a MySQL wire listener on the same data (--mysql, off by default), and the MySQL wire tutorial shows WordPress and Laravel connecting unmodified. The MySQL listener is trust-only: it does not verify the user name, so keep it on loopback or a trusted network (known limitations).

# One server, both listeners (MySQL is opt-in, loopback by default)
heliosdb-nano start --data-dir ./data --mysql

# Connect via PostgreSQL
psql -h 127.0.0.1 -p 5432 -U postgres

# Connect via MySQL -- same data
mysql -h 127.0.0.1 -P 3306 -u admin

5. AES-256-GCM Encryption at Rest

Nano includes AES-256-GCM encryption at rest, but it is off until an operator enables it and supplies a key from an environment variable or a key file (cloud KMS key sources are planned). Once on, it is transparent to queries. Key rotation is not implemented yet, offline tools cannot open an encrypted data directory, and losing the key makes the data irrecoverable (FAQ · encryption quick start):

# A 256-bit key as 64 hex characters, readable only by the server's user
openssl rand -hex 32 > /secure/path/encryption.key
chmod 400 /secure/path/encryption.key

# heliosdb.toml -- encryption stays off unless enabled here
#   [encryption]
#   enabled = true
#   key_source = { File = "/secure/path/encryption.key" }

heliosdb-nano start --config heliosdb.toml --data-dir ./data

Self-Hosted Supabase: Many Containers vs 1 Binary

Self-hosting Supabase requires orchestrating multiple services:

Component Supabase Self-Hosted HeliosDB Nano
DatabasePostgreSQL containerOne Nano binary (about 36-44 MB, by platform)
REST APIPostgREST container
AuthGoTrue container
RealtimeRealtime container
StorageStorage API + S3Planned
Edge FunctionsDeno containerPlanned
DashboardStudio containerNot in the Nano docs
# Supabase self-hosted: docker-compose.yml (simplified)
services:
  postgres:
    image: supabase/postgres:15
  gotrue:
    image: supabase/gotrue
  postgrest:
    image: postgrest/postgrest
  realtime:
    image: supabase/realtime
  storage:
    image: supabase/storage-api
  studio:
    image: supabase/studio
  # ... plus kong, meta, imgproxy, etc.
# HeliosDB Nano: one process, persistent data directory
# (PostgreSQL wire on 5432 and the HTTP API on 8080 by default)
heliosdb-nano start --data-dir ./data

# Beyond loopback, trust auth is refused: add a real method, and keep
# the HTTP API on loopback (--http-listen; it defaults to --listen)
#   --listen 0.0.0.0 --http-listen 127.0.0.1 \
#   --auth scram-sha-256 --password "$HELIOSDB_PASSWORD"

The server needs either --data-dir or --memory; in-memory data is discarded on exit. See the CLI reference and network exposure.


When to Choose Supabase

Supabase might be a better fit if you need:

  • A fully managed stack -- Supabase hosts the database together with storage, edge functions and the dashboard; managed Nano Cloud covers Nano databases (see pricing)
  • Edge Functions -- serverless Deno runtime at the edge
  • Dashboard UI -- built-in table editor and SQL console
  • S3 file storage -- production-grade object storage with CDN
  • Ecosystem -- Supabase CLI, migration tools, community templates

When HeliosDB is not the right fit

  • You rely on row-level security to protect data from API clients. 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 Nano makes no privilege decision from database roles. Server deployments must enforce per-user access in the application. Deployment modes · Security hardening
  • Your schema relies on triggers, PL/pgSQL control flow, ENUM types or extensions. 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, and ENUM types, custom types and extensions need built-in equivalents. Known limitations · PL/pgSQL compatibility · Migrating from PostgreSQL
  • Your app listens for database notifications. LISTEN, NOTIFY and pg_notify are not implemented, so clients must poll; realtime events for SQL writes are planned. Known limitations
  • Realtime subscribers need per-table authorization. The realtime tutorial lists per-table authorization through JWT claims as roadmap, so keep the realtime endpoint on a trusted network or behind your own gateway. Realtime WebSocket tutorial
  • You need the PostgREST table API today. Nano's REST filters support eq, neq, gt, gte, lt, lte, like, ilike, is and in, with not. negation; cs, cd, ov, full-text and or/and filters are planned, and the /rest/v1 table routes are a known issue in the current release. Use the PostgreSQL wire protocol until a fixed release. REST API reference
  • You want to install the JS client from npm. @heliosdb/client is not published on npm; you build it from the HeliosDB SDKs source, or use the pg driver over the PostgreSQL wire protocol. TypeScript SDK
  • You run prebuilt binaries on older Linux hosts. Prebuilt Nano Linux binaries need glibc 2.39 or newer; on an older host, run the official container image ghcr.io/heliosdatabase/heliosdb-nano (the default-feature build) instead. Distribution notes · Docker install

When to Choose HeliosDB Nano

  • Self-hosted / air-gapped -- single binary, no internet required
  • Edge / IoT deployment -- one self-contained binary of about 36-44 MB, depending on platform, embedded or as a server
  • MySQL applications -- WordPress and Laravel on the opt-in MySQL listener
  • Database branching -- built-in copy-on-write branches for rehearsing migrations
  • Time-travel queries -- audit, compliance, debugging
  • Vector search without extensions -- native HNSW, with Product Quantization in the default build
  • No license fees -- Apache 2.0, free to self-host
  • Data sovereignty -- your data never leaves your server

Migration from Supabase

1. Export and Adjust Your Schema

An unmodified pg_dump-format script does not restore on Nano today: it calls pg_catalog.set_config(), which Nano does not implement. ENUM and custom types, extensions, trigger bodies and PL/pgSQL control flow also need rewriting. Adjust the dump, load it into a new data directory and verify row counts (migration guide · known limitations).

# Export from Supabase
supabase db dump --schema public > schema.sql

# Edit schema.sql: remove set_config() calls, replace ENUMs with
# TEXT + CHECK, drop extensions and trigger/DO-block logic

# Load into a new HeliosDB Nano data directory, then verify
heliosdb-nano init ./mydb
heliosdb-nano repl --data-dir ./mydb < schema.sql

2. Update Your Client

// Before: Supabase cloud
import { createClient } from '@supabase/supabase-js'
const db = createClient('https://xyz.supabase.co', 'your-anon-key')

// After: HeliosDB Nano (same fluent API; @heliosdb/client is built from source)
import { createClient } from '@heliosdb/client'
const db = createClient('http://localhost:8080', 'your-anon-key')

// Re-test each query: filters follow PostgREST conventions.
// Known issue in the current release: the /rest/v1 table routes return 404, so until
// a fixed release, query these tables with the pg driver instead
const { data } = await db.from('users').select('*').eq('active', true)

3. Move Access Rules Into Your Service Layer

Supabase row-level security policies do not carry over as a security boundary. 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, so requests over REST or the PostgreSQL and MySQL wire protocols are not filtered by it. Supabase's auth.uid() is not a documented Nano function; the documented helpers are current_user_id(), current_tenant_id() and current_tenant_name() (RLS system functions). For a server deployment, enforce per-user access in your application.

-- SQL CREATE POLICY is planned in Nano. Today a policy is defined in the
-- REPL (or through the embedded API) and applies to embedded-API and REPL
-- callers, not to REST, PostgreSQL-wire or MySQL-wire clients
\tenant rls create posts own_posts author_id=current_user_id() ALL

Straight Answers

Can HeliosDB Nano replace a self-hosted Supabase stack?

Partly. One Nano binary serves the database, PostgREST-style REST (its /rest/v1 table routes are a known issue in the current release), email sign-up with JWT sessions, Google and GitHub OAuth with PKCE, and a realtime WebSocket (known issue: realtime events are not delivered in the current release; tracked by the Nano team). File storage and edge functions are on the HeliosDB roadmap and there is no dashboard, so plan to keep those elsewhere. See the REST, auth and realtime tutorials.

Does HeliosDB Nano keep data in memory?

No, not by default. Nano stores data in a persistent data directory that survives restarts, protected by an always-on crash-recovery write-ahead log. In-memory storage is an explicit opt-in (--memory or EmbeddedDatabase::new_in_memory()) for tests and CI, and its data is discarded when the process exits. See storage modes.

Is data encrypted at rest automatically?

No. AES-256-GCM encryption at rest is compiled into Nano but stays off until an operator enables it and supplies a key from an environment variable or a key file; cloud KMS key sources are planned. Key rotation is not implemented yet, and losing the key makes the data irrecoverable. See the encryption quick start.

Do my Supabase row-level security policies carry over?

Not as a security boundary. 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. Supabase's auth.uid() is not among Nano's documented RLS functions, so enforce per-user access in your service layer. See access-mode differences.

Will my supabase-js code work against HeliosDB Nano?

Partly. Nano's REST API follows PostgREST conventions with the eq, neq, gt, gte, lt, lte, like, ilike, is and in filters and not. negation, but its /rest/v1 table routes are a known issue in the current release, and its realtime WebSocket accepts subscriptions in the Supabase message shape (known issue: realtime events are not delivered in the current release; tracked by the Nano team). The @heliosdb/client package offers the same fluent API but is not published on npm; build it from the HeliosDB SDKs repository, or use the pg driver over the PostgreSQL wire protocol. See the TypeScript SDK.

Is HeliosDB Nano as PostgreSQL-compatible as Supabase's Postgres?

No. Nano implements the PostgreSQL wire protocol and a large subset of PostgreSQL SQL, which is client compatibility rather than semantic parity. Today LISTEN/NOTIFY are not implemented, PL/pgSQL control flow and most trigger bodies are planned, and collation is byte-order only. See the known limitations.

How do branching and time travel work in HeliosDB Nano?

CREATE DATABASE BRANCH makes a copy-on-write branch of the whole database, and AS OF TIMESTAMP reads data as it was, as far back as versions are retained (by default Nano keeps all history). MERGE DATABASE BRANCH is last-writer-wins with no conflict detection, so discard branches and re-apply validated SQL instead. Time travel is not a backup. See merging branches.

What does it cost to run HeliosDB Nano instead of Supabase?

Self-hosting Nano costs nothing beyond your infrastructure, because it is licensed Apache 2.0. Managed Nano Cloud has a Free plan at $0/mo, Starter at $9/mo, Pro at $49/mo and an Enterprise plan, with add-ons for extra storage, requests, databases and a dedicated IP. See pricing.

Can WordPress or other MySQL applications share the same HeliosDB Nano server?

Yes. Started with --mysql, one Nano server accepts MySQL and PostgreSQL clients on the same data, and the MySQL tutorial shows WordPress, Laravel Eloquent, mysql2, PyMySQL and mysql-connector-j connecting unmodified. The MySQL listener is trust-only and does not verify the user name, so keep it on loopback or a trusted network. See the MySQL wire tutorial.

Now also: code-graph + graph-RAG + native MCP

HeliosDB Nano, built from source with these features, adds CREATE EXTENSION hdb_code for SQL-callable LSP, the WITH CONTEXT clause for grounded RAG, eight ingestion adapters (incl. Docling-backed PDF / Office / audio / image), an in-process embedder, and a native MCP server reachable from Claude Code, Cursor, Continue, Codex, and Aider. Equivalents for HeliosDB Lite and Full are planned. Learn more →

Ready to try HeliosDB?

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

Get Started Contact Sales