Settings → Storage has one button each: Provision Postgres database sets DATABASE_URL, Provision object storage sets six S3_* variables, and running commits restart so the values reach the app. From an agent: provision_postgres and provision_storage, both idempotent.
What is injected
| Backend | Variables | Notes |
|---|---|---|
| Postgres | DATABASE_URL |
a postgresql:// URL; Postgres 18, one database per project |
| Object storage | S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY, S3_REGION, S3_FORCE_PATH_STYLE |
path-style addressing: switch that option on in your S3 client |
Neither reaches a static site: the nginx presets run no server (deploy).
Connection pools and the pause
An app that gets no request for a while is paused and resumes on the next one. The connections it held open do not survive the pause. A pool does not notice: the first statement on a pooled connection fails once with server closed the connection unexpectedly, and the next one works. Tell the pool to test a connection before it hands it out:
| Client | Setting |
|---|---|
| SQLAlchemy | create_engine(url, pool_pre_ping=True) |
| psycopg_pool | ConnectionPool(url, check=ConnectionPool.check_connection) |
| Django | "CONN_HEALTH_CHECKS": True, needed only when CONN_MAX_AGE is not 0 |
A connection opened per request is not affected. Nothing in DATABASE_URL can switch the test on, so it is a line of your code.
Console and SQL from an agent
The project page's database console opens read-only every time; write mode is a separate switch, and a destructive statement asks for a typed confirmation.
Agents get two tools on the project's own credentials:
query_sqlruns one read-only statement (SELECT,WITH,EXPLAIN,SHOW,TABLE,VALUES) in a read-only transaction: at most 500 rows, 5 seconds.execute_sqlruns writes and schema changes, up to 25 statements in one transaction, all or nothing. A project can require approval first (Settings → Agents).
The bucket
The object explorer browses by folder and takes drag-and-drop uploads. Agents have list_objects, one folder level at a time, and upload_object, one file from base64 bytes, overwriting an existing key. 100 MiB per file.
An optional disk
Separate from both: Mount path in Settings → Storage, empty means off. Each commit has its own data. Seed previews from served commit copies the served commit's disk into every preview at boot, doubling disk per preview; leave it off for a stateless app.
Restore points
A restore point is a snapshot of the production commit's data, picked from a list, newest first; no arbitrary second.
- Snapshot now, every plan;
snapshot_nowfrom an agent, one per 10 minutes per project. The newest 5 manual points are kept. - Daily restore-point ladder is paid plans only, opt-in per project, newest 7 kept.
- When you promote an older commit, the dialog offers Keep current data or Restore point. The second puts the data back and loses everything written since; it asks for a typed confirm word, keeps a safety copy and offers Undo.
rollback_commithas the same modes,keep_data(default) andrestore_data.
Limits
- One database and one bucket per project; no choice of Postgres version, no extension list, no pooling, no replicas.
- No point-in-time recovery, only discrete restore points.
- No Redis, no queues.
- No object delete over MCP.
- Public alpha: restore points are not a backup strategy. Keep your own.