I released KoutenDB v0.9.0.

Release:

https://github.com/puffball1567/koutendb/releases/tag/v0.9.0

KoutenDB is a ring-oriented NoSQL document and vector database written in Nim.
Its central idea is deliberately narrow: when an application already knows a useful locality boundary, that knowledge should reduce the data a request has to inspect.

Previous releases established the data model, public API, native C ABI, and language-driver foundation. v0.9.0 concentrates on a harder question: can that locality model be tested against a realistic, persistent related-data read shape rather than only described as a design idea?

This is still a technical preview. It is not a claim that KoutenDB replaces PostgreSQL, Redis, or every document store. The goal of this release is to make the narrower claim measurable and reproducible.

The Request Shape: One Entity, Several Bounded Collections

Many web application detail pages need more than one record. A user page, for example, may need a profile, a few addresses, recent employment entries, preferences, recent orders, and notifications. Each collection has its own limit and sort order.

In a relational database, this can be expressed with several indexed queries or with a JSON aggregate query built from limited subqueries. Both are valid approaches. The question KoutenDB explores is different: if these collections are already known to belong to one user, can that relationship be represented as bounded nearby data from the start?

v0.9.0 models the example as subrings below a user ring:

kouten get --ring=users/<id> \
  --subring=profile,addresses,career,preferences,orders,notifications \
  --subring-limit=profile:1,addresses:3,career:2,preferences:1,orders:10,notifications:5 \
  --subring-rsort=orders:time,notifications:time

Enter fullscreen mode Exit fullscreen mode

This says exactly what the endpoint needs: retrieve six nearby collections, with independent bounds. It is not a general query language and it is not intended to be one. The useful property is that the caller supplies the locality boundary before the read begins.

What Changed in v0.9.0

The release adds a benchmark for that heterogeneous related-data bundle and strengthens the corresponding read path.

  • readStellar now prepares projection state once and reuses it across subrings.
  • Stellar reads validate per-subring limits and descending time sorts.
  • Simple embedded reads with an empty filter, a positive limit, and id or time ordering can use a bounded ring-window read path.
  • Disk-backed segment reads reuse cached streams instead of repeatedly opening the same segment files.
  • import-jsonl supports chunked commits through --batch-size=N for larger data imports.

The point of these changes is not an isolated micro-optimization. A locality model only helps if its normal persistent read path remains bounded when the dataset grows.

A Reproducible Related-Data Comparison

The repository now includes a helper that builds fresh temporary KoutenDB and PostgreSQL data directories, loads the same logical user dataset, and measures the related-data bundle:

N=10000 READS=1000 examples/subring_bundle_postgres_bench.sh

Enter fullscreen mode Exit fullscreen mode

One local run on 2026-07-21 used an AMD Ryzen 5 5600H, Linux 6.8, Nim 2.2.10, and PostgreSQL 14.23.

Users Logical records System and query shape Returned records Read latency
10,000 1,050,000 KoutenDB users/<id>/* stellar read with per-subring bounds 22 across 6 rings 196.859 us
10,000 1,050,000 PostgreSQL: six indexed SELECT statements 22 515 us
10,000 1,050,000 PostgreSQL: JSON aggregate over indexed limited subqueries 1 JSON bundle 236 us

These numbers describe one machine and one workload; they are not a universal database ranking. PostgreSQL's aggregate form is close to the measured KoutenDB result, and it expresses the result through a different but perfectly
reasonable abstraction. The value of the comparison is to keep the claim honest: KoutenDB's ring and subring model should be judged on workloads where the application can name a local working set.

Testing the Larger Locality Claim

v0.9.0 also records the completed disk-backed effect-validation run on generated data. The validation imports deterministic JSONL corpora and compares broad retrieval with ring-routed retrieval. It reports import time, records scanned, estimated token volume, and retrieval latency.

The standard scale-1000 matrix completed locally with a largest case of 13,500,000 documents.

Workload Broad scan Ring-routed scan Estimated tokens: broad -> routed
small-balanced 168,000 24,000 692 -> 260
near-distractors 1,860,000 120,000 1,730 -> 433
medium-noisy 13,500,000 500,000 2,595 -> 692

The token column is an estimate for the generated retrieval payloads, not a benchmark of any model. More generally, this validation is not limited to AI workloads. Scanned records, transferred data, candidate memory, and downstream application work all increase when a request must inspect unrelated data.

The important result is that the test makes the expected trade-off visible:
locality can reduce the candidate set when the application supplies a valid ring boundary. It cannot invent a useful boundary when the application has none.

Offline Validation Before Production Traffic

The release also adds an offline JSONL path:

KOUTEN_REAL_JSONL=/path/to/export.jsonl \
QUERY_RING=docs/japan \
examples/offline_effect_validation.sh

Enter fullscreen mode Exit fullscreen mode

This is intended for copied or exported data rather than a production service.
It gives a team a way to test whether a proposed ring layout narrows its own workload before asking the database to serve live traffic.

That boundary matters. A database experiment should be reproducible without requiring production credentials, traffic capture, or an unbounded benchmark environment.

Verification Included in the Release

The v0.9.0 release state was checked with Nim module checks, the public API test program, the smoke suite, package validation, and whitespace validation:

nim check src/kouten/store.nim
nim check src/koutendb.nim
nim check src/koutencli.nim
nim check tests/tapi.nim
nim c --nimcache:/tmp/nimcache_kouten_tapi -r tests/tapi.nim
scripts/test_all_smoke.sh
nimble check
git diff --check

Enter fullscreen mode Exit fullscreen mode

The largest generated run remains an explicit manual validation rather than a default CI job. It is valuable precisely because it exercises a scale that a quick smoke test should not pretend to cover.

What Comes Next

v0.9.0 makes the locality hypothesis easier to test with persistent data and a concrete web-style read shape. The next work is about making that evaluation more operable: verification commands, controlled drain and snapshot workflows, backup checks, audit records, and safer topology transitions.

Those are v0.10 development goals, not claims included in v0.9.0.

KoutenDB remains an early project, but the direction is now more concrete:
data locality should be a testable part of a database read path, not only a diagram or a benchmark headline.

Source and release notes:

https://github.com/puffball1567/koutendb