---
title: "Globally Distributed Postgres"
description: "Globally distributed Postgres describes a way to serve a conventional CRUD application across regions while keeping Postgres writes directed to one primary and reads near users. Fly’s proxy sends each request to the local application instance, where most requests succeed; when a write reaches a read-only replica, Rails catches PG::ReadOnlySqlTransaction and returns a fly-replay header naming PRIMARY_REGION. The proxy then retries the complete HTTP request inside its network, avoiding per-query cross-region database routing and allowing the application to retain its ordinary connection behavior. The approach can also support session-based read-your-own-writes and replica-freshness checks, but it is not suitable for every workload; the text contrasts it with geographically distributed databases such as CockroachDB."
---

# Globally Distributed Postgres

[Fly.io](https://yomu.fyi/company/fly-io) · Jun 30, 2021

**Type:** Problem & solution

## Summary

Globally distributed Postgres describes a way to serve a conventional CRUD application across regions while keeping Postgres writes directed to one primary and reads near users. Fly’s proxy sends each request to the local application instance, where most requests succeed; when a write reaches a read-only replica, Rails catches PG::ReadOnlySqlTransaction and returns a fly-replay header naming PRIMARY\_REGION. The proxy then retries the complete HTTP request inside its network, avoiding per-query cross-region database routing and allowing the application to retain its ordinary connection behavior. The approach can also support session-based read-your-own-writes and replica-freshness checks, but it is not suitable for every workload; the text contrasts it with geographically distributed databases such as CockroachDB.

## Context

Geographically distributed applications can use read replicas for fast local reads, but writes landing on multiple database instances are difficult to manage. Rails connection switching can address this, but the text describes it as painful to configure and deliberately simplified.

## Approach / What changed

Each application instance attempts to handle every request. If a write reaches a read-only Postgres replica, Rails catches PG::ReadOnlySqlTransaction and sets a fly-replay header for PRIMARY\_REGION; Fly’s proxy retries the entire HTTP request in the writer’s region.

## Takeaways

- Fly Postgres can be configured with a writer in one region and read replicas in other application regions; the text presents flyctl postgres create as the command to create such a cluster.
- The Rails implementation uses eight lines to detect PG::ReadOnlySqlTransaction and direct Fly’s proxy to replay the request in the primary region.
- The pattern is intended for read-heavy applications and is not a cure-all; distributed-by-design databases such as CockroachDB are presented as an alternative for write-heavy scenarios.

**Tags:** [Distributed Systems](https://yomu.fyi/topic/distributed-systems), [Fly](https://yomu.fyi/topic/fly), [Postgres](https://yomu.fyi/topic/postgres), [Ruby on Rails](https://yomu.fyi/topic/ruby-on-rails)

- Source: [Fly.io](https://fly.io/blog/globally-distributed-postgres)
- Source URL: https://fly.io/blog/globally-distributed-postgres
- Ingested by Yomu: 2026-09-02T12:00:44.325Z

[Read original post](https://fly.io/blog/globally-distributed-postgres)
