Graphus v0.0.5
Graphus v0.0.5
Version: 0.0.5
Date: 2026-07-03
Tag: v0.0.5
Summary
Graphus v0.0.5 is a performance-and-hardening release of Graphus, the Label Property
Graph (LPG) database server written in Rust for extreme load and concurrency. It makes reads
and writes scale across cores, adds a network bulk-import path for loading data over
the wire, and closes a multi-vector production-readiness certification that fixed a
critical encryption-at-rest disk leak and several pre-authentication denial-of-service
vectors. It introduces no breaking changes — the public Cypher, Bolt, and REST contracts
are unchanged, so v0.0.5 is a drop-in upgrade from v0.0.4.
Throughout, the four inviolable guarantees held:
- 100% ACID — full transactional reliability under power loss, faults, and crashes.
- 100% openCypher TCK — 3914 / 3914 scenarios passing.
- 100% Bolt protocol — byte-for-byte interoperability with the Neo4j driver ecosystem.
- 100% PackStream — exact wire-level serialization.
Highlights
- Lock-free reads that scale across cores. A standalone auto-commit read is now dispatched
across the off-thread reader pool by its structural query type — so a bareMATCHsent
without a routing hint is no longer pinned to the single engine thread — and runs as a
lock-free Snapshot-Isolation snapshot read that takes no serializability overhead and can
never cause a writer to abort. This is the MySQL / MariaDB / SQL-Server autocommit model:
a transaction exists only when you open one. - Reads and writes scale with concurrency. REST reads now engage the reader pool,
read-only transactions perform zerofdatasync, explicit-transaction commits batch into a
single group-commitfdatasync, and that fsync is pipelined off the engine thread. On a
concurrent read workload server CPU rose from roughly one core to nearly five; trivial reads
climbed from a ~450 requests/s fsync-bound ceiling to tens of thousands per second; and
committed-write throughput scales several-fold with concurrency on durable storage. - Network bulk-import. A new
POST /admin/db/{db}/bulk-importstreams CSV /.gcoldata
over the wire — Mode A for a fresh or empty database, Mode B for an already-live database
concurrently with ordinary traffic — behind the Admin RBAC gate with quota, disk, and
session-timeout protection. - Certification pass. A critical encrypted-at-rest WAL disk leak, a crash-recovery
out-of-memory path, and multiple pre-authentication denial-of-service vectors were found and
fixed, each with a gating regression test.
Added
- Network bulk-import over REST.
POST /admin/db/{db}/bulk-importstreams CSV /.gcol
data into a database without buffering the payload, gated by the same Admin RBAC check as
BACKUP/RESTORE/CREATE DATABASEand protected by a per-byte quota, an ongoing
free-disk check, and a session timeout (all configurable). Mode A loads a new or empty
database through the low-level bulk-write path with a crash-durable per-batch checkpoint
sentinel; Mode B loads an already-live, serving database concurrently with ordinary
Bolt/REST traffic, its correctness coming entirely from participating in the same MVCC/SSI
machinery every ordinary Cypher transaction uses, with automatic bounded retry of a batch
that loses a serialization conflict. Ratified as decisionD-bulk-import-networkand
specified inspecification/08-network-bulk-import.md. - Product-recommendations example.
examples/product-recommendationsboots a real server,
network-bulk-loads a recommendation multigraph over the wire, and drives a concurrency ladder
of many simultaneous Bolt-over-UDS clients running a realistic read battery (direct-friend,
second- and third-level, and collaborative-filtering traversals) plus a few concurrent
writes, while sampling the server's CPU, RSS, and I/O to expose read-path bottlenecks —
backed by a new deterministic generator and client tooling (graphus-reco-gen). - Server startup banner. A single structured startup line names the application, its
version, the build platform (OS / architecture / pointer width), and the pid. docs/transactions.md. Documents autocommit-by-default, explicit transactions, lock-free
reads, the per-work isolation table, and how to opt a read back into serializable isolation.
Changed
- Reads are lock-free and scale across cores; MySQL-style autocommit isolation. A standalone
auto-commit read is dispatched off-thread by its structural query type (not the
client-declared access mode) and demoted to Snapshot Isolation: it drops its serializability
tracking and can never make a concurrent writer abort, while still reserving its MVCC snapshot
so it reads a consistent view and pins the GC watermark for the versions it reads. Writes
and explicitBEGIN … COMMITtransactions are untouched — full Serializable SSI. A read
that needs serializable isolation opts in by running inside an explicit transaction. This is
the InnoDB read-only model; seedocs/transactions.md. - Read throughput scales with concurrency. The off-thread reader pool is now engaged for
single-statement REST reads (previously every REST read ran inline on the engine thread), and
a read-only transaction performs zero WAL append and zerofdatasyncacross its whole
lifecycle. Measured: server CPU on a concurrent REST read workload rose from ~0.8 core (engine
the sole hot thread) to ~4.8 cores with the reader pool engaged, and trivial reads scaled from
~450 requests/s to 36k–54k requests/s at concurrency 8–32. - Write throughput scales with concurrency. Explicit-transaction commits batch their commit
records into a singlewrite()+ singlefdatasync(cross-transaction group commit), and the
batch fsync is offloaded to a dedicated sync thread so the engine overlaps it with preparing
the next batch and retiring off-thread reads (commit pipelining). Committed-write throughput
scales several-fold under concurrency on durable storage — the larger the fsync latency, the
larger the gain — while a committer is acknowledged only after the fsync covering its commit
record completes. - Lower per-statement engine cost. Compiled query plans are
Arc-shared through the plan
cache and executor, so a plan-cache hit ships a reference-count bump instead of a deep tree
clone — a ~64–233× reduction in the per-statement clone cost that dominates the
parameterized-repeated production case. - Cheaper bulk loading. During a Mode A bulk-import session the background
maintenance-checkpoint interval is widened 16×, cutting the maintenance overhead that a
create-only workload would otherwise accrue as the store grows; every other workload keeps the
unchanged, frequent reclamation cadence.
Fixed
- Encrypted write-ahead-log disk leak (critical). On an encryption-at-rest database the
encrypted WAL stored its sink header in the first backing segment, which the prefix-only
segment reclaimer could never free — so the encrypted WAL grew on disk without bound and a
heavily-reclaimed log could not be reopened after a crash. The header is relocated into the
never-deleted anchor (matching the plaintext layout); the on-disk sink version is bumped and
an old-layout encrypted WAL is rejected fail-closed at open. AEAD framing, nonce-budget resume,
and key-check fail-closed are preserved exactly. - Crash-recovery out-of-memory on a long-lived WAL. Recovery scans sized their buffer by the
log's absolute lifetime rather than its small retained window, so a heavily-reclaimed log could
abort on reopen with an out-of-memory error and leave the database unable to reopen (an ACID
violation). Recovery now reads only from the reclaimed floor; behaviour is byte-identical when
nothing has been reclaimed. - Pre-authentication denial-of-service vectors (PackStream). Decoding an attacker-supplied
message before authentication could burn minutes of CPU (a many-key map decoded in O(N²) — now
an order-preserving O(N) accumulator, ~780× faster) or amplify a few megabytes into gigabytes
of heap (a deeply-sized collection with no breadth budget — now a per-message decoded-element
budget caps decoded heap at a small multiple of the framing limit). - Availability and correctness hardening (certification pass). A Bolt
PULLof a full
result no longer buffers the entire result in the per-connection write buffer before flushing;
an off-thread reader whose consumer stops draining now aborts at its statement deadline instead
of blocking forever and pinning the GC watermark; the coordinator's serialization-conflict
tracker is pruned from the maintenance checkpoint instead of leaking an entry per committed
transaction and per read; and a full-text/spatial procedure feeding an expansion is no longer
mis-dispatched off-thread into a spurious "no such index" error. - REST conflict handling. A conflicting single-statement write auto-commit returns a
retriable409with the connection kept alive, instead of dropping the HTTP connection
mid-stream; single-statement reads still stream. The buffered write result is bounded (16 MiB)
so a large authenticated write cannot exhaust memory — it never commits half-way and never
silently truncates. - Bulk-import retry safety. The offline bulk importer stages each batch's external-id
bindings and row-count statistics separately and merges them only after the batch durably
commits, so an aborted batch can be retried without falsely rejecting a duplicate id or
resolving relationships against rolled-back physical ids.
Verification
This release was validated empirically; no functional test reported an error.
- Conformance gates intact. The openCypher TCK remains at 3914 / 3914 (100%), and the
Bolt, PackStream, and ACID guarantees are unchanged. The deterministic simulator (DST/VOPR)
ran safety, liveness, and mixed workloads across seed sweeps with byte-identical, deterministic
outcomes, and the Elle checker confirmed serializability of writes and explicit transactions. - Regression coverage. Every fix landed with a gating regression test proven to fail before
the fix — including the encrypted-WAL segment-reclaim test, the crash-recovery
retained-window allocation test, the pre-auth decode budget/complexity tests, the
stalled-consumer wedge test, and the REST conflict-to-409 and buffered-write-bound tests. - Performance measured, not assumed. The throughput figures above were taken from a
release-build server understraceand per-thread CPU sampling; the plan-clone and
map-decode reductions fromcriterionmicrobenchmarks.
Compatibility
v0.0.5 is a drop-in upgrade from v0.0.4 — no public Cypher, Bolt, or REST API contract
changed. The one behavioural change to be aware of is the isolation of standalone reads:
an auto-commit read that is not inside an explicit transaction now runs at Snapshot Isolation
(the MySQL / InnoDB autocommit model) instead of Serializable, so it never blocks or aborts a
writer. Writes and explicit BEGIN … COMMIT transactions remain fully Serializable. A
workload that requires serializable reads should wrap them in an explicit transaction; see
docs/transactions.md. The four inviolable guarantees (ACID,
openCypher TCK, Bolt, PackStream) remain at 100%.
Upgrading
# Docker Hub (multi-arch: linux/amd64 + linux/arm64)
docker pull flaviocfo/graphus:v0.0.5 # or :latestSee docs/getting-started.md for first-run instructions,
docs/transactions.md for the read/write isolation model, and
docs/rest-api.md for the network bulk-import endpoint.