---
title: "Known Limitations"
---

# Known Limitations


This page lists behaviour that differs from PostgreSQL (or from what the rest of
these docs might lead you to expect) in the current release, plus what the
latest release fixed. Every open item links to its public issue on
[HeliosDatabase/HeliosDB-Nano](https://github.com/HeliosDatabase/HeliosDB-Nano/issues),
which is where status updates land first.

---

## Recently fixed

If you worked around any of these on an earlier release, the workaround is no
longer needed on the current release:

- **Read-your-own-writes in `UPDATE` / `DELETE`.** Inside `BEGIN … COMMIT`, an
  `UPDATE` or `DELETE` now sees rows `INSERT`ed earlier in the same transaction
  (the create-then-patch pattern ORMs emit). Previously it reported 0 rows
  affected and the change was lost.
  ([#41](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/41)) Transactions
  on a **database branch** still do not see their own branch writes from
  `UPDATE`/`DELETE`.
- **`CALL` inside a transaction.** A procedure body invoked with `CALL` inside
  `BEGIN` now runs in that transaction and is undone by `ROLLBACK`; previously
  its writes committed immediately.
- **Savepoints.** A savepoint belongs to the transaction that created it, is
  cleared at `COMMIT`/`ROLLBACK`, and `SAVEPOINT` / `RELEASE` /
  `ROLLBACK TO SAVEPOINT` work over the extended query protocol. Naming a
  savepoint not established in the current transaction raises `3B001`.
- **`CREATE TEMPORARY TABLE`.** Temporary tables are now private to the session
  that creates them and are dropped when it ends. Previously they were
  created as permanent, globally visible tables.
- **Session-less statements and the embedded transaction.** A wire, REST or MCP
  statement executed without a session can no longer run inside, commit, or roll
  back a transaction opened by the embedding application; it is refused with
  `No active transaction to commit`. `POST /v1/branches/:name/execute` refuses
  transaction-control statements.
- **Multiple databases in one process.** Advisory locks
  (`pg_advisory_lock`), `pg_stat_activity`, MCP SSE sessions and
  `join_memory_limit_mb` are scoped per open database. Within one database,
  `pg_stat_activity` masks `client_addr`, `client_port`, `state`,
  `backend_start` and `state_change` for backends owned by another login role,
  as PostgreSQL does.

---

## Open issues

### Concurrency

- **Concurrent `UPDATE … SET n = n + 1` on one row can lose increments.** Under
  the default `READ COMMITTED`, concurrent autocommit read-modify-write updates of
  the same row can each report success while some increments are lost, and no
  `40001` is raised.
  ([#50](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/50))
  Until fixed, serialise such updates in the application (for example with
  `pg_advisory_lock` around the update, or a single writer) rather than relying
  on the database to merge them.
- See [Concurrency and Transactions](https://www.heliosdb.com/docs/nano/guides/concurrency-and-transactions/)
  for the embedded-mode transaction model (one transaction slot per process) and
  the isolation levels actually served.

### SQL behaviour

- **`NULLS FIRST` / `NULLS LAST` are accepted but ignored.**
  ([#43](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/43))
  Workaround: `ORDER BY CASE WHEN col IS NULL THEN 1 ELSE 0 END, col`.
- **`ORDER BY` after `GROUP BY` cannot reference a select-list alias mixed with a
  grouped column, or repeat an aggregate**; the error names internal placeholders
  such as `agg_0` / `group_N`.
  ([#44](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/44))
  Workaround: order by select-list position (`ORDER BY 3 DESC, 2 ASC`).
- **`setval()` returns its argument but does not move the sequence.**
  ([#51](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/51))
- **A boolean function whose argument is a bound parameter is returned as text**
  (`'t'`/`'f'`), e.g. `pg_try_advisory_lock($1)`.
  ([#52](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/52))
- **`CREATE INDEX` on an expression is rejected.**
  ([#34](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/34))
- **`::vector` cast on a bound parameter fails**; only inline literals work.
  ([#33](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/33))
- **`LISTEN` / `NOTIFY` / `pg_notify` are not implemented**; clients must poll.
  ([#40](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/40))
- **Trigger bodies do not execute**, apart from `BEFORE INSERT … FOR EACH ROW`
  functions that only assign `NEW.<col>` or `RETURN NULL`. Do not rely on
  triggers for audit rows or derived data; use a second statement in the same
  transaction or a procedure invoked with `CALL`.
- **SQLite-style `TEXT DEFAULT CURRENT_TIMESTAMP`** stores a quoted ISO value
  that differs from SQLite.
  ([#39](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/39))

### Driver and ORM compatibility

- **psycopg 3 defaults:** a `datetime.date` bound with `%s` (binary format) is
  rejected — use `%t`; `DEALLOCATE ALL` is not implemented.
  ([#54](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/54))
- **`SELECT * FROM current_schema()`** fails with `42P01`, which blocks TypeORM
  initialisation. ([#46](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/46))
- **`pg_catalog.set_config()` is missing**, so an unmodified `pg_dump` script
  does not restore. ([#47](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/47))

### Databases, roles and security

- **No switch to require TLS.** With `--tls-cert`/`--tls-key` the PostgreSQL
  listener *offers* TLS, but a client that does not request it is still served
  in plaintext. ([#53](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/53))
  To enforce encryption, bind to loopback or a private network and terminate TLS
  in front of Nano, or require `sslmode=require`/`verify-full` on every client.
- **A role created with `CREATE ROLE … LOGIN` cannot authenticate with SCRAM**;
  the bootstrap `postgres` user can.
  ([#49](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/49))
- **Credentials can only be given on the command line**, so `--password` is
  visible in the process list.
  ([#38](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/38))
- **A `CREATE DATABASE` registration is lost after restart**; the rows remain
  reachable through the default database.
  ([#48](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/48))
- **Offline tools cannot open a data directory encrypted at rest** (no key
  source on that path). ([#45](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/45))
- **Encryption key rotation is not implemented.** AES-256-GCM runs under a single
  static key with random nonces; very high-volume deployments should track write
  volume against the 2^32-invocations-per-key bound.
- **The MySQL listener is trust-only**: the user name is asserted by the client,
  not verified. Do not expose `--mysql` beyond trusted networks.

### Realtime

- **Known issue: realtime events are not delivered in the current release;
  tracked by the Nano team.** Subscriptions to `/realtime/v1/websocket` are
  accepted, but change events do not arrive. Poll with SQL in the meantime.

### Replication, CDC and backup

- **`ALTER TABLE … RENAME` has no logical-log entry**, so replay and CDC
  consumers can diverge after a rename.
  ([#36](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/36))
- **A standby can transiently observe a partially-applied transaction**; see
  [Concurrency and Transactions](https://www.heliosdb.com/docs/nano/guides/concurrency-and-transactions/#durability-and-replication).
- **`restore` reports `Tables: 0, Rows: 0`** although the data is restored.
  ([#42](https://github.com/HeliosDatabase/HeliosDB-Nano/issues/42))

---

## Planned

These capabilities are described elsewhere in the docs or in older material but
are not part of the current release. Each is planned.

- **Row-level security outside the embedded API.** 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. The REST
  API does not apply RLS policies, so enforce per-user access in your service
  layer. Realtime (WebSocket) subscriptions are not filtered by row-level
  security; secured realtime is planned.
- **Row-level security for set operations and WITH queries.** RLS policies
  filter table scans, joins, aggregates, sorts and limits; filtering of set
  operations (`UNION`/`INTERSECT`/`EXCEPT`), `WITH` queries and table functions
  is planned.
- **PL/pgSQL control flow and trigger bodies.** Nano runs plain-SQL `DO` blocks
  and simple SQL/PL/pgSQL functions (SQL statements, `SELECT INTO`, `RETURN`);
  PL/pgSQL control flow (`IF`, `LOOP`, `WHILE`, `FOR`, `RAISE`, `:=`, dynamic
  `EXECUTE`) and trigger bodies are planned. See
  [PL/pgSQL](https://www.heliosdb.com/docs/nano/reference/compatibility/plpgsql/) for the exact scope.
- **REST filter operators.** 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 for table access in the meantime.
- **Full-text search stemming.** `tsvector`, `tsquery`, `@@`,
  `to_tsvector`/`to_tsquery` and `ts_rank`/`ts_rank_cd` work, but the text
  search configuration argument is ignored: language stemming, boolean
  `tsquery` operators and phrase/proximity search are planned. Matching today is
  any-term over lowercase tokens. See [Full-text search](https://www.heliosdb.com/docs/nano/reference/compatibility/fts/).
- **Geospatial.** Geospatial functions and indexes (`ST_DWithin`,
  `ST_Distance`, geometry types) are planned; they are not in the current release.
- **File storage and edge functions.** File storage (buckets and signed URLs)
  and edge functions are on the HeliosDB roadmap; today Nano serves REST, auth
  and realtime, and stores data in its data directory.
- **API key authentication for the HTTP API.** Keep the HTTP and MySQL
  listeners on loopback (the default): API-key authentication for the HTTP API
  is planned, and a smaller listening surface is good practice anyway.
- **Cloud KMS key sources and online key rotation** for encryption at rest are
  planned; keys come from an environment variable or a key file today.
- **MCP, Code-Graph and Graph-RAG in the prebuilt binaries.** Code-Graph
  (`hdb_code`), Graph-RAG (`WITH CONTEXT`) and the native MCP server ship in
  HeliosDB Nano as build-from-source features
  (`--features code-graph,graph-rag,mcp-endpoint`); the prebuilt binaries and
  the container image use the default features and do not include them.

---

## Distribution

- Prebuilt Linux binaries require glibc 2.39 or newer.
- A container image is published at `ghcr.io/heliosdatabase/heliosdb-nano`
  (one tag per release plus `latest`, multi-arch amd64/arm64); it contains the
  default-feature build. Docker Hub is not an official channel.
- Nano is published on crates.io as `heliosdb-nano`, with prebuilt binaries for
  Linux, macOS and Windows on GitHub Releases.
- The PyPI binding `heliosdb-nano-embedded` is released separately and can lag
  the engine release; check PyPI for the published version.
- The TypeScript client `@heliosdb/client` is built from the HeliosDB-SDKs
  source and is not published on npm; Node apps can also use the `pg` driver
  over the PostgreSQL wire protocol.

Found something not listed here? Open an issue on
[GitHub](https://github.com/HeliosDatabase/HeliosDB-Nano/issues), ask on
[Discord](https://discord.gg/yTykuUrFXc), or email
[support@heliosdb.com](mailto:support@heliosdb.com). Report security issues
privately to [security@heliosdb.com](mailto:security@heliosdb.com).
