What Sirannon promises for the life of your product

You can start with SQLite because it is the simplest option that works. Sirannon then lets you keep SQLite once your product needs replication, backups, or a server.

You can keep the same database from your laptop to your cluster

Sirannon can open your database as a file on your laptop, serve that same file over HTTP and WebSocket from its own server, or replicate it across a cluster of nodes that fails over through a coordinator. The query code that you write on the first day can stay unchanged when you move to a cluster, because you change only the configuration as your product grows.

Read the getting started guide
One codebasethree deployments
const db = await sirannon.open('app', path)

Laptop

one file on disk

app.db

Server

HTTP and WebSocket

4 readers

Cluster

three nodes with failover

coordinator
The line above stays the same in all threeno rewrite

You can restore a terabyte to any moment that you name

Sirannon copies the whole database on the first backup, after which it sends only the write-ahead log frames that SQLite wrote since the previous backup. When you name the moment that you want back, Sirannon rebuilds the database from the full copy and every piece of change that it captured up to that moment. During a restore, Sirannon fetches one piece and applies it before it requests the next, so it holds only one piece in memory however large the database is.

Read the restore guide
Backup chainrestore to 14:02
02:00Full copy1.0 TB
06:00WAL frames412 MB
10:00WAL frames96 MB
14:00WAL frames233 MB
14:02Rebuilt to this momentone piece in memory
Every piece up to 14:02 replays in orderrestoreBackup

Every customer and every AI agent can have their own database

A resolver maps any identifier to a file path, so Sirannon opens a database for a new customer or a new AI agent the first time that your code requests it, with no provisioning call. The lifecycle manager closes idle handles and evicts the least recently used one once the open count reaches your cap, which lets the number of files on disk grow while the number of open handles stays where you set it. Sirannon applies your migrations to each database as it opens the file, so the database of a tenant that you add long after the last schema change still opens on the current schema.

Read the lifecycle guide
Instancescustomers and AI agents

brightwood-legal

data/tenants/brightwood-legal.db

4 connsActive

drafting-agent-04

data/ai-agents/drafting-agent-04.db

2 connsActive

patel-associates

data/tenants/patel-associates.db

12 minIdle

volta-tours

data/tenants/volta-tours.db

freedEvicted
Opening a file is what creates oneLRU eviction

An AI agent or a browser can reach only the operations that you register

By default, a Sirannon server executes only the statements that you register, each under a name. A caller sends that name with its arguments, so it can reach only the tables and columns in the named statement. Each statement accepts only the arguments that you declare, so the server rejects a request carrying any other argument with ARGUMENT_NOT_ALLOWED before it passes anything to SQLite. The server takes every tenant identifier from the authenticated identity, so a caller can reach only its own tenant's rows whatever it sends. For trusted service code on a private network, you can allow raw statements again by setting acceptSql.

Read the registered operations guide
Registered operationsAI agent caller
callordersByStatus { status: 'pending' }3 rows
callordersByStatus { tenant: 'other' }ARGUMENT_NOT_ALLOWED
sqlDROP TABLE ordersno SQL accepted
The server holds every statement it may rundigest 40c2fd90

Your application can keep working offline

A device holds its own database file and writes to it whether or not it can reach the server. When the device reconnects, it pushes its own writes and pulls everyone else's over a WebSocket. To settle conflicts, both sides apply the same resolvers that Sirannon uses to replicate between servers. As a result, your application can treat time offline as an ordinary state and keep one data store for online and offline alike.

Read the device sync guide
DeviceOffline
Local writes waiting12
Last pull from the server09:41
Conflicts resolved so far2
Back on the networkpushed 12 · pulled 47
Both sides apply the conflict rules the cluster usespush · pull

You can see every change as it commits

Triggers record every insert, update, and delete as it commits, so clients can subscribe to those changes over a WebSocket. You can then build activity feeds, live dashboards, and cache invalidation on the database itself. After a reconnect, the client SDK restores every subscription automatically.

Read the change data capture guide
Change feedorders, cartsLive
4194deletecarts#92212:04:07
4193updateorders#1837 → paid12:04:05
4192insertorders#1841 → pending12:04:04
WebSocketSubscriptions restore on reconnect

Sirannon sustains four times PostgreSQL's read rate

The benchmark harness drove both engines through their own clients on one machine, at ten million rows, with every commit fsynced. Sirannon held 64.0K point-selects per second against PostgreSQL's 16.0K, while on the YCSB-A mix of half reads and half updates it held 16.0K against PostgreSQL's 1.0K. Every figure is the highest rate that the engine sustained while holding p99 latency under 25 ms.

Read the full benchmark results
Point-select10M rows
Sirannon64.0K
operations per secondp99 6.2 ms
PostgreSQL16.0K
operations per secondp99 2.4 ms
Both engines fsync every commitrun 20260804T221053Z

Try Sirannon on your own data

The documentation covers everything above in depth, starting with the getting started guide.