Distributed SQL on an object store

Strict transactions.
Disposable compute.
One bucket.

Gauntlet is a distributed SQL database built on the Turso engine. Run strictly serializable transactions across shards, connect over PostgreSQL wire or HTTP, and keep durable state in your own object-store bucket.

Start for free

SQLite-family SQL · PostgreSQL wire protocol · HTTP JSON · pre-beta, read the limits

Agents and appsPostgreSQL wire · HTTP
node n1owner · cache only
node n2standby · cache only
node n3killed · nothing lost
One durable bucketjournals · decisions · checkpoints
A write is acknowledged only after the bucket holds what recovery needs. Nodes keep caches, never the only copy. Illustration, not live data.

One order for your transactions.

Every transaction is strictly serializable, including ones that span shards of a database. It is the default and the only isolation level.

Transaction guarantees

Nothing durable on the nodes.

An acknowledged write is in the bucket. Memory and local disk are caches. Lose every node and you have lost nothing.

The durability boundary

No work while released.

An idle database is released after 30 seconds and makes no bucket requests. It keeps its bytes and nothing else.

Scale to zero

Database per agent

Give every agent its own database.

Keep each agent's state behind its own SQL boundary and its own token. Create, use and release databases as work comes and goes. One agent's mistake cannot reach another agent's rows.

  • The database is the unit of isolation. A token opens exactly one.
  • Listing a fleet never wakes a database.
  • Shown at 1,000 databases on one deployment. Coming · P10.25 qualification at one million.
Shell
# One database per agent. Each gets its own token.
gauntlet admin create-database agent-7f3a > agent-7f3a.json
gauntlet admin token agent-7f3a

# Idle for 30 s: released. No bucket requests until its next query.
DatabasesIllustration
DatabaseAgentTenantEnvState
agent-7f3asupport-triagenorthwindprodServing
agent-91c2invoice-readernorthwindprodIdle
agent-0b5eresearchtailspinprodIdle
ci-run-4471—internalciActivating

Labels and a paged fleet listing are Coming · P10.53. The console preview shows the design on sample data.

How it works

Keep the bucket. Replace the compute.

Any node accepts any query and routes it to the database's current owner. There is no control plane in the query path and no member list to maintain: nodes find each other through leases in the bucket.

  1. Commit. The owner writes the transaction to the shard's journal in the bucket with create-if-absent. Two writers can never both win a slot.
  2. Across shards. Prepare on each shard, one write-once decision object, then resolve. Atomic and isolated.
  3. Acknowledge. Only now does the client get its answer.
  4. Lose a node. Another node takes over its databases from the bucket. A fenced old owner cannot write.

The trade: commit latency follows your bucket. Put the bucket next to the nodes. Limits

A transfer across two shards
BEGIN;
UPDATE accounts SET balance = balance - 5 WHERE id = 1;  -- shard A
UPDATE accounts SET balance = balance + 5 WHERE id = 2;  -- shard B
COMMIT;  -- atomic and isolated across both shards

-- 40001: a conflict. Roll back and retry the whole transaction.
-- 40003: outcome unknown. Look the transaction up before doing anything else.

Connect with familiar tools

SQLite SQL. PostgreSQL wire. HTTP access.

Use psql, psycopg, node-postgres or pgjdbc, or send JSON over HTTPS. The wire protocol is PostgreSQL's. The SQL is the SQLite family, so write SQLite-style statements, not PostgreSQL ones.

  • SCRAM-SHA-256 and TLS on every listener.
  • What works and what is refused, with the error code for each.
  • libSQL client compatibility and certified ORMs: Coming · P10.2
psql
# The database token is the password. Any user name works.
PGPASSWORD=$GAUNTLET_DATABASE_TOKEN psql \
  "host=n1.example.net port=7151 dbname=app user=app sslmode=verify-full sslrootcert=ca.crt" \
  -c "SELECT 1"
curl
curl --cacert ca.crt \
  -H "Authorization: Bearer $GAUNTLET_DATABASE_TOKEN" \
  -H 'Content-Type: application/json' \
  https://n1.example.net:7101/db/app/sql \
  -d '{"sql": "SELECT 1"}'

Scale-to-zero economics

Idle databases keep their data, not running work.

A released database makes no bucket requests. Its incremental idle cost is its stored bytes. The first query afterwards activates it again, so that query is slower.

Serving

A node owns the database and answers queries. Commits wait for the bucket.

Idle · released

No owner. No polling. No bucket requests. Healthy, and not "down".

Activating

A node loads it from the bucket and serves the request.

This is the database's own footprint. A machine you run, an allocated node and the bucket's storage bill are separate. Pricing model

Bring your own bucket

Your bucket. Your cloud.

One dependency: a bucket that passes qualification. Support is decided by gauntlet qualify, not by the presence of an S3-compatible endpoint. Every node start runs the same checks, and a bucket that fails is refused.

Needed: atomic create-if-absent, read-after-write consistency and a strongly consistent, ordered LIST, in a single region.

Bucket providerStatus
TigrisRun by the project
Cloudflare R2Run by the project
AWS S3Unverified Coming
Google Cloud StorageUnverified Coming
Managed Gauntlet Cloud, packaged BYOCComing

On the roadmap

Explore a branch. Restore to an exact transaction. Coming

Copy-on-write branches Coming · P6.8

Fork a database with no data copied, let the work run, then keep the child or drop it. A fork by copy comes first. No automatic data merge is promised.

Restore to a transaction ID Coming · P10.17

The journal is already the log. Restore to one exact cut across all shards, always into a new identity. Today a backup is one whole image.

Neither is available today. Read the roadmap

Check the guarantees

Read the guarantees. Check the evidence.

Correctness

Fault-injection tests, deterministic simulation and bounded TLA+ models gate changes to the commit and recovery protocol.

Engineering evidence over limited compositions. Not an independent audit.

Fleet

Activation on first request and release when idle, shown on a deployment of 1,000 databases.

Not a million-database service. Larger qualifications are planned.

Readiness

The beta acceptance run (three hosts, node kills, 48–72 hours of load, a restore drill) exists as a test driver.

It has not passed yet. That is why this is pre-beta.

Sourced comparison Limits and known gaps

Start with one database. Build a fleet.

Join the waitlist for a pre-beta build, or hand the prompt to your coding agent and let it read the docs. The console preview runs on sample data, with nothing to sign up for.

Start for free

Open the console preview