How to back up Render Postgres to Cloudflare R2
RESTORE-TESTED · ENCRYPTED · IN A BUCKET YOU OWN
Render 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 Cloudflare R2 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 Render connection string
Render dashboard → your Postgres instance → Connections → External Connection String.
Use the External connection string, not the Internal one — the internal host is only reachable from other Render services. Render free-tier databases expire after 90 days, which is its own argument for keeping an independent off-site copy.
A read-only role is all you need. The exact CREATE ROLE SQL is on the security page.
Step 2 — Create a Cloudflare R2 bucket and access keys
- In the Cloudflare dashboard, open R2 and create a bucket.
- Create an R2 API token with Object Read & Write permission.
- Copy the S3-compatible access key ID, secret, and your account's R2 endpoint URL.
In R2, create an API token scoped to Object Read & Write. R2 gives you an S3-compatible access key ID and secret — use those. R2 has no egress fees, which makes it a popular backup target.
Endpoint: https://<account-id>.r2.cloudflarestorage.com Region: auto Bucket: your-backup-bucket
Step 3 — Connect it to OffsiteDB
Paste the Render connection string, add Cloudflare R2 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. Standard Postgres; a read-only role on your schemas is all that's required.
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 render-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 Render's free tier?
What permissions does the backup need on Render?
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 Cloudflare R2
- Back up Neon Postgres to Cloudflare R2
- Back up Railway Postgres to Cloudflare R2
- Back up Render Postgres to Amazon S3
- Back up Render Postgres to Backblaze B2
Keep reading
- OffsiteDB vs a cron job running pg_dump — the honest comparison
- Anatomy of a bad migration — minute by minute, with and without a checkpoint