How to back up Neon Postgres to Amazon S3
RESTORE-TESTED · ENCRYPTED · IN A BUCKET YOU OWN
Neon keeps your database running, but its snapshots live in the same account and region as the database itself. An off-site copy in your own Amazon S3 bucket protects you from the failures the platform can't: a bad migration, a locked account, or a compliance question you need a real answer to. Here's how to set it up in a few minutes — and, crucially, how to know the backup actually restores.
Step 1 — Get your Neon connection string
Neon Console → your project → Dashboard → Connection Details.
Neon gives you a pooled and a direct (unpooled) connection string. Use the direct endpoint for backups — the pooled endpoint runs PgBouncer in transaction mode, which pg_dump can't use. Neon requires SSL, so keep ?sslmode=require on the URL.
A read-only role is all you need. The exact CREATE ROLE SQL is on the security page.
Step 2 — Create a Amazon S3 bucket and access keys
- In the S3 console, create a bucket (block all public access — backups should never be public).
- Create an IAM user with programmatic access and the S3 policy above.
- Copy the access key ID and secret access key.
Create an IAM user with programmatic access and a policy granting s3:PutObject, s3:GetObject, s3:DeleteObject, and s3:ListBucket on the bucket. Use that user's access key ID and secret.
Endpoint: (leave blank — AWS default) Region: your bucket's region, e.g. us-east-1 Bucket: your-backup-bucket
Step 3 — Connect it to OffsiteDB
Paste the Neon connection string, add Amazon S3 as your destination with the bucket and keys from Step 2, and choose a schedule (hourly to daily). OffsiteDB tests the connection, then runs pg_dump, gzips and seals the artifact with AES-256-GCM, and ships it to your bucket. A read-only role scoped to your application schemas captures everything you need; Neon imposes no special hidden schemas.
Step 4 — Know it restores (the part everyone skips)
Every snapshot is restore-drilled: OffsiteDB restores it into a throwaway Postgres cluster and counts the rows before marking it sealed. When you need it back, every artifact is a standard custom-format dump:
gunzip -c neon-db_2026-06-09.dump.gz \ | pg_restore -d "$NEW_DATABASE_URL" --clean --if-exists
You also get a monthly Restore Drill Report with tested restore times — the document you forward when someone asks “are your backups tested?”
Before your next migration
Scheduled snapshots cover the slow disasters; deploys are the fast ones. One step in CI seals a tagged, restore-drilled checkpoint seconds before each migration runs — so a bad ALTER TABLE costs you a revert, not a day of data. Here's how that Friday goes with and without one.
FAQ
Does this work with Neon's free tier?
What permissions does the backup need on Neon?
Where exactly does my data end up?
Can I just run pg_dump in a cron job instead?
Related guides
- Back up Supabase Postgres to Amazon S3
- Back up Neon Postgres to Cloudflare R2
- Back up Neon Postgres to Backblaze B2
- Back up Neon Postgres to Wasabi
- Back up Railway Postgres to Amazon S3
Keep reading
- Neon Postgres backup: the complete picture — what the platform includes natively and where the gaps are
- OffsiteDB vs a cron job running pg_dump — the honest comparison
- Anatomy of a bad migration — minute by minute, with and without a checkpoint