gem

CLI commands

bb backup

Dumps the database and streams it to every registered store at once. Nothing is written to disk, so a 40 GB database needs no 40 GB of scratch space.

$ bundle exec bb backup
Boring Backup  db_production
 s3     2.1 GB in 48.3s  → /database/db_production/2026/07/29-03-00-04-812.dump
 r2     2.1 GB in 51.7s  → /database/db_production/2026/07/29-03-00-04-812.dump

Backed up to 2 store(s).

On an interactive terminal a live meter shows bytes dumped, throughput and elapsed time while it runs. Under cron or CI the meter is skipped and only the result is printed.

outcomeexitmeaning
success0every store took the dump
partial_success1at least one store took it, at least one failed
error1the dump itself failed, or no store accepted it

A failed dump deletes whatever it already uploaded. A stream that dies halfway leaves a truncated file that looks like a backup and restores like garbage, so the gem removes it rather than leave it in the bucket.

bb doctor

Answers the only question that matters before 3am: is this silently not working? Run it on the machine that runs the backups, with the same credentials and the same environment.

$ bundle exec bb doctor
Boring Backup  doctor · production
 pg_dump            /usr/lib/postgresql/17/bin/pg_dump
 versions           pg_dump 17, server 17
 database           db_production
 stores             1 registered
 s3                 s3://db-backups eu-central-1
 scheduler detected solid-queue: config/recurring.yml

Everything checks out.

What each check looks at:

checklooks at
pg_dumpan executable pg_dump on PATH
versionsthe client major version against SHOW server_version. A client older than the server fails the check, because the dump it writes may refuse to restore
databasethat a database name resolves from config, ActiveRecord or the environment
storesthat at least one store is registered
one row per storethat the store validates: bucket set, credentials paired, storage class recognised, endpoint present for R2
scheduler detectedconfig/recurring.yml or config/schedule.yml mentioning BoringBackup::BackupJob

A marks a check that could not run, such as a server version it could not read. Skipped checks do not fail the command. Any exits 1, which makes bb doctor usable as a cron canary or a CI step.

bb install

Interactive setup, covered in full on installation. Safe to re-run: it reports files that are already correct and leaves them alone.

Running from cron

With no Rails scheduler in the app, run the command directly. It exits non-zero on failure, so cron mail and CI both notice.

0 3 * * *  cd /srv/app && bundle exec bb backup

Further reading