# The bucket is the database

> Status: Available. One object-store bucket holds everything durable. Nodes are disposable compute that recover from it.

Gauntlet has one durable component: an S3-compatible bucket. Memory and local disk are caches. A node that dies is replaced by starting another one against the same bucket and prefix.

## What an acknowledgement means

A write is acknowledged only after the bucket holds what recovery needs. This is the default and, today, the only mode. There is no acknowledgement from memory, from a local disk or from a peer.

That has two consequences worth planning for:

- **Losing every node loses nothing.** Start nodes against the same bucket and prefix and the databases are there.
- **Commit latency follows the bucket.** Each commit waits for conditional writes to the bucket. Put the bucket next to the nodes.

A per-database *peer-durable* mode, which would acknowledge on peers and upload afterwards, is designed but not built. Bucket-only stays the default.

## What is in the bucket

- **A journal per shard**, written with create-if-absent. Two writers can never both win the same slot.
- **Ownership barriers** that fence an old owner once a new one takes over.
- **Write-once decision objects** for transactions that span shards.
- **Checkpoints**, so recovery does not replay the whole journal.
- **Leases**, through which nodes discover each other. There is no member list to maintain.

## What a node is

`gauntlet serve` is the only server process. Each node:

- accepts PostgreSQL wire and HTTP connections for **any** database;
- owns some databases' shards at a given moment and routes requests for the others to their owners;
- keeps a bounded, verified block cache on local disk. The cache is rebuilt from the bucket if it is lost.

Normal SQL does not pass through a control plane. There is no control plane in the query path.

## What the bucket must provide

More than the S3 API: atomic create-if-absent (`If-None-Match: *`), read-after-write consistency and a strongly consistent, ordered LIST. `gauntlet qualify` checks this, and every node start runs the same checks. A bucket that fails is refused. See [deploy and qualify a bucket](https://gauntlet-db.stavros.xyz/docs/operations/deploy.md).

The bucket is **trusted**: Gauntlet does not encrypt or sign its objects. Scope the bucket key to that bucket, and never set lifecycle or expiry rules on the prefix.

## Failure, in one table

| Event | What happens |
|---|---|
| One node is killed | The other nodes take over its databases through normal recovery |
| All nodes are lost | Nothing is lost. Start nodes against the same bucket |
| The local cache disk is lost | Nothing is lost. The cache is rebuilt |
| The bucket is unreachable | No node can commit. `/ready` turns 503. More nodes do not help |

No failover time is guaranteed in pre-beta. See [node failure and recovery](https://gauntlet-db.stavros.xyz/docs/operations/failover.md).

## Evidence and its limits

The commit and recovery protocol is checked by fault-injection tests, deterministic simulation and bounded TLA+ models, which gate changes to the engine. These check limited compositions. They are engineering evidence, not an independent audit and not a proof about arbitrary deployments.

---
Source: https://gauntlet-db.stavros.xyz/docs/concepts/architecture
