WARP.FIELD// 0xSTATIC

WARP

Bending the Fabric of Time v0.1 ▌

One entity. One stream. One writer. Everything that happened — and the present as a side effect.

The event-native database — .warp segments, one static binary, zero dependencies.

1.3M crash-durable writes/s4.1M across 8 cores3.1M reads/s0 dependencies
account / aliceseq 0
...waiting for the first fact
↳fold( events )state()
{ balance: 0, currency: "USD" }
$0.00 — derived, cached, never authoritative
THE.PROBLEM// 0xACCRETE

You didn't want a query engine. You wanted your app's history.

Watch the diagram. Every database stores where you are — and then you spend a year bolting on where you've been.

stage 01
You needed a database.
You reach for Postgres. Fine — it's a good database. Two systems online: your app, your store.
stage 02
Now you need an audit log.
An audit_log table, triggers to fill it, and a policy for when it lies. The triggers fire on some code paths. Not all of them.
stage 03
Now the frontend wants real-time.
So: CDC into Kafka into a websocket gateway. Congratulations, you operate a pipeline now. It has opinions about ordering.
stage 04
Now legal wants deletion.
A hard DELETE loses history, so you ship deleted = true. 'Deleted' data now lives on in every backup, forever. Your DPO is not thrilled.
stage 05
Now half your domain is events anyway.
Orders placed. Payments settled. Sessions opened. You add event tables — hand-rolled, unindexed, one shape per team.
exit
Or: store what happened.
One system that is the audit log, is the pipeline, is the history — and can physically forget. These aren't features bolted onto warp. They're what warp is.
field.topologystage 01
SYSTEMS ONLINE02your appPostgresaudit_logvia triggersCDCDebeziumKafkaws gatewaybackups∞ copiesevents_*hand-rolledwarp.warp segmentsA CLEAN START
CORE.MODEL// 0xARCH

Opinionated about how you store. Silent about what.

Three ideas. Each one is running live below — poke it. The stream you build in the second station is the one the third station folds.

◉

Entity

the unit of everything

One account, one document, one agent owns its stream — a single writer, its events totally ordered. No global write lock: entities shard across cores (8 by default), so writers on different shards run in parallel. Same-shard writers serialize briefly; there's no lock to configure and never a global one.

one table · one write lockeveryone else waits
acct/a▮ holds lock — writing
acct/b… queued
acct/c… queued
acct/d… queued
acct/e… queued
acct/f… queued
ops committed0
sharded · hash routes entitiesshards run in parallel
shard 0
acct/a▮ writingseq 0
acct/b… waitingseq 0
shard 1
acct/c▮ writingseq 0
acct/d… waitingseq 0
shard 2
acct/e▮ writingseq 0
acct/f… waitingseq 0
ops committed0
▤

Event

the only write

You don't UPDATE a row, you append a fact — into a .warp segment, warp's own append-only format. Press the buttons. Both worlds get the same write.

UPDATE worldstate is the storage
balance = 11,500
what was it before? destroyed on write.
reconstruct last Tuesday? you can't.
APPEND worldstorage is the history
11,500
03deposited{ cents: 4_500 }
02withdrew{ cents: 3_000 }
01deposited{ cents: 10_000 }
what was it before? stateAt(n) — any n.
same writes. nothing forgotten.
one write, two worlds — watch what each remembers
▣

Fold

the derived present

State is fold(events) — and so is every view. Three read-models, one truth, all live. Drag n and all three agree about the past.

Account.view(sum)
11,500
Account.view(count)
3 events
Account.view(series)

▸Optimistic concurrency

expect: 3 throws on a conflicting write. No lost updates, no locks.

▸Real-time

subscribe(cb) pushes live folded state, in-process — no pipeline.

▸Views

Cross-entity aggregates declared once, materialized, kept live.

▸Sagas

Multi-entity transactions with automatic compensation.

▸Time-travel

stateAt(n) for any n. The whole history is the storage.

▸Physical erasure

erase() rewrites the segment without the entity.

FRAME.NATIVE// 0xVIDEO

A video is an append-only log of frames.

So it's already a warp entity. Frames are events, playback is history(), and dragging the scrubber is literally stateAt(n) — seek to any frame, exactly.

video/clip · seq 0/0
frame events● recording
…waiting for the first frame
each frame = one event · scrub = stateAt(n) · playback = history()
CODE.WALK// 0xTS

From zero to an audited ledger in six steps.

Scroll. The panel follows. No schema.sql, no manual JSON, no stringly-typed event names.

app.ts1 / 6
import { warp, reject } from "@geeksquad/warp-embedded" const Account = warp.entity("account", {  state: { balance: 0, currency: "USD" },  events: {    opened:    (s, p: { currency: string }) => ({ ...s, currency: p.currency }),    deposited: (s, p: { cents: number })   => ({ ...s, balance: s.balance + p.cents }),    withdrew:  (s, p: { cents: number })   => ({ ...s, balance: s.balance - p.cents }),  },  commands: {    // atomic fold → check → emit; a reject writes nothing    withdraw: (s, a: { cents: number }) =>      s.balance < a.cents ? reject("insufficient funds") : [{ type: "withdrew", payload: a }],  },})
step 01
Define the entity
Events are the methods. state is where the fold begins. No schema.sql, no stringly-typed event names — payload types are inferred from the reducers.
step 02
Open the store
In-process, zero dependencies. Pick a durability tier — no daemon, no server, no connection string.
step 03
Append
alice.deposited(...) autocompletes to exactly what an account can do. A typo is a compile error, not a 3am incident. Synchronous — no await, no pool.
step 04
Read the present
Folded and cached — 3.1M reads/sec, a property lookup rather than a query, and they don't degrade while writes are landing.
step 05
Subscribe and aggregate
Real-time is a primitive, not a pipeline. Views are declared once and kept live automatically.
step 06
Travel, and forget
Every past is addressable. And erase() rewrites the segment without the entity — real right-to-be-forgotten, not a boolean column.
BENCHMARKS// 0xPERF

Same machine. Same 80-byte record. Same workload.

One M1 (arm64) laptop for every figure below — warp against SQLite, its fair embedded peer. Both crash-durable, both single-op, no app batching. Every number measured this pass, nothing carried over.

engine
writes/sec — linear scale
relative
#1
warpembedded event log
0baseline
#2
SQLiteembedded relational (WAL)
01/11 of warp
Single thread, one op at a time, no app batching — both crash-durable (survive a process crash: SQLite WAL synchronous=NORMAL, warp mmap-append). warp memcpy's each event into a mapped segment; SQLite runs a full autocommit per row. Roughly 11×.
Add cores. Watch who scales.
warp shards — writers on different entities run in parallel. SQLite has one global write lock, so it stays flat no matter how many cores you give it.
0×warp vs SQLite
warpsharded
1,460,000/s
SQLiteone write lock
114,000/s
1 core1 core
Crash-durable writes, measured on an 8-core M1. Every point on the warp curve is a real number; SQLite's is a single lock, so it never moves.
Pick your guarantee

Measured with real macOS F_FULLFSYNC — a true on-platter flush, not a page-cache promise.

0writes/sec
Each write is memcpy'd into an mmap'd segment — the bytes are in the kernel page cache before the ack, so a process crash loses nothing. Same guarantee as SQLite WAL synchronous=NORMAL, ~11× the throughput.
EngineCommits/secSync
warp — power-durable (group F_FULLFSYNC)1,200,000full flush per batch — survives power loss
warp — crash-durable (mmap, no fsync)1,300,000process-crash safe; power loss can lose the tail
SQLite (WAL, synchronous=FULL)11,500fsync per commit
warp — strict (F_FULLFSYNC per single event)~220one full drive-cache flush per event — the honest floor

Three tiers, and the honest floor. warp's group-commit modes stay over a million/sec — crash-durable (mmap, process-crash safe) and power-durable (F_FULLFSYNC per batch, power-loss safe). But if you force a full drive-cache flush on every single event with no batching, warp drops to ~220/sec — slower than SQLite's per-commit fsync. That's not a mode you'd run; it's published so the durability claim can't be called a bluff. Group commit is the design.

AND.NOT.JUST.WRITES// 0xMORE
1.3M writes/s
Crash-durable single appends — no batching, survives a hard crash. 11× SQLite's equivalent.
4.1M writes/s
Across 8 cores — sharded, crash-durable. 37× SQLite, which can't scale writes past one lock.
3.1M reads/s
Folded state served from RAM — a property read, not a query. 6× SQLite.
2.0M ops/s
A realistic 90/10 read-heavy feed, mixed. Reads don't degrade under write load.
Built in
History, time-travel, live subscriptions, physical GDPR erase — the engine, not add-ons.
HA + scaling
Ownership routing + warm replicas over the network. Fixed-size clusters scale ~linearly.
THE.TRADE// 0xHONEST

We won't tell you warp is the fastest database, full stop. It isn't a relational engine and doesn't pretend to be.

warp drops ad-hoc SQL — you pre-declare the queries you need as views — and multi-table ACID, leaving you single-entity atomicity plus sagas. In exchange, the ~90% of an app that is entities changing over time, read live, runs an order of magnitude faster, with audit, real-time, history and erasure that the others make you build and then maintain forever.

If you need a six-table join with a window function next Tuesday, keep Postgres for that. For what your product's core loop actually does all day, warp is faster and does more.

warpSQLiteLiteFS
Modelevent streams per entityrelational (embedded)SQLite + replication
On-disk format.warp append-only segments (mmap)B-tree pages + WALSQLite pages over FUSE
Crash-durable write1.3M/sec116K/sec≈ SQLite
Concurrent writes (8 cores)4.1M/sec — shardedone write lock, no scalingone primary
Reads (folded / cached)3.1M/sec516K/sec (B-tree SELECT)read replicas
History / auditbuilt inDIY (triggers)DIY
Real-time subscriptionsbuilt innonenone
Time-travelbuilt inDIYDIY
Physical erasure (GDPR)built inVACUUM-dependentDIY
HA / replicationbuilt in — ownership + replicasnoneprimary + replicas
Ad-hoc SQL / joins✗ pre-declared views✓✓
Dependencieszero — one dylib, in-processlibsqliteGo + FUSE
WARP.DEPLOY// 0xFLY

Self-hosted Durable Objects.

One entity lives in exactly one place, owned by one writer — the model Cloudflare made everyone want, minus the proprietary runtime. One primitive, three ways to run it.

01

Embedded

Link the engine, store to local .warp files. Zero network, zero processes to supervise. warp.open() and go — no daemon, no server, no connection string.

02

HA + scaling

Add peers. Each node is the single writer for its hash-slice of entities and fire-and-forwards every write to warm replicas over the private network; a failover is instant because the replica already has the events. Ownership routing lives in the SDK — owner_of / isOwner.

03

Polyglot

Under the hood it's a C-ABI dylib, so any language with an FFI can embed it. Ships today with a full TypeScript SDK; the entity/command API is the same everywhere.

clientANY REGIONfly-replayKEY = ENTITY IDmachineSOLE WRITERsegmentAPPEND + SHIPENTITY "ALICE" — ONE PLACE, ONE WRITER, ALWAYS
the routing key is the entity id
ON.FLY// 0x6PN
  • ▸One dylib, in-process. No daemon, no FUSE, no kernel modules, no sidecar. Link it into your app — a couple of megabytes — and store to a Volume.
  • ▸Fixed-size clusters scale linearly. N Machines, each a warp instance owning a hash-slice of entities. Route each write to its owner; aggregate write capacity grows ~linearly per Machine, because each writes its slice fully in-process.
  • ▸Warm replicas, instant failover. The owner fire-and-forwards each write to R replica Machines over the 6PN private network. A Machine dies, a replica already holds the events — no cold restore.
  • ▸Crash-durable across restarts. Autostop is safe: an acked crash-durable write is in the mmap'd segment's page cache, so it survives the process going down and comes back on wake.
  • ▸Per-tenant Machines. Each holds its own .warp segments and naps when idle, waking sub-second. Durable-Objects economics, on infrastructure you control.
warp — durable, on-platter
1.2M
writes/sec, F_FULLFSYNC group commit
LiteFS — published figure
100
transactions/sec

Same job, different engine. LiteFS ships SQLite pages over FUSE. warp has no SQLite in it — it's.warp append-only segments in a single static binary. Four orders of magnitude apart. Per-machine throughput on Fly isn't quoted here; that number goes up when it's measured on the platform, not before.

WHO.FOR// 0xFIT

Built for domains that were always event-shaped.

SaaS platforms

doc.edited({ span })

Users, orgs, sessions, documents, billing. Real-time collaboration and audit trails arrive with the storage engine.

Fintech & ledgers

ledger.settled({ batch })

An append-only log is a ledger. Sagas are transfers with compensation. History is non-negotiable and already there.

Agent & AI memory

agent.remembered({ ref })

Durable, replayable, per-entity streams are the substrate agent memory keeps trying to reinvent badly.

Anything real-time

presence.joined({ room })

Chat, presence, live dashboards, multiplayer. Subscriptions are a primitive, not a pipeline you operate.

Edge & per-tenant apps

tenant.woke({ region })

One binary, one volume, entity-affine, region-routable. Tenants that nap when idle and wake sub-second.

Anything with a DPO

user.erase() // Art. 17

Erasure is physical. You answer an Article 17 request with a function call instead of a project.

FAQ// 0xASK

The questions a skeptic actually asks.

Single-entity commands are atomic and enforce invariants under one lock — no overdrafts, no lost updates (the classic ‘15 debits on a balance of 10, exactly 10 succeed’ is structurally guaranteed). Cross-entity work uses sagas: completed-step compensation, eventually consistent. If a slice of your domain needs strict multi-row serializable transactions, pair warp with Postgres for that slice.
Three tiers you pick per database. Buffered (fastest, ~4ms crash window). Crash-durable — each write is memcpy'd into an mmap'd segment, so an acked write survives a process crash; same guarantee as SQLite WAL synchronous=NORMAL, ~11× the throughput. Power-durable — F_FULLFSYNC per flush, survives power loss, still over a million/sec. Verified with a hard-kill test: crash-durable writes replay exactly on reopen.
For writes and folded reads, yes — measured on one machine: 1.3M crash-durable writes/sec single-threaded (11× SQLite), 4.1M across 8 cores (37×, because SQLite has one global write lock and can't scale writes with cores), 3.1M cached reads (6×). warp is an append-only log, so a write is a memcpy; SQLite maintains a queryable B-tree, which is dearer per write but buys you ad-hoc SQL. Different tools, honestly.
Not ad hoc — that's SQLite/Postgres's job. You declare the views you need; they're folded from the log and kept live. Genuinely exploratory analytics belong in an analytics store.
Ownership = fnv1a(entity) % nodes: each machine is the single writer for its slice, and the owner replicates every write to warm standbys. Your gateway routes writes to the owner (owner_of / isOwner ship in the SDK). Fixed-size clusters scale ~linearly; for the common case, run one primary + read replicas, LiteFS-style. No daemon to operate.
warp is new; SQLite is decades of hardening. It's embedded and zero-dependency, so you can adopt it for one service — an event log, a ledger, agent memory — alongside what you already run, instead of a rip-and-replace.
QUICKSTART// 0xNPM

One install and a reducer.

# in-process, no daemon, no server
npm i @geeksquad/warp-embedded
import { warp, reject } from "@geeksquad/warp-embedded"

const Todo = warp.entity("todo", {
  state: { title: "", done: false },
  events: {
    created:   (s, p: { title: string }) => ({ ...s, title: p.title }),
    completed: (s) => ({ ...s, done: true }),
  },
  commands: {
    // validated intent — a reject writes nothing
    complete: (s) => s.done ? reject("already done") : [{ type: "completed" }],
  },
})

const db = warp.open({ entities: { todo: Todo }, durability: "crash" })
db.todo("t1").created({ title: "ship it" })
db.todo("t1").complete()   // command: atomic, guarded
BEGIN// 0xSTART

Store everything that happened.
Get the present for free.

One entity. One stream. One writer. Nothing to bolt on later.

END.TRANSMISSION // 0xFFFF ▌warp v0.1.0 — Bending the Fabric of TimeTHE GEEKSQUAD