Skip to content

Graphus v0.0.5

Choose a tag to compare

@FlavioCFOliveira FlavioCFOliveira released this 03 Jul 07:29

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 TCK3914 / 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 bare MATCH sent
    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 zero fdatasync, explicit-transaction commits batch into a
    single group-commit fdatasync, 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-import streams CSV / .gcol data
    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-import streams CSV / .gcol
    data into a database without buffering the payload, gated by the same Admin RBAC check as
    BACKUP / RESTORE / CREATE DATABASE and 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 decision D-bulk-import-network and
    specified in specification/08-network-bulk-import.md.
  • Product-recommendations example. examples/product-recommendations boots 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 explicit BEGIN … COMMIT transactions 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; see docs/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 zero fdatasync across 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 single write() + single fdatasync (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 PULL of 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
    retriable 409 with 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 under strace and per-thread CPU sampling; the plan-clone and
    map-decode reductions from criterion microbenchmarks.

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 :latest

See 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.