Butler DB app icon

Production databases on macOS

PostgreSQL and MySQL,
backed up and proven.

Butler DB runs your production databases on your Macs and keeps them safe: scheduled backups to disk, S3 and SFTP, automatic test restores so you know they work, users and grants without the SQL, and every server managed from one app over SSH.

Download for macOS

Latest · Apple silicon · macOS 14 or later

Early release. Keep your existing backups running alongside it.

Backups on a schedule

Full and incremental backups, every incremental taken against the last full, so a restore is always one full plus at most one incremental.

Restores, tested for you

After every scheduled full backup, Butler DB restores it into a throwaway server, recovers it and runs queries against it, so you know the backup works before you need it.

Several places at once

An external drive, any S3-compatible storage (AWS, R2, B2, MinIO) and SFTP to another Mac or a NAS, all at once. Every copy can drive a restore on its own.

Users and access

Create users, change passwords and give each one read-only, read-write or admin access per database. Every level shows the exact privileges it grants.

All your Macs, one app

Save every Butler DB server and manage it over SSH with your own keys and ~/.ssh/config. Group them, give each a name and icon, and see their health at a glance.

Move in from DBngin

Import existing DBngin databases. Only the instance being moved is stopped, it's copied cleanly, and it's checked for collation problems first.

Engines built for production

Our own builds, signed and checksummed, and installed side by side. Installing a new version never touches a running database.

PostgreSQL
1718

Native incremental backups with pg_basebackup and pg_combinebackup. TLS, lz4/zstd, every contrib module, pgvector and pg_cron. ICU pinned per build.

MySQL
8.4 LTS

Hot backups with Percona XtraBackup, which we build for macOS ourselves. Keeps mysqlbinlog and the server tools a production install needs.

Always UTC
timezone=UTC

Every server runs in UTC, set on the engine's command line so no config file can change it. Timestamps mean the same thing on every machine.

How it's built

Butler DB holds your production data, so here's exactly what it does on your Mac.

Each database is its own job

Every database runs as its own launchd job, not as a child of Butler DB. Updating the app, restarting the daemon or a daemon crash never stops a running database.

Root only at startup

Jobs start as root just long enough to set up, then drop permanently to a dedicated _butlerdb account. Data directories owned by anyone else are refused.

No network control port

The app talks to the daemon over a local socket that only administrators can open. Remote servers are reached over your own SSH, so there's nothing new to expose.

Signed engine builds

The engine list is signed, and every download is checked against its SHA-256 before it's unpacked. A tampered list or file installs nothing.

Your data stays yours

Nothing leaves the Mac except the backups you send to your own destinations. Storage secrets stay readable only by the service account and never end up in logs.

Restores never overwrite

A restore always creates a new instance next to the original. It never writes over a database you have.

Scriptable, too

Everything the app does is a butlerdb command, with --json for scripts.

$ butlerdb add shop --engine postgresql --version 18.6 --label "Shop Production" ✓ created shop (postgresql 18.6), slot 1 superuser: postgres password: •••••••••••••••• ✓ shop running on 127.0.0.1:5432 $ butlerdb backup run shop --full --wait ✓ backup 20261004T060000Z-full of shop done $ butlerdb backup verify shop ✓ 20261004T060000Z-full restored from offsite-r2, recovered and answered queries (3 databases) in 41s

Setup

From download to a tested backup in about ten minutes.

Install and approve

Drag Butler DB into Applications and open it. It asks to add its background service; approve it in System Settings → General → Login Items & Extensions. It shows up there as Butler DB.

Add a database, or bring one in

Install an engine from the Engines window, then add a database instance. Coming from DBngin? Import it instead, and keep its data and logins.

Choose where backups go

Add one or more destinations: a drive, an S3 bucket, or another machine over SFTP. Then set each instance's policy: where its backups go, how often fulls and incrementals run, and how many to keep.

Test a restore

Press Test Restore. Butler DB restores the newest backup into scratch space, recovers it and queries it. Scheduled fulls are tested automatically after that.

Add your other Macs

Install Butler DB on each server Mac. Make sure ssh <host> works from your Mac with a key, logging in as an administrator on the server. Then use Add Server. Hosts from ~/.ssh/config work as-is.

Requirements

  • A Mac with Apple silicon on macOS 14 or later
  • An administrator account to approve the background service
  • PostgreSQL 17 or 18, or MySQL 8.4
  • For remote servers: Butler DB installed there, and SSH key access

Good to know

  • FileVault: after an unplanned restart, the Mac waits for a password before any database starts. For planned restarts, sudo fdesetup authrestart skips that.
  • Not supported: PostgreSQL 16 and older, MySQL 5.7, MariaDB.
  • Coming later: point-in-time recovery, then replication and automatic failover.
  • Single machine is fine. Each database shows that it isn't replicated, but nothing is blocked.