0.22.0 Release Notes
Released 2026-10-25 from the merge of PR #1510 (4254bca0, tag v0.22.0). It
includes everything since 0.21.0. The full list is in the repository
changelog.
Highlights
- History epochs (RFC-0038). Opt-in sealing, archiving and cluster-wide hot release of old history; released history is read from the verified archive. See History epochs.
- Identity and access management (RFC0037). Profiles, API keys, optional OIDC/OAuth providers and SCIM-managed identities. See IAM.
- Database incarnations. Each database carries a replicated incarnation UUID; drop and recreate, and restore, start a new one.
- Query engine. The RFC 0042 planner and executor switches are on by default (factorization, degree statistics, cost-based entry choice), with bounded per-query memory admission across sort, join, UNWIND and collect paths. See Query planning.
- Storage. Secondary labels moved inline into the adjacency (schema 8, RFC 0040 increment 1); wide vertex-property values are stored once per owner (schema 7). See Storage.
- Stability under memory and disk pressure (PR #1510). Paced checkpoint packaging, batched and recoverable squash cleanup, bounded redb freed-page reclamation per commit, single-barrier fork seeding, and a BEGIN wait bounded by the transaction deadline.
Data safety and recovery
Bulk upserts enforce schema constraints, keep graph entities intact across chunks and preserve unambiguous pre-load rollback targets. Restored baselines are checkpointed before admitting replicas, with snapshot publication and purge ordering enforced. Backup archive v2 retains property registrations and named indexes that older exports could lose.
Forced snapshot replacement durably retains the replay tail or fences the incomplete repair. Backfill errors are classified per call and retain their original cause; repair latches remain database-local across restart. Vector preparation propagates scan errors and publishes complete definitions last.
Queries and operational limits
Completed deferred tag snapshots release their cached read transactions, including when another snapshot path completed the work. Durable tags and pending snapshot captures remain intact. This removes a source of retained old database pages; fresh long-run memory qualification remains required.
Spill-heavy index loading now merges at most 32 input runs at a time, adding one output file for an intermediate merge. This fixes reproduced file-descriptor exhaustion while preserving duplicate ordering and cleanup on failure or early drop. The bound applies to each active merge, not all descriptors in the process; no throughput improvement is claimed. See the implementation and regression evidence.
FOREACH executes ordered mutation clauses with lexical scope and authorization.
Actual nodes/relationships retain their identity through containers and Bolt,
JSON and WASM conversions; UUID scalars remain scalars and real Paths stay Paths.
Store scalar references such as id(n) rather than entity/path property values.
Grouped ordering preserves renamed keys. Eligible partial-prefix multi-key ordering supports mixed directions while retaining NULL/tie-break rules, materialization limits and execution errors through SKIP. Seeded UNWIND and FORK DATABASE share their corresponding row/database limits. Terminating an idle transaction wakes its owner. Cache shape-admission history is bounded. Decoded rotation request secrets are zeroized on drop, including cancellation; this is not a guarantee about every raw transport or parser buffer.
COUNT subqueries in projections and WHERE comparisons share a seeded plan, including correlated filters. Single-pattern COUNT accumulates matches without materializing result rows; evaluation errors remain errors. General list-predicate lowering and decorrelation are still pending. Eligible unsorted equality filters use bounded advisory index probes, and SHOW INDEXES includes compound definitions.
Authorized management audit responses include stored peer_ip and origin. Both embedded UIs replace the vulnerable single-file plugin dependency chain with a shared offline bundler. These changes do not inherit the earlier soak.
Upgrade and downgrade boundaries
- Storage schema is 8. Opening a schema-7 store migrates it in place and rebuilds the inline label data; schema-6 stores must be recreated or reimported (no on-disk migration). Do not open a migrated store with an older binary.
- Peer protocol is 22 and the Raft snapshot format is 8. Physical snapshots with schema-8 bodies require protocol 22. Feature floors (incarnations 17, IAM 19, epoch metadata 20, history restore 21) apply once the corresponding records exist; new members must then speak at least that version. A matching protocol number alone does not qualify every mixed-version scenario.
- New backup readers accept archive formats 1 and 2. Old readers reject format 2; verify restores with compatible binaries before retiring older exports.
- Local snapshot-install intent changes from 1 to 2 and retains v1 reading. Do not downgrade across an unfinished v2 install/recovery intent.
- Direct Rust runtime-value consumers must handle the added Entity variant.
JSON containers expose structured entities; Bolt returns native entity
containers. Entity/path property values are rejected rather than coerced;
store
id(n)explicitly.
Qualification
PR #1510’s three-hour five-node mixed pressure soak passed on the released product code (run ae8ab7dd43ed, independently audited, no OOM), and its CI passed all 47 checks. This is one passing soak on one host, not a latency guarantee: the write tail under squash and checkpoint load is reduced but not solved (#1516, #1512). The RFC-0024 token release gate (#1151) remains a separate decision, including acceptance of finite token retention and eviction at capacity. A release is not a production approval for any particular deployment.