Database as Code.

Immutable transaction files inside a Git repository. No global locks. Deterministic concurrency. 100% Audit trail.

Core Capabilities

Git-Native

Database transactions are stored as standard Git objects. Every write is a commit, every sync is a push.

SQLite Sidecar

Reads are served from a materialized SQLite index. Get the write speed of append-only logs with the query power of SQL.

Tamper-Evident

Built on a Merkle DAG. Every state change is cryptographically linked to its parent. History cannot be rewritten without detection.

Offline-First

Writes occur locally and sync asynchronously. The system is designed for partition tolerance and eventual consistency.

Strict Schema

Enforce structure with JSON Schema. Writes are validated before they hit the ledger, ensuring data quality at the source.

Atomic CAS

Concurrency is handled via optimistic locking (Compare-And-Swap) on the Git reference. No global locks required.

Quick Start

Git-native ledger with a SQLite sidecar index.

# 1. Build
$ make build

# 2. Init repo (sharded + append history)
$ ledgerdb init --name "LedgerDB" --repo ./ledgerdb.git \
    --layout sharded --history-mode append

# 3. Apply schema
$ ledgerdb collection apply tasks \
    --schema ./schemas/task.json \
    --indexes "status,assignee"

# 4. Write data
$ ledgerdb doc put tasks "task_0001" \
    --payload '{"title":"Ship v1","status":"todo","priority":"high"}'

✔ Commit 8a7b9c written._

System Design

History lives in documents/. State in state/. Schema in collections/.

db-root/
db.yaml
collections/
  • schema.json
  • indexes.json
documents/
SHARDED
DOC_<hash>/
  • HEAD POINTER
  • tx/2025..._put.txpb
  • tx/2025..._patch.txpb
state/
LATEST
DOC_<hash>/
  • HEAD POINTER
  • tx/current.txpb

CAS Write Flow

Atomic compare-and-set on refs/heads/main.

1

Read Ref

2

Read HEAD

3

Build Tx

4

Hash

5

Validate

6

Write Blobs

7

Commit

8

CAS

9

Retry

Write Throughput

Writes are O(1) appends. Reads served from SQLite sidecar.

32
Default Max Chain
Append + State — 5000 puts / 2500 updates / 100 deletes
Amend + State — 2000 puts / 400 updates / 100 deletes
State Watch 250ms — 1000 puts / 200 updates / 40 deletes

FAQ

What problem does LedgerDB solve?
LedgerDB is for applications that need auditability, offline-first writes, and easy replication without running a centralized database service. It stores immutable transactions in Git, so teams can reduce infrastructure overhead while keeping a reliable, verifiable history of state changes.
How do reads work (CQRS + SQLite sidecar)?
Git is the write model and source of truth. The SQLite sidecar is a derived read model that can be rebuilt at any time. The indexer tails commits or the state tree and projects documents into tables for fast queries.
What is the state index and why is it fast?
The state tree stores the latest snapshot per document. Indexing in state mode diffs the state tree and applies only changed docs (O(changes)), which makes near real-time updates practical.
What are append vs amend history modes?
Append keeps full history per document (audit trail). Amend stores only the latest state per document (compact). Both can use the state index for fast reads.
Why sharding in the filesystem?
Sharding spreads files across deep directories so large collections stay fast and avoid OS directory limits. It keeps lookup time stable as the dataset grows.
What happens when a push is rejected?
A push can be rejected when the remote advanced (non-fast-forward). The client fetches the new head and detects divergence. If auto-merge is enabled, it rehydrates both histories, applies a deterministic merge policy, writes a merge transaction, and retries the push. If it cannot merge safely, it surfaces a conflict for manual resolution.
Do you need Raft or consensus to be safe?
LedgerDB uses optimistic concurrency with atomic compare-and-set on the Git ref. You can choose a coordinator for single-writer semantics, or layer consensus if strict linearizability is required, but it is not mandatory for correctness.
How is the tree validated during commit?
Each write produces deterministic transaction bytes, hashes them, and updates the stream HEAD pointer. The commit rewrites only the affected paths, then atomically swaps refs/heads/main. If the ref moved, the write is rejected and retried, guaranteeing the committed tree matches the expected parent state.
Is LedgerDB a replacement for Redis or DynamoDB?
Not a drop-in replacement. LedgerDB trades microsecond latency and managed global throughput for auditability, offline-first writes, and decentralized replication. It can be a lower-cost alternative for many workloads that do not need a centralized cloud database.