Open source · MIT · v1.0 API frozen

A file-based
document database.

FileDB v2 stores each collection as append-only NDJSON — human-readable, one JSON object per line. Get a durable document store with gRPC + REST from a single Go binary, or embed the engine directly in your program. No daemon, no external runtime, no hidden state.

zsh — filedb
$ filedb serve --data ./data --api-key dev-key &
$ filedb-cli insert users '{"name":"alice","age":30}' --api-key dev-key
   id=01J8... key=01J8... rev=1

$ filedb-cli find users '{"field":"name","op":"eq","value":"alice"}'
  ▶ index hit users.name (1 row scanned, 1 returned)
  {"name": "alice", "age": 30}

$ tail -1 data/users/000001.ndjson  # it's just text on disk
  {"id":"01J8...","key":"01J8...","rev":1,"data":{...},"crc":"a1b2"} 

Why FileDB

Persistence without the operational weight

When you need a real document store but standing up PostgreSQL or MongoDB is overkill — and you'd like to still be able to cat your data.

📄

Human-readable storage

Every collection is plain NDJSON — one JSON object per line. Inspect, grep, back up, or migrate your data with any text editor. No binary format, no hidden state.

Append-only & durable

Inserts, updates, and deletes are always new lines. Choose your fsync policy, and a CRC32C checksum on every entry catches silent on-disk bit-rot on read.

🔌

gRPC + REST + embed

A dual API served from one binary — plus a `go get`-able storage engine you can run in-process, with zero gRPC/Prometheus/OTel dependencies.

📦

Single binary

No JVM, no Python, no daemon zoo, no config file to get started. One small Go binary that serves, and one CLI that talks to it over a Unix socket.

How it works

An append-only engine with real indexes

Writes append to a segment log; a background compactor merges and dedups sealed segments; an in-memory id index and per-field secondary indexes keep reads fast.

Storage engine

crc32c-verified
  • segment log append-only NDJSON files, sealed at 4 MiB
  • id index in-memory O(1) lookup, checksummed on disk
  • secondary indexes per-field equality + range, auto-maintained
  • compactor goroutine per collection merges & dedups

Records carry a key, a monotonic rev, and a crc. A limited Find is bounded by the page size, not the collection size, and streams rows as it reads — with keyset pagination that covers every row exactly once.

Over the wire

7client SDKs
PythonJS/TSPHP JavaRubyRust C#

Plus a generated OpenAPI spec for any other language.

Durability modes

noneOS flush · fastest
intervalfsync on a timer
alwaysfsync per write

Trade throughput against your crash-loss window with --sync. The embedded façade defaults to interval (~1s).

Replication & scale

Leaderread + write
Followersread replicas
Failovermanual promote

A follower bootstraps from a snapshot then tails the leader's committed writes by global LSN — resumable, no gaps or dupes. Bound staleness by diffing applied vs leader LSN.

Two binaries, three ways to run

Server, embedded, or containerized

🖥️

Standalone server

Run filedb serve and get gRPC on :5433 and REST on :8080 from one binary. Talk to it from any language, or from the CLI over a Unix socket.

📚

Embedded library

Skip the server entirely — go get the engine and run the database in-process. Keyed CRUD, CAS, secondary indexes, and in-process Watch.

🐳

Docker & Compose

Pull ghcr.io/srjn45/filedbv2 or docker compose up. Data persists in a named volume; REST and gRPC ports exposed and ready.

The API surface

More than a key-value store

Keyed CRUD with caller-supplied string keys, insert-or-replace upsert, and revision-checked compare-and-swap — plus streaming queries, aggregations, TTL, optimistic transactions, and live Watch subscriptions.

insertfindupdatedeleteupsertupdate-if-revaggregatewatchbegin-txbackup

Explore

Everything FileDB does

Quickstart

Up in under a minute

# start the server (or: docker compose up -d)
filedb serve --data ./data --api-key dev-key

# insert, then query — via the CLI over the Unix socket
filedb-cli insert users '{"name":"alice","age":30}' --api-key dev-key
filedb-cli find   users '{"field":"age","op":"gt","value":18}' --api-key dev-key

# or embed it directly in Go — no server at all
go get github.com/srjn45/filedbv2/filedb