A replicação multi-região é uma topologia de banco que copia dados entre regiões geográficas para reduzir latência de leitura e sobreviver a quedas. O inimigo é a física: uma ida e volta cruzando um oceano custa dezenas de milissegundos antes de o banco fazer qualquer trabalho, e padrões de requisição tagarelas pagam isso repetidamente. A replicação leva os dados até os usuários — e imediatamente levanta as perguntas que definem o tema: quem aceita escritas, o quão desatualizadas as leituras podem estar, e se você já precisa de algo disso.
Principais pontos
| Pergunta | Resposta |
|---|---|
| O prêmio | Leituras locais em toda parte; sobreviver à queda de uma região |
| O preço | Lag de replicação, latência de escrita até o primário, complexidade |
| Topologia padrão | Um primário de escrita + réplicas de leitura por região |
| O fato estrutural | Replicação entre regiões é assíncrona — o lag vem embutido |
| Primeira pergunta | A distância é mesmo o seu problema de latência? Meça antes de replicar |
Meça antes de replicar
Antes de qualquer decisão de topologia, obtenha o número do qual ela depende — quanto uma ida e volta custa de fato aos seus usuários, por região:
// JavaScript / Node.js — Back4app JS SDK
// Latency probe: measure what users in this region actually feel
const probe = new Parse.Query('HealthCheck');
probe.limit(1);
const started = Date.now();
await probe.first(); // one lightweight read
const readMs = Date.now() - started;
const sample = new Parse.Object('LatencySample');
sample.set('clientRegion', 'eu'); // where this client runs
sample.set('readMs', readMs);
await sample.save(); // writes always travel to the primary
console.log(`read: ${readMs} ms — reads can be served locally,`);
console.log('writes pay the distance to the primary region'); // Flutter / Dart — Back4app Flutter SDK
// Latency probe: measure what users in this region actually feel
final probe = QueryBuilder<ParseObject>(ParseObject('HealthCheck'))
..setLimit(1);
final started = DateTime.now();
await probe.query(); // one lightweight read
final readMs = DateTime.now().difference(started).inMilliseconds;
final sample = ParseObject('LatencySample')
..set('clientRegion', 'eu') // where this client runs
..set('readMs', readMs);
await sample.save(); // writes always travel to the primary
print('read: $readMs ms — reads can be served locally,');
print('writes pay the distance to the primary region'); // iOS / Swift — Back4app Swift SDK
// Latency probe: measure what users in this region actually feel
let probe = HealthCheck.query().limit(1)
let started = Date()
probe.first { result in // one lightweight read
let readMs = Int(Date().timeIntervalSince(started) * 1000)
var sample = LatencySample()
sample.clientRegion = "eu" // where this client runs
sample.readMs = readMs
sample.save { _ in // writes always travel to the primary
print("read: \(readMs) ms — reads can be served locally,")
print("writes pay the distance to the primary region")
}
} // Android / Kotlin — Back4app Android SDK
// Latency probe: measure what users in this region actually feel
val probe = ParseQuery.getQuery<ParseObject>("HealthCheck")
probe.limit = 1
val started = System.currentTimeMillis()
probe.getFirstInBackground { _, e -> // one lightweight read
val readMs = System.currentTimeMillis() - started
val sample = ParseObject("LatencySample")
sample.put("clientRegion", "eu") // where this client runs
sample.put("readMs", readMs)
sample.saveInBackground { // writes travel to the primary
println("read: $readMs ms — reads can be served locally,")
println("writes pay the distance to the primary region")
}
} Quando os números justificam réplicas, a maquinaria é padrão — aqui como replicação lógica do PostgreSQL, com o lag como fato consultável de primeira classe:
-- No primário (região A): publique as mudanças
CREATE PUBLICATION app_pub FOR ALL TABLES;
-- Na réplica (região B): assine e receba o stream
CREATE SUBSCRIPTION app_sub
CONNECTION 'host=primary.internal dbname=app'
PUBLICATION app_pub;
-- O número que define a sua janela de desatualização:
SELECT application_name,
now() - reply_time AS approx_lag
FROM pg_stat_replication;
Um primário, muitas regiões — o fluxo e o lag
Esta é a topologia cavalo de batalha — replica sets em bancos de documentos, réplicas em streaming nos relacionais — e os seus dois custos estão visíveis no diagrama. Latência de escrita: toda escrita viaja até a região do primário, então usuários distantes pagam a travessia do oceano justamente nas ações que mudam dados. Lag: streams entre regiões são assíncronos — replicação síncrona somaria a ida e volta completa a cada commit —, então as réplicas ficam para trás de milissegundos a segundos, e as leituras podem estar desatualizadas nessa medida. A mordida clássica é o read-your-own-writes: salvar, atualizar contra a réplica local, não ver nada. Os remédios são política de roteamento, não mágica — mande as leituras pós-escrita do usuário para o primário, ou fixe a sessão dele até a réplica alcançar.
O passo seguinte — múltiplos primários de escrita — localiza também as escritas, mas compra a mercadoria mais difícil do teorema CAP: escritas concorrentes e conflitantes em regiões diferentes precisam ser detectadas e resolvidas. Cargas livres de conflito (dados por usuário, streams append-only) vestem bem isso; estado mutável compartilhado veste mal.
Região única vs. réplicas de leitura vs. multi-primário
| Dimensão | Região única | Primário + réplicas regionais | Multi-primário |
|---|---|---|---|
| Latência de leitura (global) | Distante para a maioria | Local em toda parte | Local em toda parte |
| Latência de escrita | Local para uma região | Entre regiões, até o primário | Local em toda parte |
| Consistência | A mais simples | Lag nas leituras de réplica | Exige resolução de conflitos |
| Queda de região | Indisponibilidade | Failover para uma réplica | Continua atendendo |
| Complexidade | A menor | Moderada | A maior — respeite isso |
| Serve para | Usuários concentrados, estágio inicial | Leitores globais, um caminho de escrita | Escritores globais, dados mescláveis |
A leitura honesta da tabela: cada coluna à direita troca simplicidade por localidade. A maioria dos produtos deveria ficar na coluna mais à esquerda que atenda aos seus números de latência e disponibilidade — e muitos descobrem que um CDN para os ativos mais uma região de banco bem escolhida já atendem, já que o peso estático costuma dominar o tempo de carregamento percebido.
Casos de uso comuns
- Produtos globais de leitura intensa. Catálogos, conteúdo, dashboards — tráfego dominado por navegação, em que réplicas regionais convertem oceanos em milissegundos de um dígito.
- Bases regionais com cauda global. Primário na região do mercado principal, réplicas onde vive a cauda.
- Disaster recovery e failover. Uma cópia atual em outra região como história de disponibilidade — valiosa mesmo quando a latência nunca justificou réplicas.
- Residência de dados. Manter os dados de determinados tenants em jurisdições específicas — particionamento com consciência de tenant por região, um primo de política da replicação.
- Seguro de portabilidade. Replicar sobre engines open-source mantém a topologia sua — um hedge silencioso contra vendor lock-in que bancos globais proprietários não oferecem.
Você deveria ir multi-região? Matriz de decisão
| Multi-região se paga quando… | Fique em região única quando… |
|---|---|
| Uma população distante de usuários sofre de forma mensurável | Os usuários se concentram numa geografia |
| A latência de leitura domina e as leituras superam em muito as escritas | O produto é pré-lançamento ou pré-tração |
| A queda de uma região é risco existencial | Consultas lentas, e não distância, causam a latência |
| Contratos exigem residência ou DR regional | Um CDN já resolveu a lentidão percebida |
| Você consegue bancar a operação adicional | O time ainda está entregando o produto principal |
A ordem do diagnóstico importa: perfile as consultas e adicione índices primeiro, agrupe os padrões de requisição tagarelas em segundo, coloque os ativos estáticos num CDN em terceiro, posicione bem a sua região única em quarto — e replique em quinto, quando a latência restante for genuinamente geográfica. Times que pulam direto para o quinto herdam problemas de sistemas distribuídos enquanto o gargalo real era uma consulta sem índice.
Limitações e trade-offs
- O lag é estrutural. Streams assíncronos ficam para trás por projeto; toda leitura em réplica carrega uma janela de desatualização que o seu produto precisa tolerar ou contornar por roteamento.
- As escritas continuam cruzando o oceano. Topologias de primário único localizam apenas as leituras — o checkout, o post, a reserva continuam pagando a distância.
- Failover é um procedimento, não uma promessa. Promoção, cutover e o risco de perder escritas não replicadas (RPO de novo) — faça o simulado antes de acreditar.
- Multi-primário importa conflitos. Escritas concorrentes no mesmo registro em duas regiões precisam ser mescladas de algum jeito; “a última escrita vence” é uma política de perda de dados vestida de padrão.
- O custo escala com as cópias. Armazenamento, tráfego entre regiões e a atenção de engenharia de mais um sistema distribuído — precificados com honestidade, por região.
- Replicação não é backup. Toda réplica copia fielmente os seus erros em segundos; point-in-time recovery existe para a classe de falha que a replicação espalha.
Multi-região e latência no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A mecânica de replicação mora abaixo do seu código: o banco gerenciado roda sobre infraestrutura replicada com failover tratado pela plataforma, e a escolha de região na criação do app coloca o primário onde os seus usuários estão — a decisão de latência de maior alavancagem que este artigo recomenda tomar primeiro. Como a stack é open source de ponta a ponta, a topologia continua portátil: o mesmo Parse Server e os mesmos engines de banco rodam onde quer que você venha a precisar de uma região que o menu da plataforma não liste.
Perguntas frequentes
O que é replicação de banco de dados multi-região?
Manter cópias de um mesmo banco em regiões geográficas diferentes e transmitir as mudanças entre elas. Na topologia comum, um primário numa região aceita todas as escritas enquanto réplicas em outros lugares atendem leituras de usuários próximos. Os objetivos são menor latência de leitura — dados fisicamente mais perto dos usuários — e sobreviver a uma região inteira apagar, ao preço de lag de replicação e complexidade operacional.
Por que a distância aumenta a latência das consultas?
Física antes de software: sinais cruzam oceanos em dezenas de milissegundos por trecho, e uma ida e volta transatlântica custa algo na ordem de 70–100 ms antes de qualquer trabalho de banco. Uma requisição tagarela que faz cinco consultas sequenciais paga esse pedágio cinco vezes. A replicação ataca o problema aproximando os dados dos usuários; a alternativa é fazer menos idas e voltas, agrupadas.
O que é lag de replicação?
O atraso entre uma escrita commitar no primário e aparecer numa réplica — tipicamente bem abaixo de um segundo dentro da mesma região, e mais variável entre regiões e sob carga. O lag é o motivo de um usuário criar um registro, atualizar a tela contra uma réplica local e não vê-lo. Replicação entre regiões é assíncrona na prática, então algum lag é estrutural, não um bug a consertar.
O que é localidade de leitura vs. latência de escrita?
A troca central da topologia de primário único. Réplicas tornam as leituras locais em toda parte — vitória para produtos de navegação intensa. As escritas continuam viajando até a região do primário, então usuários distantes pagam latência entre regiões justamente nas ações que mudam dados. Topologias multi-primário localizam também as escritas, mas importam resolução de conflitos: duas regiões passam a poder alterar o mesmo registro ao mesmo tempo.
Leituras em réplicas retornam dados desatualizados?
Podem, na medida do lag. A maioria das leituras tolera isso — feeds, catálogos, dashboards. A falha clássica é o read-your-own-writes: o usuário salva, depois lê de uma réplica que não alcançou o primário, e a mudança dele parece perdida. Remédios padrão: rotear para o primário as leituras que seguem uma escrita do usuário, fixar a sessão no primário por um curto período após escrever, ou exigir réplicas atualizadas além da última escrita daquele usuário.
Multi-região é a mesma coisa que CDN?
Mesmo instinto — aproximar as coisas dos usuários —, camada e dificuldade diferentes. Um CDN replica ativos estáticos imutáveis, onde cópias não podem conflitar e a desatualização é administrada por expiração de cache. Replicação de banco move estado mutável, importando questões de consistência, lag e conflito que um CDN nunca enfrenta. Muitos produtos obtêm a maior parte do ganho percebido com um CDN mais uma única região de banco bem escolhida.
Quando multi-região é exagero?
Quando os usuários se concentram numa geografia, quando o produto é pré-lançamento, ou quando as reclamações de lentidão vêm de consultas lentas e APIs tagarelas, e não de distância. Um banco de região única bem indexado atrás de um CDN atende uma parcela notável dos produtos de sucesso. Multi-região paga a própria complexidade quando uma população distante de usuários sofre de forma mensurável — e escolher bem a região única vem antes.
Um backend gerenciado cuida da replicação por mim?
Da mecânica, sim: bancos gerenciados replicam para durabilidade e failover como rotina, e os planos da plataforma distribuem infraestrutura entre regiões. O que continua seu é a geografia: saber onde estão os seus usuários, escolher onde os dados devem morar e decidir se as leituras distantes justificam réplicas. A plataforma roda a topologia; o produto a decide.