COOLJAPAN
← All posts

OxiRS 0.4.0 Released — A Real On-Disk Store and a Unified SPARQL Engine, End to End

OxiRS 0.4.0 ships oxirs-tdb as a genuinely durable on-disk backend (WAL, superblock, sorted bulk build), unifies SELECT/ASK/CONSTRUCT/DESCRIBE through a single real oxirs-arq dispatch, migrates every route to axum 0.8, and hardens DID crypto, SSO, and cluster BFT — 45,199 tests, zero warnings across 27 crates.

release oxirs rdf sparql shacl graphql knowledge-graph pure-rust wasm

The SPARQL query path that used to be a demo parser is now the real oxirs-arq engine, end to end — and the “TDB2” store behind it finally survives a restart.

Today we released OxiRS 0.4.0 — the Rust-native Semantic Web / SPARQL 1.2 / GraphQL platform’s biggest correctness release yet, consolidating the previously-unpublished 0.3.3 production-hardening pass (a 272-finding audit, 288 fixes, 455 regression tests) with the 0.3.4 deployment fixes surfaced by the public, query-only sparql.wik.jp rollout. Neither 0.3.3 nor 0.3.4 ever reached crates.io — both ship here, together, as 0.4.0.

No JVM. No fabricated demo responses standing in for real query execution. No RDF store that quietly forgets your data was ever durable in the first place. OxiRS stays the Rust-first replacement for Apache Jena + Fuseki — one dataset speaking both SPARQL 1.2 and GraphQL, compiled to a single static binary or WASM module, with a dependency tree you can actually audit. 0.4.0 is the release where the query engine and the storage engine both stop cutting corners.

Why OxiRS 0.4.0 is a game changer

Most “production-ready” RDF stores accumulate a specific kind of technical debt: a query path that started as a demo and never got replaced, and a storage layer that “works” until the process actually restarts. That debt is invisible in a benchmark and catastrophic in production.

OxiRS 0.4.0 pays it off:

All of this lands at 45,199 tests passing with --all-features (44,398 on default features), zero compilation warnings across all 27 crates.

Technical Deep Dive: what’s new under the hood

1. Sorted bulk build meets a real WAL. insert_triples_bulk/insert_quads_bulk now intern and encode a whole batch up front (failing loudly on a bad batch before any mutation), construct each index (SPO/POS/OSP, GSPO/GPOS/GOSP) sorted, and issue one WAL batch plus one sync per batch — both the bulk loader and the fuseki TDB adapter route through it. Optional Unix direct I/O (O_DIRECT on Linux, F_NOCACHE on macOS) is available for callers who want to bypass the page cache.

2. arq_exec.rs is the new single front door. Instead of routing SELECT/ASK/CONSTRUCT/DESCRIBE through separate, drifting code paths, oxirs-fuseki’s new handlers/sparql/arq_exec.rs parses the query exactly once and dispatches into a zero-copy StoreRefDataset view over the real oxirs-arq engine. A graph_result module backs CONSTRUCT/DESCRIBE specifically — per-row blank-node-scoped template instantiation for CONSTRUCT, and a cycle-safe, blank-node-closure-following, now-symmetric Concise Bounded Description for DESCRIBE (both outgoing and incoming arcs).

3. Parser fixes that change real query results, not just edge cases. BIND is now scoped positionally per SPARQL §18.2.2 (a BIND followed by more graph patterns in the same group used to silently produce wrong bindings), a bare FILTER after a top-level UNION is properly group-scoped, and GROUP BY/ORDER BY expression lists — previously silently dropped by a tokenizer/parser mismatch on the trailing BY keyword — now populate correctly.

4. Security work that closes real gaps, not theoretical ones. oxirs-fuseki’s read_only enforcement now covers SPARQL Update, Graph Store Protocol, file upload, RDF Patch, admin dataset management, and the REST API v2 write endpoints — the last of which was a completely unguarded write bypass before. oxirs-cluster’s BFT consensus closes the loop end to end: real 2f+1 quorum, idempotent commit handling, and a real authenticated network service instead of a no-op broadcast stub.

Getting Started

The oxirs CLI stays intentionally off crates.io (publish = false, so it can optionally pull in the C-FFI quarantine adapters from 0.3.2 without exposing them on a published surface). Build it from source:

git clone https://github.com/cool-japan/oxirs.git
cd oxirs
cargo install --path tools/oxirs

Then put the new durable store to work:

# Bulk-load onto a real, durable, WAL-backed on-disk store
oxirs import mykg data.ttl --dataset-type tdb2

# Query it — now through the unified oxirs-arq engine end to end
oxirs query mykg "SELECT ?s ?p ?o WHERE { GRAPH ?g { ?s ?p ?o } } LIMIT 10"

# Serve it — SPARQL 1.2, GraphQL, and a Fuseki-style admin UI, all read/write against the same on-disk store
oxirs serve mykg/oxirs.toml --port 3030

The other 25 OxiRS library crates remain normally published — cargo add oxirs-core for the RDF/SPARQL engine on its own, or cargo add oxirs-arq if you just want the query layer:

[dependencies]
oxirs-core = "0.4.0"
oxirs-arq = "0.4.0"

What’s New in 0.4.0

Tips

This is the foundation

OxiRS is part of the COOLJAPAN ecosystem of Pure-Rust infrastructure, and 0.4.0 is the release where both halves of “production-ready” — a query engine that runs the query you actually wrote, and a store that actually keeps your data — come together. It rides on SciRS2 (0.6.1) for graph analytics and numerics, routes compression through the OxiARC family (0.3.6), handles crypto and transport through OxiCrypto/OxiTLS (0.2.1), and leans on OxiSQL (0.3.3) for its SQLite-compatible GeoSPARQL backend. Alongside siblings like OxiZ (SMT) and OxiRAG, OxiRS gives you an end-to-end auditable, JVM-free, C-free path from bytes on disk to a reasoned SPARQL answer — and now, one that survives a restart.

Repository: https://github.com/cool-japan/oxirs

Star the repo if you want a knowledge graph where “the query engine” and “the storage engine” both mean what they say. The era of demo query parsers pretending to be production SPARQL engines is over. Pure Rust Semantic Web is here — fast, safe, durable, and sovereign.

KitaSan at COOLJAPAN OÜ July 19, 2026

↑ Back to all posts