Changelog

All notable changes to OxiDB, organized by version.

v0.28.18

2026-05-25 latest

Added

  • OxiWire HELLO handshake — new cmd: "hello" returns server version, supported wire versions, stable-surface feature set, experimental feature set, and auth methods. Pre-auth, idempotent, backward-compatible (clients without HELLO default to wire v1). See oxidb-server/src/hello.rs and ADR-0003 Phase 2.
  • REST /v1/ URL prefixGET /v1/hello returns server info; /v1/api/... is the 1.0 stable surface entry point. Legacy bare /api/... still routes during the deprecation window.
  • WebSocket subprotocol versioning — server advertises oxidb.v1 via Sec-WebSocket-Protocol. Clients without the header still connect.
  • oxidb migrate CLI — new subcommand on oxidb-cli: migrate inspect --data <PATH> walks a data directory and reports each file's on-disk format version (OXWA / OXTX / OXBT / OXIX / blob format_version). migrate run validates versions and is the scaffold for future v2 migrations (ADR-0003 Phase 4).

Performance

  • Bytes-first find path for OxiWire responses — new jsonb_oxiwire module converts JSONB to OxiWire bytes via a custom serde Visitor, skipping the serde_json::Value tree intermediate (~20 µs/doc saving on cache miss). A new doc_bytes_cache (env-tunable via OXIDB_DOC_BYTES_CACHE_SIZE, default 1M) keeps pre-encoded bytes around.
  • Composite-index fast pathfind queries that are exactly covered by a composite index's fields now route through find_prefix directly, skipping post-filter and Value materialisation.
  • Partial-JSONB filter — new helper evaluates top-level $eq/$ne/$gt/$gte/$lt/$lte/$in conditions plus $and / $or / dot-paths directly against JSONB bytes using codec::extract_field. Wired into the aggregation pipeline's $match step AND the find full-scan rayon path; reserves the full JSONB→Value decode for queries with predicates the partial matcher can't evaluate.
  • Doc cache capacity is env-tunableOXIDB_DOC_CACHE_SIZE overrides the 100K default. Production hardware with more RAM can hold the full working set.

Benchmark

  • OxiDB sweeps MongoDB at 1M docs. The full tests/comparison-mongodb bench at 1M-document scale (in-network Docker harness, no port-forward artifact) goes OxiDB 24 – MongoDB 0 across 24 measured workloads. Largest wins: count-all 2189×, Top-5 cities aggregation 1262×, composite-indexed compound 4.1×. Smallest wins: bulk insert 1.1×, range-10K-rows-each 1.2×. Resource footprint at peak: OxiDB 1.71 GiB RSS / 741 MB disk vs MongoDB 1.00 GiB / 626 MB. See Benchmarks.

.NET clients (developer-friendly rework)

  • 4 NuGet packages published at v0.28.18OxiDb.Client.Tcp, OxiDb.Client.Embedded, OxiDb.EntityFrameworkCore, and NEW: OxiDb.Linq (LINQ provider, previously source-only).
  • Exception hierarchyOxiDbException base + OxiDbDuplicateKeyException, OxiDbTransactionConflictException, OxiDbAuthenticationException, OxiDbNotFoundException, OxiDbImmutableException (WORM), OxiDbConnectionException, OxiDbProtocolException. Server error strings routed to the right subclass via FromServerMessage. Legacy OxiDbTcpException retained as [Obsolete] alias.
  • HelloAsync + HelloResponse record — wire-protocol handshake returning server version, supported wire versions, stable + experimental feature sets, auth methods.
  • Typed CRUD overloadsFindAsync<T>, FindOneAsync<T>, InsertReturningIdAsync (returns long), InsertManyReturningIdsAsync (returns long[]). Eliminate the JsonElement→parse dance.
  • StreamAsync<T>IAsyncEnumerable<T> over paginated LIMIT/SKIP batches for million-row result sets.
  • DI integrationservices.AddOxiDbTcp(opts => opts.Host(…)) registers IOxiDbClient as a singleton.
  • Type-safe query builderQuery.Eq, Query.Gte, Query.In, Query.And, Query.Or, Query.Range … for runtime-constructed queries that don't fit LINQ.

1.0 prep docs

  • docs/SEMVER.md, docs/STABILITY.md, docs/DEPRECATION.md, docs/SECURITY.md — Phase 5 of ADR-0003. Translate the ADR-0004 release-policy decisions into operational docs (24-month LTS, additive-only minor releases, GitHub Security Advisories channel, etc.).
  • docs/PHASE3-SDK-FREEZE.md + Python client api/v1.json snapshot + CI gate script (template for the other 9 Tier-A clients).
  • docs/format/compat-matrix.md — Phase 2 cross-version compat matrix (OxiWire / REST / WebSocket).

v0.28.12

2026-05-24

Added

  • Audit log rotationRotationPolicy in oxidb-server/src/audit.rs supports size-based (OXIDB_AUDIT_MAX_BYTES), age-based (OXIDB_AUDIT_MAX_AGE_SECS), and calendar-aligned UTC rotation (OXIDB_AUDIT_CALENDAR=hourly|daily), with optional gzip compression of rotated files (OXIDB_AUDIT_COMPRESS=true). Wired into both standalone and cluster modes.
  • CERN-grade testing program — 9 cargo-fuzz targets (RESP, pg_wire, OxiWire, MsgPack, differential vs Redis & Postgres), OSS-Fuzz integration scaffolding, coverage reporting, ACID isolation-anomaly suite, HEP-shaped scale workload, encrypted-backup DR drill, upgrade-chain fixture corpus, and 39 authn/authz/SCRAM/canonicalisation/audit attack patterns — all rejected by the server.
  • Format version headers — OXTX for _tx_commit_log, OXWA for .wal, OXBT for .btree; explicit format_version in blob .meta JSON. Establishes the 1.0 on-disk-format contract.

Fixed

  • Unauthenticated DoS bugs found by fuzzing — RESP multi-byte UTF-8 line splitter panic, RESP CR-truncation + allocator-bomb, pg_wire message length unbounded allocation (now capped at 16 MiB), pg_wire i16-overflow + empty-body panic, OxiWire array/map pre-allocation now bounded by remaining bytes. Server versions < 0.28.3 vulnerable.

Changed

  • Julia client surfacefind / aggregate now return a Tables.jl-compatible row collection (DataFrames, CSV, MLJ, GLM accept it directly). SQL exports removed from Julia clients — OxiDB is a document database; Tables.jl covers the data-frame integration story.

v0.25.3

2026-04-25

Changed

  • Raft persistence: O(1) per mutation — rewrote oxidb-server/src/raft/log_store.rs to split state into a small raft_meta.json (vote / committed / sm_data) and an append-only raft_log.jsonl (one entry per line).
  • Append-only log writesappend_to_log is now a single line append per entry instead of rewriting the entire log; delete_conflict_logs_since and purge_logs_upto rewrite only on those rare events.
  • Transparent migration from the v0.25.2 single-file raft_state.json on first boot.
  • Unblocked 1M-record load tests under failover — 22.4 s end-to-end, 44,701 rec/s avg, zero records lost. The previous single-file snapshot stalled the cluster at ~52% complete due to 14 MB-per-mutation rewrites.

v0.25.2

2026-04-25

Added

  • Persistent Raft state for cluster modeOxiDbStore in oxidb-server/src/raft/log_store.rs was previously in-memory only; nodes that restarted came back as Learner term=0 and lost cluster membership, breaking failover scenarios.
  • New OxiDbStore::open(db, &data_dir) constructor — loads existing Raft state on startup; OxiDbStore::new(db) retained as in-memory variant for tests.
  • Atomic write-through on every mutation — save_vote, save_committed, append_to_log, delete_conflict_logs_since, purge_logs_upto, apply_to_state_machine, install_snapshot.
  • ShardReplicaRealWorldTest harness — 14-service docker-compose: 9 oxidb-server nodes (3 Raft groups), 3 per-shard oxipool master/replica routers, 1 top-tier shard-routing oxipool, Go API tier, one-shot cluster-init bootstrapper.
  • End-to-end test suites — Go smoke harness (5 assertions), Python integration tests (8 cases: CRUD + sharding + aggregation), Python failover scenarios (5: network partition, follower down, recovery catch-up, two followers down, leader down), parameterized load test with mid-stream failover (validated against 10K, 100K, 1M record loads).

v0.25.1

2026-04-18

Added

  • Eight new query operators$not, $nor, $all, $size, $type, $mod, $expr, $elemMatch.
  • $not field operator — negate any field condition; missing fields evaluate to true (MongoDB-compatible).
  • $nor top-level operator — match documents where none of the listed conditions are true.
  • $all array operator — array must contain all specified values.
  • $size operator — match arrays with an exact length.
  • $type operator — match by JSON type (string, number, bool, array, object, null, int).
  • $mod operator — modulo arithmetic on numeric fields ([divisor, remainder]).
  • $expr top-level operator — cross-field comparisons, e.g. {"$expr": {"$gt": ["$sold", "$stock"]}}.
  • $elemMatch operator — match array elements against sub-queries with AND semantics.
  • Go client additions — stored procedures (CreateProcedure, CallProcedure, ListProcedures...), CreateTTLIndex, retention policies, alerting methods, ExtractText, Backup/Restore, SetDialect.

Fixed

  • Array dot-notation in $set / $inc / $unsetvariants.0.stock no longer corrupts arrays.

Changed

  • Refactored matches_doc and matches_value into a shared eval_field_op helper.

v0.24.0

2026-04-10

Added

  • WebAssembly support -- New oxidb-wasm crate compiles OxiDB to wasm32 and runs entirely in the browser.
  • In-memory browser mode -- No server needed. JSON queries, SQL, and aggregation all work client-side in the browser.
  • wasm-bindgen API -- Full JavaScript API surface: init, insert, find, update, delete, count, sql, aggregate.
  • ~1.5 MB gzipped WASM binary -- Compact binary size suitable for production web applications.
  • TypeScript types included -- Full type definitions shipped with the WASM package for editor autocompletion and type safety.
  • Cross-platform lock shim (src/locks.rs) -- Uses parking_lot on native targets, spin locks on wasm32.

Changed

  • Native-only dependencies made target-specific -- rayon, memmap2, zstd, and other native-only crates moved to target-specific dependencies to enable WASM compilation.
  • #[cfg(not(target_arch = "wasm32"))] guards throughout core engine -- Platform-incompatible code paths conditionally compiled out for the WASM target.

v0.18.0

2026-03-05

Added

  • OxiWire binary protocol -- Custom wire format with 1-byte type tags, 4-byte LE lengths, 8-byte LE numbers. Magic byte 0xDB. Replaces MsgPack for all request/response paths. Encoder + decoder in Rust and Go
  • .NET EF Core provider -- Full Entity Framework Core support with LINQ queries, transactions, and both TCP and embedded modes. d7d5a05
  • .NET NuGet packages -- OxiDb.Client.Tcp, OxiDb.Client.Embedded, OxiDb.EntityFrameworkCore. d7d5a05
  • Composite index tests -- 9 subtests covering exact match, prefix match, count, sort, update, delete, aggregate, drop, and triple-field composite indexes in Go.
  • Parallel OxiWire serialization -- Result sets >= 5,000 docs are serialized across up to 8 CPU cores. Chunk-based, zero per-doc allocation.
  • OxiDB vs MongoDB benchmark suite -- 22 tests across 7 categories. Score: OxiDB 19 -- MongoDB 1.
  • OxiDB vs PostgreSQL benchmark suite -- 20 tests comparing document workloads. Score: OxiDB 10 -- PostgreSQL 10. d7d5a05
  • OxiDB vs SQLite benchmark -- 100K document embedded benchmark. ce8db5f

Changed

  • Aggregation indexed-path threshold -- Changed from 10% to 50% selectivity. Indexed aggregation path now preferred when candidate set is less than 50% of collection size.
  • Go client rewritten for OxiWire -- All requests/responses use OxiWire binary format. MsgPack dependency removed entirely.
  • Pipeline handler updated -- Sub-responses decoded from OxiWire and re-encoded for composite pipeline responses.

Removed

  • MsgPack support -- Removed from server (Rust), Go client, and all benchmark tests. OxiWire is the sole binary protocol.
  • github.com/vmihailenco/msgpack/v5 -- Removed from Go module dependencies.

v0.17.0

2026-02-23

Added

  • LRU document cache -- Per-collection in-memory cache with configurable capacity. JSON deserialized once, then Arc-refcounted. 0997d8e
  • Streaming scan for non-indexed finds -- Avoids loading all documents into memory for large unindexed queries. 39cd803
  • Lock-free pread -- Separate read-only file handle uses pread for concurrent reads without locking the write path. 63093a3
  • Sorted-offset batch reads -- Indexed finds sort offsets before reading to minimize disk seeks. 63093a3
  • Zero-decode aggregation -- Extract only needed fields from raw JSONB, skip full document deserialization. 4a6f696
  • Batch pread for indexed $match aggregations -- Combine pread with zero-decode for indexed aggregation paths. 4b610ea
  • Zero-decode index creation -- Extract only _id and the indexed field from raw JSONB during index build. beb3f49
  • DocIdSet optimization -- Inline storage for single-document index entries saves ~80 bytes per entry. 4897f86
  • Zero-decode filter for unindexed scans -- JSONB keypath extraction avoids full JSON parse on scan. 7b9c639
  • Parallel segmented scan -- Large unindexed queries split across CPU cores for parallel processing. b339e5a
  • Index-only count for aggregations -- $group with $sum: 1 on indexed fields returns set size without touching documents. b339e5a

Changed

  • Memory consumption reduced -- Skip bulk cache during insert, drop unused Value clones, use DocIdSet instead of BTreeSet for single-entry indexes. 4897f86
  • Streaming I/O throughout -- Replaced collect-then-process patterns with streaming iterators for finds, aggregations, and index creation.

v0.16.0

2026-02-23

Added

  • Core document database engine -- Append-only storage, WAL with CRC32 checksums, per-collection locking.
  • JSON query language -- $eq, $ne, $gt, $gte, $lt, $lte, $in, $exists, $regex, $and, $or. Dot notation for nested fields.
  • Update operators -- $set, $unset, $inc, $mul, $min, $max, $rename, $currentDate, $push, $pull, $addToSet, $pop.
  • Aggregation pipeline -- $match, $group, $sort, $project, $limit, $skip, $unwind, $addFields, $lookup, $count. Accumulators: $sum, $avg, $min, $max, $count, $first, $last, $push.
  • Single-field, unique, and composite indexes -- BTreeMap-backed with index-only count and index-backed sort.
  • Full-text search -- TF-IDF ranking with HTML, XML, JSON, PDF, DOCX, XLSX, and OCR support.
  • Vector search -- HNSW index with cosine, euclidean, and dot product distance metrics.
  • ACID transactions -- OCC with 3-phase commit, per-document versioning, deadlock-free sorted locking.
  • SQL support -- SELECT, INSERT, UPDATE, DELETE, CREATE/DROP INDEX, CREATE/DROP TABLE, JOINs, GROUP BY, aggregate functions.
  • Blob storage -- S3-style bucket/object API with metadata, ETags, content types.
  • Encryption at rest -- AES-256-GCM with random 12-byte nonce per document.
  • Zstd compression -- Level 3, transparent per-document, thread-local context reuse.
  • Change streams -- Watch collections for insert/update/delete events. Resumable with 4096-event replay buffer.
  • Stored procedures -- Named multi-step operations with parameter substitution.
  • Scheduled tasks -- Background job scheduling with enable/disable control.
  • Multi-database support -- Isolated databases within a single server instance.
  • Backup & restore -- Compressed full backups with all data, indexes, and metadata.
  • TCP server -- Length-prefixed JSON over TCP (max 16 MiB). Tokio-based async runtime.
  • SCRAM-SHA-256 authentication -- Salted challenge-response, no plaintext passwords on wire.
  • RBAC -- Admin, ReadWrite, Read roles with per-command authorization.
  • TLS/SSL -- Certificate-based encryption for all traffic.
  • Audit logging -- GELF format for centralized logging.
  • Raft clustering -- Multi-node replication via openraft (optional cluster feature flag).
  • Client libraries -- Python, Go, Julia, .NET (TCP + Embedded), Swift (C FFI).
  • C FFI -- oxidb-client-ffi (cdylib) and oxidb-embedded-ffi (staticlib + cdylib) for language bindings.