How to replace Supabase managed backups and PITR when self-hosting
If you have moved, or are moving, from Supabase Cloud to self-hosted Supabase, you must rebuild backups, point-in-time recovery and Storage object backups yourself. Supabase's self-hosting documentation lists managed backups and PITR as unavailable when self-hosting, and the Docker Compose stack is community-supported, so no vendor schedule protects your data by default. The first decision is which path fits your team: dump and archive the database you already run, or run Postgres under an operator that manages failover and archiving for you.
The first path is pg_dump for logical backups, combined with WAL archiving for point-in-time recovery. Archiving requires you to choose a destination outside the database host, configure archive_mode and archive_command, and keep base backups alongside the WAL segments. The second path runs Postgres on CloudNativePG, which documents backups to object storage through the Barman Cloud plugin, volume snapshots and WAL archiving with point-in-time recovery, or on Patroni, which provides high availability but leaves backup tooling to you. Confirm each tool's current backup options against its CloudNativePG documentation before you commit.
Whichever path you choose, schedule restore tests and record the recovery time you actually achieve, because an untested backup is not a recovery plan. Include Storage objects in the same plan, since the database holds only object metadata, and rehearse a full restore of both together. Before any self-hosted Supabase upgrade that changes the Storage schema, take a fresh database backup, as the Docker configuration changelog flags one-way Storage migrations.
Which open-source tool covers each backup capability
This table maps each backup and recovery capability that Supabase Cloud provides to the open-source tool that covers it when you self-host. Read each row as a gap to fill: several capabilities need two tools, and some, such as detecting a failed primary, are not handled by PostgreSQL at all. Confirm each tool's fit against your own recovery targets before you assign it.
| Capability | Open-source tool or approach | Coverage note |
|---|---|---|
| Logical dumps | pg_dump and pg_dumpall, scheduled from cron or a Kubernetes CronJob | Produces consistent logical copies of the database. Restores are slower than base backups, so treat them as a complement, not the main recovery path. |
| Base backups | pgBackRest-style tooling, or the Barman Cloud plugin in CloudNativePG | Physical copies of the cluster directory. Pair them with WAL archiving so you can restore to a chosen point in time. |
| WAL archiving and PITR | PostgreSQL continuous archiving, handled by pgBackRest-style tooling or the CloudNativePG Barman Cloud plugin | Point-in-time recovery needs an unbroken WAL chain. PostgreSQL does not ship a managed archive, so you must monitor archive failures yourself. |
| Replicas and failover | PostgreSQL streaming replication with Patroni, or CloudNativePG's built-in failover | PostgreSQL does not detect a failed primary or promote a standby on its own. Patroni or CloudNativePG supplies that detection and promotion. |
| Storage object backups | rclone or S3-compatible tooling against the Storage bucket, with volume snapshots as an option | Storage objects live in object storage, not in Postgres. A database dump does not include them, so back up the bucket on its own schedule. |
| Restore testing | Scheduled restores into a separate environment, using the same tools as the backup jobs | No open-source tool tests restores for you. Confirm how often restores are run, who signs off, and how long a full restore takes in your environment. |
| Retention and encryption | Object storage lifecycle rules and client-side encryption in the backup tool | Retention and encryption are configured per tool, so they must match across dumps, WAL and Storage backups. Confirm key custody before go-live. |
Choosing between pg_dump with WAL archiving and an operator
Self-hosted Supabase runs on plain Postgres, so the backup design is a Postgres decision. The options below range from scheduled logical dumps to operator-managed continuous archiving, and each one trades setup effort, skills and restore time differently.
Scheduled pg_dump with tested restores
A cron job or scheduler runs pg_dump against the Supabase database on a fixed cadence and copies the output off the host. It is the simplest route and fits small projects where losing hours of data is acceptable. The main risk is the restore, not the dump: a dump you have never restored is not a backup. Check how long a full restore takes into a scratch instance, and confirm that roles, extensions and the auth and storage schemas come back intact.
Continuous WAL archiving with PITR
Base backups plus archived write-ahead log segments let you recover to a chosen moment instead of the last dump. This suits a single-node Postgres that holds data you cannot easily recreate. You take on the archive storage, retention settings and the monitoring that tells you archiving has stalled, which is a common silent failure. Test a point-in-time restore at least as often as you change the archive configuration.
CloudNativePG with the Barman Cloud plugin
CloudNativePG runs Postgres as a Kubernetes-native cluster and sends base backups and WAL to object storage through the Barman Cloud plugin, with point-in-time recovery built in. It fits teams that already operate Kubernetes and want backups defined as cluster resources. The trade-off is Kubernetes dependency: someone on your team must understand operators, storage classes and object store credentials. Confirm that the Supabase services can reach the cluster as you have configured it before you cut over.
Patroni for high availability
Patroni manages failover for a Postgres cluster but does not replace backups. Its value is keeping a standby ready to take over when the primary fails, which reduces downtime for planned and unplanned outages. It suits organizations that already run Patroni estates and have a distributed configuration store such as etcd or Consul. Backups and archiving still need their own tooling, so budget for both. Ask who owns the failover runbook and how often it is rehearsed.
Volume snapshots
Storage-level snapshots of the volume holding the Postgres data directory are fast to take and can be scheduled through your platform. They are only consistent when the database is quiesced or the snapshot tool coordinates with Postgres, so an unplanned crash-consistent copy needs careful validation. They also carry no PITR on their own. Use them as a complement to logical or WAL-based backups, and confirm with your storage vendor how snapshots are retained, replicated and restored.
How PITR works on self-hosted Postgres
Point-in-time recovery rests on two pieces: a base backup (a physical copy of the whole database cluster taken at one moment) and a continuous archive of the write-ahead log (WAL) segments produced after that moment. To restore to a chosen time, you start from the base backup, replay archived WAL up to the target, and stop. The PostgreSQL continuous archiving documentation describes this mechanism. Two consequences follow. First, the archive must be complete: a missing WAL segment leaves a gap, and you can only recover to a time before that gap. Second, a restore you have never performed is an untested assumption, so schedule restore rehearsals on a separate host and time how long they take, because that duration is the number your recovery plan actually depends on.
Version matching matters here. The self-hosted Supabase Docker configuration 0.8.0 switched to Envoy, and version 0.6.0, released on June 17, 2026, made Postgres 17 the default database. Backup tooling, base backup format and the restore target must all match the major version of the running cluster, so confirm the exact image tag in your Compose file before choosing tools. PostgreSQL supports major version 17 until November 8, 2029, per the PostgreSQL versioning policy, so plan the next major upgrade against that date and rehearse it alongside your restores.
A logical dump made with pg_dump is useful for migrations and selective restores, but it does not give you point-in-time recovery. It captures a snapshot at the moment the dump ran, and anything written afterward is lost unless you have WAL archives to replay. Treat nightly dumps and WAL archiving as complementary: dumps help you move or inspect data, while base backups plus WAL deliver recovery to a specific minute. Before you go live, confirm with your operations team who owns the archive location, how long archived WAL is retained, what alerts fire when archiving falls behind, and who is authorized to run a restore.
Running backups alongside the rest of self-hosted Supabase
On a single host, the Postgres database runs as a container from the Docker Compose file, so backup jobs usually run on the host and reach the database through the container, for example with docker compose exec against the db service. The backup job must write its output outside the containers, to a separate disk or object store, because a backup stored on the same volume as the database does not protect against losing that volume. Storage objects live in the Storage service's file backend and are not inside the database dump, so they need their own copy job that runs on the same schedule.
- Dump access: run
pg_dumpthroughdocker compose execwith the database service name, and keep the credentials in.envrather than in shell history or cron lines. - Storage files: copy the Storage volume or bucket on the same schedule as the database dump, so the two sets match.
- Restore order: restore the database first, then start Auth, PostgREST, Realtime and Storage at the versions pinned in the Docker release you run.
- Upgrade gate: the 0.8.3 changelog flags one-way Storage database migrations that need a database backup before updating, so take a dump and a file copy immediately before pulling that release.
- Test restores: restore into a second Compose project on a different host at least periodically, since a dump that has never been restored has not been verified.
Confirm with your team which Docker release you run and which services you have removed from docker-compose.yml, because the restore sequence depends on both.
On Kubernetes, the community Helm chart or the Supabase Operator is maintained by the Supabase community rather than by Supabase, so the chart version and the upstream service versions it deploys need to be checked against the release you intend to run. The backup job runs as a Kubernetes workload that reaches the database through its cluster service and a secret holding credentials, not through a container shell on a host. Where the database is managed by an operator such as CloudNativePG, backups are handled by that operator's own mechanism, which the backup job should call or verify rather than duplicate.
- Service access: point the backup job at the database service name and read credentials from a Kubernetes secret, with network policies limiting which pods can connect.
- Object storage: run Storage file copies on a separate schedule with their own credentials and retention, since the Storage pods do not hold the files in the database.
- Pinned versions: record the Auth, PostgREST and Realtime versions from the release you deploy, because a restore into a different set of versions can fail on JWT or schema differences.
- Persistent volumes: confirm that snapshots, if you use them, capture the database volume consistently with WAL or dumps, since a crash-consistent snapshot alone may not meet your recovery goal.
- Ownership: agree who maintains the chart fork, the operator version and the backup jobs, because community charts change without a Supabase support commitment.
Confirm the chart version, the operator version and the restore procedure in a non-production cluster before relying on them.
Some organizations already run PostgreSQL with its own backup tooling and want Supabase's services to use that estate. In this case the backup design belongs to the database team, and the Supabase services connect to it as clients. Supabase's Storage and Auth schemas must be included in any backup, because they live in the same database, and the Supabase service roles and extensions must be restorable as well.
- Scope of the database: include all Supabase schemas in the backup and not only the application schema, so Auth users and Storage metadata come back with the data.
- Continuous archiving: PostgreSQL's WAL archiving and point-in-time recovery apply to the estate, so the database team should confirm they cover the Supabase schemas and the recovery window the business requires.
- Replicas: a standby is not a backup, since an error replicated to a standby also replicates. Keep at least one copy that is isolated from the primary.
- Major upgrades: coordinate Postgres major upgrades with Supabase's supported version and test the restore on the new major version before cutover.
- Connection path: if you use a pooler such as Supavisor or PgBouncer, confirm the backup job connects directly to the primary rather than through the pooler.
Confirm with your database team which tool produces the recovery point and who tests it, because Supabase's self-hosting docs do not cover backups for an external database.
Setting up backups after moving off Supabase Cloud
This sequence rebuilds backup and recovery for a self-hosted Supabase project, from inventorying what the Cloud project provided through to a timed, repeatable restore that you have verified against the original data.
Inventory what the Cloud project provided
Before cutover, the team lead and the database owner record what the Supabase Cloud project actually had: which backup features the current plan includes, the daily backup retention window, whether point-in-time recovery was enabled, and where Storage buckets and their object counts sit. Supabase's plan pages (linked from the pricing page) describe what each plan includes, so confirm the figures for your own project in the dashboard rather than relying on memory. The output is a short written baseline that the rest of the sequence measures against. Confirm this baseline before you move on to the next step.
Take a final dump and Storage copy
Shortly before cutover, the database owner freezes writes if the application allows it, then takes a full logical dump of the Postgres database and copies every Storage bucket to the new environment. Supabase's restore and Storage copy guides describe the platform-to-self-hosted path, and the same artifacts serve as your first known-good backup. Store the dump files and the object copy in a location separate from the new cluster, and record the dump timestamp, file checksums and the object count per bucket. The step is done when a test read of the dump file succeeds and the checksums are written to the migration record.
Configure WAL archiving or operator backups
The platform team sets up continuous backup on the new target. On a self-managed Postgres cluster, this means enabling WAL archiving to object storage and taking base backups, following the continuous archiving and point-in-time recovery documentation. On Kubernetes, CloudNativePG can handle this through the Barman Cloud plugin, volume snapshots and WAL archiving, while Patroni clusters typically pair with a separate backup tool. Choose the approach based on your platform skills and on-call model, and keep the archive bucket on separate credentials from the database. Confirm that the first base backup and at least one archived WAL segment appear in the target bucket before the step closes.
Run a full restore to a separate environment
Restore the final dump and the latest base backup plus archived WAL into an isolated environment that has no route to production. Use the same Postgres major version as production, and apply the self-hosted Supabase Docker configuration you intend to run so that Auth, Storage and Realtime schemas load correctly. Watch for restore errors in the logs, and do not treat a clean exit alone as success. The step is done when Supabase Studio or a test client can sign in and query the restored data.
Time the restore and record the procedure
Measure the wall-clock time from starting the restore to the point where the application's smoke tests pass, and write down each command, the order of operations and the credentials location (not the secrets). This timing is the recovery time you can actually demonstrate, and it is the figure to bring to the business owner when they ask how long an outage would last. Store the runbook in the same place as your other operational documentation and assign an owner who will update it after every change. The step is done when a second engineer can follow the runbook without help.
Verify Storage objects and database rows
Compare the restored environment against the baseline from the first step. For the database, compare row counts for critical tables, run checksums or aggregate queries on key columns, and confirm that the auth users table matches the source count. For Storage, compare object counts and sizes per bucket and sample-check a set of files by hash. Record any mismatch with a cause and fix it before you accept the backup as valid. The verification record is the evidence you will show auditors or an internal review board later.
Schedule recurring restore tests and upgrade backups
Put the restore test on a recurring calendar owned by a named person, and repeat the full procedure on that schedule, not only at launch. Before each self-hosted Supabase Docker release, take a fresh backup and store it separately, because the changelog flags some upgrades, such as one-way Storage database migrations, that require a database backup before updating. Treat a failed restore test as an incident, and do not apply the upgrade until the backup is restorable. The step is done when the calendar, backup checklist and owner are all recorded.
Questions teams ask before rebuilding Supabase backups
What does it cost to rebuild backups and PITR for self-hosted Supabase?
The cost comes from four components: object storage for base backups and WAL archives, compute for the backup and restore jobs, the operator time to build and maintain the pipeline, and the time spent running restore tests. Storage and compute are recurring and grow with database size, write volume and retention length. Operator time is largely one-time for the initial build, then recurs for upgrades and monitoring. No fixed figure applies to every environment, so ask any provider for a quote that lists each component separately, states the retention period it assumes and names the restore test frequency. Compare that with the managed backup and PITR features on the Supabase Cloud plan you would be leaving, which are priced separately in the plan you are on. Confirm current plan details on Supabase pricing.
How long does a self-hosted Supabase backup setup take?
The duration depends on your environment and team skills, and no fixed figure applies to every setup. The main variables are whether you already run PostgreSQL backups, whether object storage with an S3-compatible API is available, how many environments need the same pipeline, and how much restore testing you require before go-live. A team that already operates PostgreSQL and Linux will move faster than one learning both at once. Ask for a scoped estimate that lists the backup method, the storage target, the restore test plan and the acceptance criteria, then agree it in writing before work starts. Fixed-scope engagements from DeployOpen follow the same pattern: scope, deliverables and timelines are agreed in writing first.
What skills does the team need to run its own Supabase backups?
The work needs three areas of competence. First, PostgreSQL operations: running pg_dump, archiving WAL segments, understanding base backups, and performing point-in-time restores with pg_restore or the PostgreSQL recovery settings. Second, Linux and networking: scheduling jobs, managing disk, and securing the path to storage. Third, secrets handling: protecting storage credentials, database passwords and the encryption keys used for backups, and rotating them without breaking the job. Storage for Supabase objects also needs an S3-compatible endpoint and its own credentials. If one of these areas is thin on the team, plan training or outside help before the first production cutover.
Can our own team set up Supabase backups without outside help?
Yes, if the team already runs PostgreSQL and object storage and can dedicate time to testing. The official self-hosting documentation covers Docker Compose deployment, and the PostgreSQL documentation covers continuous archiving and point-in-time recovery. The decision points are whether someone will own restore testing on a schedule, whether the team can recover a database into a clean environment within the time it has committed to, and whether it has the capacity to repeat the work at each Supabase release. Self-hosted Supabase is community-supported, so the team should also decide in advance who handles incidents. If any of these are uncertain, a fixed-scope implementation with written deliverables is one option.
What happens to backups when a self-hosted project is deleted?
Nothing is removed automatically from your own storage when you delete a Supabase project in a self-hosted setup, because the backups live in buckets or volumes you control. The risk is the opposite: a deletion script, a lifecycle rule or a cleanup job can remove archives that you still need. Set retention rules in writing, restrict delete permissions on backup buckets, enable object versioning or write-once retention where your storage supports it, and keep a copy in a separate account or location. For hosted projects, check how Supabase Cloud handles backups after deletion in its own documentation, since that behavior is a provider policy rather than something you control.
Does DeployOpen run self-hosted Supabase backups for us?
DeployOpen plans, implements, hardens, backs up, upgrades, documents and supports self-hosted open-source platforms inside your own infrastructure, which covers building and testing the backup and restore pipeline for self-hosted Supabase. Work is fixed-scope, with scope, deliverables and timelines agreed in writing before work starts. Ongoing support, upgrades and continuous testing are available as retainers. DeployOpen does not publish a price list, so a quote follows from the written scope. DeployOpen prepares systems and evidence for compliance assessments but does not issue audit reports or certifications.
What support is available for self-hosted Supabase backups?
Self-hosted Supabase is community-supported. Supabase's self-hosting documentation directs operators to GitHub Discussions, GitHub Issues, Discord and Reddit, and it directs enterprises to contact its Growth Team. Community channels help with configuration questions and known bugs, but they do not carry a service commitment for your recovery time. Decide before go-live who owns incidents, which vendor or partner you call for restores, and how you will document the runbook. Confirm the support terms directly with Supabase if you need a contractual commitment, and check the self-hosting guide for the current list of channels.
What to confirm with your vendor and your own environment
Start by writing down the retention and recovery targets your organization actually needs, in terms of how far back you must be able to restore and how much data loss is acceptable, before you choose any tooling. Those numbers decide whether a nightly pg_dump is enough or whether you need WAL archiving with point-in-time recovery, and they drive the storage and staffing you will budget for. Confirm them with the data owners and your compliance lead, not with the platform team alone. Then check whether your data residency rules allow the object store you have in mind for WAL segments and Storage objects, including the region, the provider and any sub-processors behind it.
Confirm which Supabase Docker configuration version you run and read its upgrade notes before every update. The self-hosted changelog flags security fixes and one-way Storage database migrations that require a database backup first, so the backup check belongs in your change procedure, not in memory. If you run Kubernetes instead, confirm with your operator project, whether community or otherwise, that it supports your cluster version and the PostgreSQL major version you plan to run. Also confirm that the operator's backup plugin writes to the object store you approved.
PostgreSQL minor releases do not change the storage format, but they still mean replacing executables and restarting the server, so take and test a backup before each one. Major upgrades are a separate project: pg_upgrade, dump and restore, and logical replication each have different rollback paths, and each needs a fresh, restorable backup as the fallback. Check the support window for your current major version against the PostgreSQL versioning policy and plan the upgrade with that date in view, since an unsupported database is a finding in most assessments.
How DeployOpen scopes and delivers backup and recovery
DeployOpen plans, implements, backs up, documents and supports self-hosted open-source platforms inside your own infrastructure, so backup and recovery for a self-hosted Supabase stack is designed and tested as part of the engagement. The work covers the Postgres database, Storage objects and the restore procedure your team will run when something goes wrong.
How we scope
- Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
- The written scope names which Postgres topology is in use, whether a logical dump, WAL archiving or an operator-managed setup is chosen.
- Recovery point and recovery time targets are agreed with your team and recorded in the scope, not assumed.
How we build
- Backup jobs for the database and Storage object store are configured in your own cloud accounts or data centers.
- Restores are exercised in a separate environment, and the results are recorded against the agreed targets.
- Secrets, encryption keys and backup credentials are stored and rotated according to the access model agreed in scope.
How we hand over
- You receive runbooks for backup, point-in-time restore, failover and Storage object recovery, written for your operators.
- Handover includes a documented restore test with the evidence your auditors or internal risk teams will ask for.
- Your team is walked through the upgrade rule that requires a database backup before Storage migrations, with the steps written down.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer, including periodic restore tests.
- Retainers can cover monitoring of backup jobs, WAL archive health and changes to the Supabase Docker configuration.
- Ask in your quote which restore tests, reporting and response times are included, and confirm them in writing.

