Consistência eventual, explicada para o time de produto
Por que o pedido aparece três segundos depois, quais fluxos nunca podem atrasar e como fazer uma UI que diz a verdade.
Uma gerente de produto me perguntou uma vez por que um usuário conseguia criar um pedido, abrir a lista de pedidos e não ver o pedido por três segundos. Ela não estava pedindo uma aula de sistemas distribuídos. Queria saber se era bug. A resposta honesta é: depende do que a gente prometeu, e a gente nunca escreveu a promessa.
Este artigo é a versão dessa conversa que eu gostaria de ter dado da primeira vez.
O que "eventual" quer dizer de verdade
Num sistema com mais de uma cópia dos dados, as escritas vão para um lugar e as leituras podem vir de outro. As cópias se alcançam, geralmente em milissegundos, às vezes em segundos, ocasionalmente em minutos quando algo está doente. "Eventualmente consistente" significa que as cópias vão concordar, mas não agora.
A lista mostrando o pedido três segundos depois não é o banco mentindo. É uma leitura servida por uma réplica, um índice de busca ou um cache que ainda não recebeu a escrita. Nada foi perdido. O usuário só olhou para uma cópia atrasada.
As duas garantias que o usuário sente de verdade
Usuário não liga para modelo de consistência. Liga para duas experiências específicas, e as duas têm nome.
Read-your-writes: se eu acabei de fazer algo, eu preciso ver. Criei o pedido, então minha lista precisa incluir ele. Quebrar isso faz o usuário achar que a ação falhou, então ele repete, e agora tem dois pedidos. É a garantia que mais importa para qualquer coisa que o usuário acabou de tocar.
Leituras monotônicas: eu nunca deveria ver o tempo andar para trás. Se a lista mostrou cinco itens e eu atualizo, não pode mostrar quatro. Isso quebra quando leituras consecutivas caem em réplicas com atrasos diferentes. Parece dado sumindo, e destrói a confiança mais rápido do que uma página lenta.
As duas podem ser garantidas sem tornar o sistema inteiro fortemente consistente. Direcione as leituras do próprio usuário para o primário por uma janela curta depois de uma escrita. Fixe a sessão numa réplica só. Ou, o mais simples de tudo, atualize a UI com a resposta que você já tem em vez de buscar de novo.
Quais fluxos podem atrasar e quais não podem
Nem todo fluxo merece a mesma garantia, e fingir que sim é como sistemas ficam lentos e caros. A regra que uso: qualquer coisa que movimenta dinheiro, reserva um recurso escasso ou concede acesso precisa ser fortemente consistente no momento da decisão. Cobrar um cartão, reservar o último assento, baixar estoque, checar uma permissão. Isso lê da fonte da verdade, sob lock ou transação, e aceita o custo de latência.
Quase todo o resto pode atrasar. Dashboards de analytics, o índice de busca, a notificação de "seu pedido foi enviado", o feed de recomendação, a contagem de mensagens não lidas. Se o resultado da busca está dois segundos atrasado, ninguém se machuca. Se o estoque está dois segundos atrasado, você vende o mesmo item duas vezes.
Quando o time de produto classifica os fluxos assim, a engenharia gasta consistência onde importa e velocidade em todo o resto.
Uma UI que diz a verdade
A pior opção é uma UI que finge. Mostra um spinner, a requisição volta, a lista busca de novo numa réplica atrasada, e o item não está lá. O usuário agora está confuso e o sistema não fez nada de errado.
UI otimista é o padrão melhor para ações iniciadas pelo usuário: mostre o item na hora com os dados que você já tem, marque de forma sutil como pendente se o backend não confirmou, e reconcilie quando a confirmação chegar. Se a escrita falhar, remova e diga isso.
Estados pendentes são honestos. "Pagamento em processamento" é melhor do que um check verde que depois é revogado. "Seu relatório vai ficar pronto em instantes" é melhor do que um dashboard vazio que se preenche em silêncio.
A promessa para escrever é simples: em cada tela, o que o usuário acabou de fazer precisa aparecer na hora, o que os outros fizeram pode estar alguns segundos atrasado, e nada nunca anda para trás. Entregue isso, e a pergunta dos três segundos deixa de ser um bug report.