<p>Google has ]this cool tool <code>kubemci</code> - <code>Command line tool to configure L7 load balancers using multiple kubernetes clusters</code> with which you can basically have a HA multi region Kubernetes setup. Which is kind of cool.</p>

<p>But let's say we have an basic architecture like this:</p>

<ul>
<li>Front end is implemented as SPA and uses json API to talk to backend</li>
<li>Backend is a set of microservices which use PostgreSQL as a DB storage engine.</li>
</ul>

<p>So I can create two Kubernetes Clusters on GKE, put both backend and frontend on them (e.g. let's say in London and Belgium) and all looks fine. </p>

<p>Until we think about the database. PostgreSQL is single master only, so it must be placed in one of the regions only. And If backend from London region starts to talk to PostgreSQL in Belgium region the performance will really be poor considering the 6ms+ latency between those regions. </p>

<p>So that whole HA setup kind of doesn't make any sense? Or am I missing something? One option to slightly mitigate the issue is would be have a readonly replica in the the "slave" region, and direct read-only queries there (is that even possible with PostgreSQL?)</p>

<p>This is a classic architecture scenario that has no easy solution. Making data available in multiple regions is a challenging problem that major companies spend a lot of time and money to solve.</p>

<ul>
<li><p>PostgreSQL does not natively support multi-master writes. Your idea of a replica located in the other region with logic in your app to read and write to the correct database would work. This will give you fast local reads, but slower writes in one region. It's also more complicated code in you app and more work to handle failover of the master. Bandwidth and costs can also be problems with heavy updates.</p></li>
<li><p>Use 3rd-party solutions for multi-master Postgres (like <a href="https://www.2ndquadrant.com/en/resources/postgres-bdr-2ndquadrant/" rel="nofollow noreferrer">Postgres-BDR by 2nd Quadrant</a>) to offload the work to the database layer. This can get expensive and your application still has to manage data conflicts from two regions overwriting the same data at the same time.</p></li>
<li><p>Choose another database that supports multi-regional replication with multi-master writes. <a href="http://cassandra.apache.org/" rel="nofollow noreferrer">Cassandra</a> (or <a href="https://www.scylladb.com/" rel="nofollow noreferrer">ScyllaDB</a>) is a good choice, or hosted options like <a href="https://cloud.google.com/spanner/" rel="nofollow noreferrer">Google Spanner</a>, <a href="https://learn.microsoft.com/en-us/azure/cosmos-db/introduction" rel="nofollow noreferrer">Azure CosmosDB</a>, <a href="https://aws.amazon.com/dynamodb/global-tables/" rel="nofollow noreferrer">AWS DynamoDB Global Tables</a>, and others. An interesting option is <a href="https://www.cockroachlabs.com/" rel="nofollow noreferrer">CockroachDB</a> which supports the PostgreSQL protocol but is a scalable relational database and supports multiple regions.</p></li>
<li><p>If none of these options work, you'll have to create your own replication system. Some companies do this with a event-sourced / CQRS architecture where every write is a message sent to a central log, then applied in every location. This is a more work but provides the most flexibility. At this point you're also basically building your own database replication system.</p></li>
</ul>
