<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw" -->

---
title: Multi-Region PostgreSQL Disaster Recovery and Failback...
description: A comprehensive step-by-step guide to setting up multi-region PostgreSQL disaster recovery and failback using Crunchy PostgreSQL Operator (PGO) on Kubernetes...
canonical: https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Multi-Region PostgreSQL Disaster Recovery and Failback with Crunchy PGO | daily.dev
og:description: A comprehensive step-by-step guide to setting up multi-region PostgreSQL disaster recovery and failback using Crunchy PostgreSQL Operator (PGO) on Kubernetes...
og:url: https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw
og:image: https://api.daily.dev/og/posts/V2ZI79fAw.png
og:image:alt: Multi-Region PostgreSQL Disaster Recovery and Failback with Crunchy PGO
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-Region PostgreSQL Disaster Recovery and Failback with Crunchy PGO

**[CYBERTEC PostgreSQL](https://daily.dev/sources/cybertec_postgresql)** · 11 min read · 4 upvotes · 0 comments

## Summary

A comprehensive step-by-step guide to setting up multi-region PostgreSQL disaster recovery and failback using Crunchy PostgreSQL Operator (PGO) on Kubernetes with MinIO as the WAL archive backend. Covers the full lifecycle: deploying an NGINX reverse proxy to satisfy pgBackRest's HTTPS requirement for MinIO, configuring primary and standby clusters across two regions, simulating a regional failure, promoting the standby to primary (with Patroni timeline switching), and the complex failback process. The failback section details how to avoid operator deadlocks and S3 archive poisoning caused by timeline conflicts, including cleaning up stale PVCs, purging the MinIO bucket, reinitializing the pgBackRest stanza, and redeploying the original primary as a standby on the new timeline.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.cybertec-postgresql.com/en/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo>

## Questions this post answers

### How do I fix pgBackRest timeline conflicts when failing back to the original primary region after a PostgreSQL disaster recovery failover?

Delete the stale PostgresCluster resource, pods, PVCs, and finalizers in the old region to give the operator a clean slate, then reset the pgBackRest stanza on the new master (stanza-create followed by a full backup) so the S3 archive only contains the new timeline's WAL files. Redeploy the old region as a standby with standby.enabled set to true so it bootstraps from the fresh timeline instead of conflicting with the poisoned archive.

_Teams debugging timeline conflicts during PostgreSQL failback can save runbooks like this one on daily.dev._

### How do I expose MinIO over HTTPS for pgBackRest without configuring native TLS on MinIO itself?

Deploy a lightweight NGINX reverse proxy in the MinIO namespace that terminates SSL on port 443 with a self-signed certificate and forwards plain HTTP traffic to MinIO's internal port 9000. Buffering must be disabled (proxy_buffering off, proxy_request_buffering off, client_max_body_size 0) so large PostgreSQL backup and WAL streams pass through without being throttled by disk limits.

_daily.dev helps engineers comparing S3-gateway setups for PostgreSQL backups keep track of proven configs._

### What does spec.standby.enabled do in a Crunchy PGO PostgresCluster manifest?

Setting spec.standby.enabled to true tells Patroni to boot the cluster in continuous archive-recovery mode instead of initializing a fresh writable primary, letting it act as a standby that replays WAL from the specified repo. Flipping it to false promotes that standby into a writable primary, triggering a Patroni timeline switch.

_Engineers configuring Crunchy PGO standby clusters can bookmark configuration details like this on daily.dev._

## Similar posts on daily.dev

- [Going Multi-Region: How to Set Up CloudNativePG\(CNPG\) Distributed Topology](https://daily.dev/posts/going-multi-region-how-to-set-up-cloudnativepg-cnpg-distributed-topology-2tzj6onea) · CYBERTEC PostgreSQL · 1 upvotes · 0 comments
- [Comparing Migration Methods from the Crunchy Data PostgreSQL Operator to the Percona Operator for PostgreSQL](https://daily.dev/posts/comparing-migration-methods-from-the-crunchy-data-postgresql-operator-to-the-percona-operator-for-po-favq5evmb) · Percona Blog · 0 upvotes · 0 comments
- [When failover isn’t safe: Building high-availability PostgreSQL on Kubernetes](https://daily.dev/posts/when-failover-isn-t-safe-building-high-availability-postgresql-on-kubernetes-nljmhojvb) · Datadog · 4 upvotes · 1 comments
- [Highly Available PostgreSQL on Kubernetes in 10 Minutes](https://daily.dev/posts/highly-available-postgresql-on-kubernetes-in-10-minutes-72lxmcugy) · CYBERTEC PostgreSQL · 8 upvotes · 0 comments

---

Tags: [#kubernetes](https://daily.dev/tags/kubernetes), [#postgresql](https://daily.dev/tags/postgresql)

[View this post on daily.dev](https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Multi-Region PostgreSQL Disaster Recovery and Failback with Crunchy PGO","url":"https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw"},"datePublished":"2026-08-11T07:44:06.937Z","dateModified":"2026-09-13T18:55:07.106Z","description":"A comprehensive step-by-step guide to setting up multi-region PostgreSQL disaster recovery and failback using Crunchy PostgreSQL Operator (PGO) on Kubernetes...","image":"https://media.daily.dev/image/upload/s--1KxV4ohY--/f_auto/v1722860400/public/Placeholder%2007","thumbnailUrl":"https://media.daily.dev/image/upload/s--1KxV4ohY--/f_auto/v1722860400/public/Placeholder%2007","isAccessibleForFree":true,"articleSection":"CYBERTEC PostgreSQL","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"CYBERTEC PostgreSQL","logo":"https://media.daily.dev/image/upload/s--T-0b7qSy--/f_auto/v1720886268/logos/cybertec_postgresql","url":"https://daily.dev/sources/cybertec_postgresql"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":4},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"kubernetes,postgresql","timeRequired":"PT11M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"CYBERTEC PostgreSQL","item":"https://daily.dev/sources/cybertec_postgresql"},{"@type":"ListItem","position":3,"name":"Multi-Region PostgreSQL Disaster Recovery and Failback with Crunchy PGO"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/multi-region-postgresql-disaster-recovery-and-failback-with-crunchy-pgo-v2zi79faw#faq","mainEntity":[{"@type":"Question","name":"How do I fix pgBackRest timeline conflicts when failing back to the original primary region after a PostgreSQL disaster recovery failover?","acceptedAnswer":{"@type":"Answer","text":"Delete the stale PostgresCluster resource, pods, PVCs, and finalizers in the old region to give the operator a clean slate, then reset the pgBackRest stanza on the new master (stanza-create followed by a full backup) so the S3 archive only contains the new timeline's WAL files. Redeploy the old region as a standby with standby.enabled set to true so it bootstraps from the fresh timeline instead of conflicting with the poisoned archive. Teams debugging timeline conflicts during PostgreSQL failback can save runbooks like this one on daily.dev."}},{"@type":"Question","name":"How do I expose MinIO over HTTPS for pgBackRest without configuring native TLS on MinIO itself?","acceptedAnswer":{"@type":"Answer","text":"Deploy a lightweight NGINX reverse proxy in the MinIO namespace that terminates SSL on port 443 with a self-signed certificate and forwards plain HTTP traffic to MinIO's internal port 9000. Buffering must be disabled (proxy_buffering off, proxy_request_buffering off, client_max_body_size 0) so large PostgreSQL backup and WAL streams pass through without being throttled by disk limits. daily.dev helps engineers comparing S3-gateway setups for PostgreSQL backups keep track of proven configs."}},{"@type":"Question","name":"What does spec.standby.enabled do in a Crunchy PGO PostgresCluster manifest?","acceptedAnswer":{"@type":"Answer","text":"Setting spec.standby.enabled to true tells Patroni to boot the cluster in continuous archive-recovery mode instead of initializing a fresh writable primary, letting it act as a standby that replays WAL from the specified repo. Flipping it to false promotes that standby into a writable primary, triggering a Patroni timeline switch. Engineers configuring Crunchy PGO standby clusters can bookmark configuration details like this on daily.dev."}}]}
```

