Backups
Pier backs up databases by dumping them inside the running container, compressing the output, and shipping it to object storage. Backups are configured per service and run on a cron schedule, with retention enforced after every successful run.
Supported engines
Section titled “Supported engines”Backups are available for PostgreSQL (including PostGIS and TimescaleDB), MySQL, MariaDB and MongoDB. Each engine produces a different on-disk format:
| Engine | Dump tool | Stored format |
|---|---|---|
| PostgreSQL / PostGIS / TimescaleDB | pg_dump -Fc (custom format) | .dump (self-compressed) |
| MySQL / MariaDB | mysqldump | .sql.gz (gzipped in Pier) |
| MongoDB | mongodump --archive --gzip | .archive.gz |
PostgreSQL dumps always run as the cluster superuser so extension schemas (e.g. PostGIS tiger/topology) are captured cleanly.
Per-database vs. cluster-wide
Section titled “Per-database vs. cluster-wide”A schedule with a database_name set backs up a single logical database. A schedule with no database name is cluster-wide: for SQL engines it loops over every database it knows about and bundles them into a single .tar.gz (entries named <db>.dump or <db>.sql); for MongoDB it runs one full-instance mongodump.
Restore is per-database only. Cluster-wide tar archives are supported as a source — Pier extracts the one database you’re restoring into — but you can’t restore a whole cluster in one action.
Schedules
Section titled “Schedules”Each schedule stores a cron expression, a retention count and the target S3 storage. Defaults when you create one:
| Field | Default |
|---|---|
| Cron | 0 2 * * * (daily at 02:00) |
| Retention | 7 backups kept |
Schedules are driven by the unified scheduler (see Scheduled tasks) — a backup schedule appears in the Schedules list as a backup action. You can also trigger an ad-hoc run at any time; an ad-hoc per-database run falls back to the cluster-wide schedule’s storage if no per-database schedule exists yet.
Offsite storage
Section titled “Offsite storage”Backups upload to S3-compatible object storage or to Bunny.net. A storage entry holds the endpoint, region, bucket, access key, secret key and an optional key prefix (default pier-backups). Keys are laid out as {prefix}/{service}/{filename}. Use Test to verify the connection before pointing a schedule at it.
Retention
Section titled “Retention”After each successful backup, Pier keeps the newest retention_count completed backups for that schedule and deletes the rest — both the object-storage blob and the database record. A failed cleanup is logged but never fails the backup itself.
Restore
Section titled “Restore”There are two restore paths, both per-database and both destructive — the target database is dropped and recreated, so the target must already exist in the service (its stored credentials supply the owner role and password):
- Restore from a stored backup — downloads the blob from storage, extracts the database from a cluster tar if needed, and replays it via
pg_restore/psql/mysql/mongorestore. - Restore from a direct upload — upload a
.dump,.sql.gz,.tar.gzor.archive.gzfile by hand. This is the cross-cluster disaster-recovery path: it works on a fresh Pier instance with no storage configured. The format is detected from the filename and validated against the target engine.
Backups can also be downloaded as files and deleted individually.
System backup of pier.db + .env
Section titled “System backup of pier.db + .env”Independently of database backups, Pier takes a daily local snapshot of its own state: pier.db and .env are copied into data/backups/system/, timestamped per day, with the last 7 days retained. This protects the control-plane database and encryption configuration; it is not shipped offsite.
Next steps
Section titled “Next steps”- Alerts & notifications — get notified when a backup fails.
- Scheduled tasks — the scheduler that fires backups.
- Access & audit — how database credentials are protected.