Expedition. Free, on-demand.

Technical tracks for practitioners, outcomes for leaders.

HA Terminology

Before getting into how managed Postgres handles high availability, here are the terms you'll see everywhere.

RPO (Recovery Point Objective) is how much data loss is acceptable. An RPO of zero means you can't lose a single committed transaction. An RPO of 5 minutes means you can tolerate losing the last 5 minutes of writes.

RTO (Recovery Time Objective) is how long your application can be down. An RTO of 30 seconds means users might notice a brief hiccup. An RTO of 30 minutes means customers are waiting.

HA vs. DR:

  • High availability (HA) is quick, automatic recovery from common failures: a crashed process, a failed disk, a network blip. Usually within one region.
  • Disaster recovery (DR) is about surviving the big stuff, like a whole data center or region going offline. Usually cross-region.

Failover is promoting a standby to be the new primary when the original primary is unavailable.

Switchover is a planned, graceful handoff of the primary role to another node, usually for maintenance.

Replication lag is the delay between a transaction committing on the primary and being applied on the standby. Less lag means less potential data loss during a failover.

How Managed Postgres Delivers HA

When you run Postgres yourself, high availability is something you build. You configure streaming replication, deploy failover tooling (Patroni is the usual choice), set up health checks, and wire up connection routing. With a managed service, the platform does all of that.

A typical managed HA architecture looks like this:

┌────────────────────────────────────────────────────────┐
│  Managed Platform                                      │
│                                                        │
│  ┌──────────┐    replication    ┌──────────┐          │
│  │ Primary  │ ───────────────▶  │ Standby  │          │
│  │ (R/W)    │                   │ (hidden) │          │
│  └──────────┘                   └──────────┘          │
│       ▲                                               │
│       │  health monitoring, automatic failover        │
│       │  connection routing                           │
└───────┼───────────────────────────────────────────────┘
        │
   Your application connects here

Behind the scenes, the platform streams WAL from the primary to one or more standbys in near real time, watches instance health and replication status, promotes a standby automatically if the primary goes away, and points your connection endpoint at the new primary afterward. You keep using the same hostname.

Why You Can't See or Connect to the Standby

On most managed platforms the HA standby is hidden. You won't find a connection string for it, and you can't query it. That's on purpose:

  • Failover has to be fast and predictable. If your heavy analytics queries or long-running transactions are on the standby, promoting it gets risky. Keeping the standby dedicated to one job means it's always ready to take over.
  • Replication has to stay current. Queries on a standby can conflict with WAL replay and make it fall behind, which raises your effective RPO. A hidden standby replays WAL as fast as it arrives.
  • The platform owns the configuration. It's a lot easier to hit RTO and RPO targets when nobody is changing settings on the standby.

Read replicas are a different thing. Some platforms offer them as a separate feature: they're visible, you can connect to them, and they exist to offload read traffic. They aren't your failover target.

Snowflake Postgres

In Snowflake Postgres, HA is a setting on the instance. Turning it on provisions a standby in a separate availability zone with automatic failover:

CREATE POSTGRES INSTANCE prod_postgres
  COMPUTE_FAMILY = 'STANDARD_M'
  STORAGE_SIZE_GB = 500
  AUTHENTICATION_AUTHORITY = POSTGRES
  HIGH_AVAILABILITY = TRUE;

HA is available on the STANDARD and HIGHMEM compute families, not on the BURSTABLE sizes. You can turn it on or off later with ALTER POSTGRES INSTANCE, but that change requires a maintenance operation, so plan for it. Without HA, recovering from a failed primary means restoring from backup, which can take hours on a large or busy instance. For production, turn it on.

What Happens During a Failover

Here's the usual sequence when a primary fails on a managed platform:

  1. Detection. Health monitoring notices the primary is unresponsive.
  2. Promotion. The standby finishes replaying whatever WAL it has and starts accepting writes.
  3. Routing. The connection endpoint (DNS or internal routing) is updated to point at the new primary.
  4. Reconnection. Your application's next connection attempt lands on the new primary.

This generally takes seconds to a minute or so, depending on the platform and how failure is detected. During that window, active connections are dropped and new connections can fail briefly.

Planned Maintenance

Upgrades and patches typically use a switchover, a graceful handoff instead of a crash-triggered failover. The platform drains connections from the current primary, promotes the standby, and reroutes traffic. You usually see a shorter blip than with an unplanned failover.

What You're Responsible For

The platform handles replication, monitoring, and failover. Your application still has to ride out the brief interruption.

Connection Retry Logic

During failover, active connections drop. Your application should retry instead of throwing errors straight at users:

import psycopg
import time

def get_connection(dsn, max_retries=3, base_delay=1):
    for attempt in range(max_retries):
        try:
            return psycopg.connect(dsn, connect_timeout=5)
        except psycopg.OperationalError:
            if attempt < max_retries - 1:
                time.sleep(base_delay * (2 ** attempt))
            else:
                raise

Most connection pools and frameworks have retry support built in. Make sure it's turned on with reasonable timeouts.

Idempotent Writes

If a connection drops mid-commit, you don't know whether the transaction made it. Design writes so they're safe to retry:

  • Use INSERT ... ON CONFLICT for upserts.
  • Include a unique request ID so you can detect duplicate submissions.
  • Wrap multi-step operations in an explicit transaction so they commit or fail together.

Sensible Timeouts

Set connect_timeout so your application doesn't hang waiting on a dead node, and a statement_timeout so a stuck query doesn't hold a connection forever. connect_timeout is a libpq connection parameter. statement_timeout is a server setting, so in a connection URI you pass it through options:

postgresql://user:pass@managed-endpoint:5432/mydb?connect_timeout=5&options=-c%20statement_timeout%3D30000

Conclusion

With managed Postgres, high availability is something the platform provides rather than something you build. Replication, health monitoring, failure detection, and failover happen without you. Your part is making the application tolerate a short connection interruption: retry logic, idempotent writes, and sensible timeouts.

Related Resources

Enable and manage HA for Snowflake Postgres instances.


Official docs covering replication concepts and standby server architecture.


How streaming and logical replication work in Postgres.

Updated Oct 27, 2026

This content is provided as is, and is not maintained on an ongoing basis. It may be out of date with current Snowflake instances