Deployment Modes
Deployment Modes
Applies to: HeliosDB Nano 4.31.1
This is the canonical page for how a HeliosDB Nano process is deployed. Two decisions are independent of each other, and mixing them up is the single most common source of confusion:
- Storage mode — where the data lives: persistent (a data directory on disk) or in-memory (RAM only).
- Access mode — how callers reach the engine: embedded library API, interactive REPL, foreground server, or background daemon.
Every combination of the two is valid. “Embedded” is an access mode, not a storage mode; “in-memory” is a storage mode, not an access mode.
Storage modes
Persistent
Data is written to a data directory and survives process restart. The local crash-recovery write-ahead log is always on.
heliosdb-nano repl --data-dir ./my-dataheliosdb-nano start --data-dir ./my-data --port 5432use heliosdb_nano::EmbeddedDatabase;
let db = EmbeddedDatabase::new("./my-data")?;heliosdb-nano start requires either --data-dir or --memory; repl
defaults to ./heliosdb-data.
In-memory
Data lives in RAM and is discarded when the process exits.
heliosdb-nano repl --memoryheliosdb-nano start --memory --port 5432let db = EmbeddedDatabase::new_in_memory()?;Add --dump-on-shutdown (CLI only) to write a dump on a graceful exit —
heliosdb-nano repl --memory --dump-on-shutdown --dump-file ./snapshot.heliodump.
An abrupt kill still loses everything: in-memory storage is not a durability
mechanism.
Use in-memory for tests, CI, and short-lived transforms. Use persistent storage for anything whose loss would matter.
Access modes
1. Embedded library API (in-process)
The engine runs inside your process, with no network listener and no separate server to manage — the SQLite-style deployment.
use heliosdb_nano::EmbeddedDatabase;
let db = EmbeddedDatabase::new("./my-data")?;db.execute("CREATE TABLE users (id BIGSERIAL PRIMARY KEY, name TEXT)")?;A Python binding for this same in-process engine is published as
heliosdb-nano-embedded (pip install heliosdb-nano-embedded, then
import heliosdb_nano), version-locked to the engine release.
- Best for: desktop and mobile apps, edge devices, CLI tools, single-process services, test harnesses.
- No network listener, no authentication layer, no per-connection sessions.
- Concurrent reads and single-statement autocommit writes are supported; independent overlapping explicit transactions are not — see Concurrency and transactions before you share one handle between threads.
2. Interactive REPL
A single-user interactive SQL shell over the same in-process engine.
heliosdb-nano repl --data-dir ./my-dataheliosdb-nano repl --memory- Best for: schema work, ad-hoc queries, inspecting a data directory, learning.
- REPL meta commands (
\d,\dt,\branches,\use,\stats) are available here and not over the wire protocols. - Single process, single user, no network access.
3. Foreground server
A PostgreSQL-wire server that stays attached to the terminal and logs to stdout.
heliosdb-nano start --data-dir ./my-data --port 5432 --listen 127.0.0.1Connect with any PostgreSQL client:
psql -h 127.0.0.1 -p 5432- Best for: development, protocol debugging, watching server output live.
- Multiple clients; each connection gets its own session and its own transaction state, which is the supported way to run independent transactions today.
- Optional listeners on the same process:
--mysql(MySQL wire),--pg-socket-dir <dir>(Unix-domain socket at<dir>/.s.PGSQL.<port>),--http-port(health/HTTP API).
4. Background daemon
The same server, detached, with a PID file for process management.
heliosdb-nano start --daemon \ --data-dir ./my-data \ --port 5432 \ --pid-file ./heliosdb.pid
heliosdb-nano status --pid-file ./heliosdb.pidheliosdb-nano stop --pid-file ./heliosdb.pid- Best for: long-running deployments, containers, service managers.
- Identical engine and connection semantics to the foreground server; the difference is process lifecycle, not capability.
Choosing
| Requirement | Access mode |
|---|---|
| Ship the database inside the application binary | Embedded library API |
| Explore or administer a data directory by hand | Interactive REPL |
| Several clients, or clients in another language/host | Foreground server or daemon |
| Independent overlapping explicit transactions | Server or daemon (separate connections) |
| Run under systemd / Docker / a supervisor | Background daemon |
| Throwaway state for a test run | Any access mode + in-memory storage |
| Requirement | Storage mode |
|---|---|
| Data must survive restart | Persistent |
| Reproducible, isolated test fixtures | In-memory |
| Fastest possible scratch workspace | In-memory (accepting total loss on exit) |
One process per data directory
A data directory is owned by exactly one running process. Starting a second
process against a directory another process already has open is not supported
and surfaces as lock errors (database is locked) — see
Troubleshooting.
This has three practical consequences:
- Modes are chosen at open/start time. There is no live switch between embedded and server access.
- Moving from embedded to server is a stop-then-start handoff. Stop the embedded process, start the server against the same data directory, then repoint the application at a PostgreSQL client. Keep the engine version identical across the switch — combine one change at a time.
- Two processes cannot share one dataset. If more than one process needs the same data, one of them must be the server and the rest must be clients.
Running a server and a REPL at the same time (“hybrid”)
Running a daemon and a REPL side by side is a genuinely useful development setup — but it is two independent processes with two separate data directories, not shared access to one dataset:
# Terminal 1 — server, its own data directoryheliosdb-nano start --daemon \ --data-dir ./server-data \ --port 5432 \ --pid-file ./heliosdb.pid
# Terminal 2 — REPL, a DIFFERENT data directoryheliosdb-nano repl --data-dir ./scratch-dataWrites made in the REPL are not visible to clients of the server, and vice
versa. The two processes share nothing. To inspect the server’s data
interactively, connect to the server with psql instead of opening a second
process against its directory.
Authentication and network exposure
--authacceptstrust,password,md5,scram-sha-256; the default istrust.- Any method other than
trustrequires--password. trustis refused on a non-loopback listener — binding to anything other than127.0.0.1/::1requires a real authentication method.- TLS:
--tls-certand--tls-keymust be supplied together. --max-connections(default 100) caps concurrent client connections.
heliosdb-nano start --daemon \ --data-dir /var/lib/heliosdb \ --listen 0.0.0.0 --port 5432 \ --auth scram-sha-256 --password "$HELIOSDB_PASSWORD" \ --tls-cert /etc/heliosdb/cert.pem --tls-key /etc/heliosdb/key.pem \ --pid-file /run/heliosdb.pidConfiguration file
Server-mode settings can come from a TOML file instead of flags:
heliosdb-nano start --config heliosdb.toml[storage]path = "/var/lib/heliosdb"memory_only = falsecache_size = 536870912 # bytescompression = "zstd"wal_enabled = true
[server]listen_addr = "127.0.0.1"port = 5432max_connections = 100tls_enabled = false# tls_cert_path = "/etc/heliosdb/cert.pem"# tls_key_path = "/etc/heliosdb/key.pem"
[performance]worker_threads = 8simd_enabled = trueparallel_query = truequery_timeout_secs = 300
[encryption]enabled = falsealgorithm = "Aes256Gcm"key_source = { Environment = "HELIOSDB_ENCRYPTION_KEY" }Encryption is compiled in by default but disabled at runtime by default and
requires a key source; setting algorithm alone does not encrypt anything.
See Configuration for the full key reference.
Feature differences between access modes
| Capability | Embedded / REPL | Server / daemon |
|---|---|---|
| SQL, vector search, branching, time travel | Yes | Yes |
REPL meta commands (\d, \branches, …) | REPL only | No |
| Network clients (psql, JDBC, drivers) | No | Yes |
| Per-connection sessions and transactions | No — one process-global transaction slot | Yes, per connection |
| Row-level security / multi-tenancy | Yes | Not reachable over PG wire, MySQL wire or REST in any release to date |
| Authentication | Not applicable (in-process) | trust / password / md5 / scram-sha-256 |
Backups
Do not treat a copy of a live data directory as a backup. Use the dump/restore path, which is the supported mechanism:
heliosdb-nano dump --data-dir ./my-data --output backup.heliodumpheliosdb-nano restore --input backup.heliodump --target ./restored --verifyThe same operations are available on the embedded API as dump_full and
restore_from_dump.
Related
- Concurrency and transactions — what is and is not safe to do from multiple callers
- Deployment Modes overview — the short version, for first-time readers
- Production Deployment
- Migration Guide — including the embedded → server transition