KantanDB / current implementation

Go

The Go server implements the current database design as one HTTP service backed by a local Pebble store.

For now, the Go server is the reference implementation. Its storage formats may change as the design develops.

Browse the server source →

01

HTTP interface

The service creates named databases and accepts document CRUD requests. It generates UUIDv7 document IDs and exposes revisions as ETags. Replacement, patch, and deletion can use If-Match to reject a stale revision.

Patches support JSON Merge Patch and JSON Patch. Routes use Go's net/http package and live under /db. Paths without a trailing slash are canonical.

The HTTP layer validates names and documents, limits body size, uses a consistent JSON error format, and shuts down gracefully. GET / reports the service name and build version. See the OpenAPI 3.2 contract for the complete interface.

02

Storage

Pebble holds every logical database in one ordered local store. Documents, database metadata, index definitions, and index entries occupy separate key ranges. Synchronous batches update a document and its indexes atomically and durably.

Striped locks coordinate concurrent document writes. Database deletion takes the corresponding database lock so that it cannot race with those writes.

03

Encryption

The server requires a base64-encoded 256-bit master key in a file outside the data directory. It derives a store wrapping key and uses it to protect a random key for each database.

Document JSON is compressed with Zstandard, then encrypted and authenticated with AES-256-GCM. Per-document keys are derived with HKDF-SHA256. Cursor keys are derived separately. The key and record layout authenticate stored data but do not hide database names, IDs, indexed values, or record sizes.

04

Indexes

Indexes are declared when a database is created. Each one maps a JSON Pointer path to ordered Pebble keys containing the encoded field value and document ID.

Equality accepts any JSON scalar. Ordered comparisons accept numbers and strings without coercion. Number encoding preserves exact JSON numeric order; strings use binary UTF-8 order. Query pages return document IDs and opaque authenticated cursors.

05

JSONPath queries

QUERY /db/{database} accepts RFC 9535 JSONPath in a JSON request body. A document matches when any scalar selected by the path satisfies the comparison.

A simple path uses a matching declared index when it is safe to do so. Other paths scan documents in ID order. Each page may scan at most 10,000 documents, each request has a five-second deadline, and path size, nesting, selectors, and evaluated document nodes are bounded.

06

Bulk transfer

GET /bulk/{database} streams documents as NDJSON from a consistent Pebble snapshot. POST /bulk/{database} imports them with new UUIDv7 IDs and revisions, rebuilds the target database's index entries, and commits atomically.

Operators can limit transfer size, document count, Pebble batch size, duration, and concurrency. Bulk transfer preserves document values but omits database metadata, original IDs and revisions, ETags, and encryption keys. It is not backup and restore.