# Architecture

> How Resta works inside: five services behind one domain, how requests flow, where data lives, and how much one server holds.

Source: https://resta.dev/docs/architecture · Updated 2026-11-01

**A Resta server is five containers from one Docker Compose file: a gateway that serves everything on one domain, the dashboard, an API, a data node that holds the databases, and Postgres for metadata.** Apps query the node directly through the gateway; the API never sits in the query path.

## Services

| Service | Role | Data |
|---|---|---|
| `gateway` | Caddy. Routes `/v1` to the API, `/db` to the node, everything else to the dashboard. TLS. | `caddy` volume |
| `dashboard` | Static web UI. | none |
| `api` | Account, API keys, database list, tokens, backup requests. | `keys` volume |
| `node` | Stores and serves the databases; takes snapshots. | `dbdata`, `backups` volumes |
| `postgres` | Metadata for the API. | `pgdata` volume |

## Request flow

1. Your backend calls `POST /v1/databases` with an API key. The API records the database in Postgres and asks the node, over the internal network, to create its directory.
2. Your backend calls `POST /v1/databases/{name}/tokens` and receives a signed JWT.
3. Your app sends SQL to `https://<server>/db/<id>/v3/pipeline` with that token. The gateway forwards it to the node, which checks the signature with the public key and runs the SQL.

## Storage

Each database is its own directory on the node, holding a SQLite-format file and its write-ahead log. A database that was created but never written is just the directory. Databases open on first use and close after 5 minutes idle; at most 10,000 are open at once by default. Each database has one writer at a time; different databases write in parallel.

Commits are synced to disk before they are acknowledged. In testing, every acknowledged write survived the node being killed with `SIGKILL`, and the database passed `PRAGMA integrity_check`.

## Capacity

These are estimates, not load-test results:

| State | Cost |
|---|---|
| Created, never written | A Postgres row and a directory |
| Written, idle | Its files on disk; small databases are tens of kilobytes |
| Open | About 2 file handles and some engine memory |

A small VPS should hold tens of thousands of databases with a few thousand open at once. The first limit to expect is the backup pass, which checks every database on each run; at the hourly default there is a lot of headroom.

## Limits of the design

- One node on one machine: no replication or failover.
- The node restarts during upgrades.
- The default backup target is on the same disk as the data.
- Postgres needs its own backup.
