O que é deduplicação e por que ela é necessária
Processar o mesmo evento duas vezes pode ser catastrófico
Deduplicação é o processo de identificar e descartar cópias de uma mesma operação antes que sejam processadas novamente. Em sistemas distribuídos, mensagens chegam duplicadas com frequência: por retransmissões TCP, reenvios de clientes após timeout, reentregas de filas com garantia "ao menos uma vez" ou falhas parciais que deixam o sistema em estado incerto. Sem deduplicação, cobranças duplicam, emails são enviados duas vezes, pedidos são criados em dobro — efeitos diretos que o usuário percebe e que custam dinheiro, suporte e reputação para corrigir.
A diferença entre deduplicação e idempotência
Idempotência é sobre o resultado; deduplicação é sobre o rastreamento
Idempotência garante que executar uma operação múltiplas vezes produz o mesmo resultado que executar uma vez. Deduplicação é o mecanismo que detecta ativamente quando uma operação já foi processada e a descarta. Idempotência é uma propriedade do design; deduplicação é uma implementação de rastreamento. Na prática, funcionam juntas: a operação é desenhada para ser idempotente (resultado consistente), e a deduplicação garante que só execute uma vez (prevenção ativa). Em filas de mensagens, por exemplo, o worker precisa dos dois: idempotência no processamento e deduplicação para evitar reprocessamento.
Fontes de duplicação em produção
Onde duplicatas surgem e por que são inevitáveis
As principais fontes de duplicação em sistemas reais são: clientes com retry automático após timeout sem saber se a requisição chegou ao servidor, filas de mensagens com garantia "ao menos uma vez" (SQS, RabbitMQ padrão) que reentregam quando o consumer não confirma a tempo, reprocessamentos após falhas de infraestrutura como reinícios de pod ou crash do worker no meio de uma operação, e webhooks que reenviam quando o receptor retorna erro ou demora para responder. Duplicação não é um bug de implementação — é um comportamento esperado de redes e sistemas distribuídos. O bug é não estar preparado para ela.
Chaves de deduplicação — identificando o que já foi processado
Um identificador único que representa a intenção, não a tentativa
A estratégia central é criar ou exigir um identificador único para cada operação de negócio — chamado de deduplication key, message ID ou idempotency key. Esse identificador deve ser gerado pelo originador (não pelo processador), persistido antes de qualquer side effect, e verificado no início de cada processamento. Para filas como SQS FIFO, o MessageDeduplicationId faz isso automaticamente dentro de uma janela de 5 minutos. Para outras filas, o worker precisa implementar: armazenar o ID do evento em banco ou cache, verificar antes de processar, e só então executar a operação de negócio.
Armazenamento do estado de processamento
Redis, banco de dados ou tabela dedicada — cada um com seus trade-offs
Para rastrear quais eventos já foram processados, as opções mais comuns são: Redis com TTL (eficiente para grandes volumes, mas perde dados se reiniciar sem persistência), tabela dedicada no banco relacional com index no deduplication_key (durável, transacional, mais lento), DynamoDB com TTL e ConditionalExpression (para sistemas AWS), e coluna no próprio registro do domínio (quando o evento mapeia diretamente para um registro único no sistema, como um orderId). A escolha depende do volume, da latência aceitável e de quanto tempo é necessário guardar o estado — geralmente 24h a 7 dias é suficiente.
Race conditions na deduplicação
Dois workers processando o mesmo evento ao mesmo tempo
O cenário mais perigoso é dois workers consumindo o mesmo evento simultaneamente antes que qualquer um salve o registro de processamento. A solução é garantir atomicidade na verificação e no registro: usar INSERT ... ON CONFLICT DO NOTHING (PostgreSQL), SET NX no Redis (set if not exists), ou uma transação que verifica e insere de forma atômica. Sem isso, a janela de tempo entre "verificar se existe" e "inserir registro" permite que dois workers passem ao mesmo tempo pela verificação — e ambos processem o evento. Em filas com consumidores paralelos, essa race condition é mais comum do que parece.
Deduplicação em webhooks externos
Gateways de pagamento, serviços de email e notificações podem reenviar
Sistemas externos como gateways de pagamento (Stripe, Mercado Pago), serviços de email (SendGrid, Postmark) e plataformas de mensagens (WhatsApp Business API) enviam webhooks com reenvio automático quando o receptor não responde com 200 dentro de alguns segundos. Para deduplicar, use o ID do evento fornecido pelo serviço externo (exemplo: evt_123 do Stripe) como deduplication key. Retorne 200 imediatamente ao receber o webhook, coloque o processamento em fila assíncrona, e deduplique no worker usando esse ID. Dessa forma, o gateway considera entregue e o sistema processa exatamente uma vez.
Janela de deduplicação e TTL adequado
Quanto tempo manter o registro de eventos processados
Guardar o registro de processamento para sempre é impraticável — cresce indefinidamente e gera custo de armazenamento. A janela de deduplicação deve cobrir o tempo máximo em que uma duplicata pode chegar: para retries de cliente, 24h é o padrão comum (Stripe usa exatamente isso). Para reentregas de fila, o TTL do registro deve ser maior que a janela de visibilidade máxima da fila. Para webhooks, considerar o tempo máximo de retry do serviço externo (Stripe tenta por 72h). Deduplication keys expiradas permitem que operações com o mesmo ID sejam processadas novamente após o período — o que geralmente é o comportamento correto.
Testando deduplicação antes de ir para produção
Como simular duplicatas para garantir que o sistema está protegido
Testar deduplicação exige provocar as situações reais: enviar a mesma mensagem duas vezes para a fila e verificar que só um efeito aconteceu, reenviar a mesma requisição HTTP com a mesma chave e confirmar que o segundo retorno é idêntico ao primeiro sem processar novamente, e simular crash do worker após processar mas antes de confirmar para verificar que o reprocessamento na reentrega é seguro. Testes unitários validam a lógica de verificação; testes de integração validam o comportamento real com concorrência e reentregas. Deduplicação sem teste é só esperança de que vai funcionar.
Conclusão — deduplicação como proteção estrutural
Não é opcional para sistemas que precisam de confiabilidade real
Deduplicação não é uma otimização para ser adicionada depois — é uma proteção estrutural obrigatória em qualquer sistema que lida com dinheiro, comunicações ou dados críticos. Os padrões são estabelecidos, as ferramentas estão disponíveis e o custo de implementar é baixo comparado ao custo de corrigir duplicatas em produção. Comece pela fonte mais provável no seu sistema — webhook externo, fila de mensagens ou retry de cliente — e proteja de dentro para fora. Continue em: Fundamentos obrigatórios antes de produção.
Deduplicação em Sistemas Distribuídos — Vídeos
Message deduplication — Messaging in distributed systems | DevMentors EN
Idempotency in Cows and REST APIs — entendendo deduplicação via idempotência
Idempotency Explained — REST API e deduplicação na prática
Idempotency in APIs Explained — como evitar processamento duplicado
Algorithms You Should Know For System Design — ByteByteGo
Kafka In 3 Minutes — sistema de streaming com deduplicação nativa
Deduplicação e Sistemas Distribuídos no Instagram
Deduplication Key
Identificador único gerado pelo originador para identificar uma operação de negócio, independente da tentativa de envio.
Entrega ao menos uma vez
Garantia de filas como SQS e RabbitMQ padrão — pode entregar duplicatas, exige deduplicação no consumer.
SET NX (Redis)
Operação atômica set-if-not-exists no Redis — base para implementar deduplicação sem race condition.
TTL de deduplication key
Tempo de expiração do registro de processamento — normalmente 24h a 7 dias dependendo do contexto.
INSERT ON CONFLICT
Instrução SQL (PostgreSQL) que insere apenas se não existir conflito — garante atomicidade na verificação.
Webhook deduplication
Usar o ID do evento externo (ex: evt_stripe) como chave para evitar processar o mesmo pagamento duas vezes.
Deduplicação e Sistemas Distribuídos no X
@bytebytego
Reels — Sistemas e Arquitetura
@bytebytego
ByteByteGo no Facebook
Referências e Leituras Recomendadas
Como testar que sua API é resiliente e segura para produção real
Ver post completo no X →Implementando padrões de resiliência em .NET Core com exemplos reais
Ver post completo no X →Vertical Slice Architecture — organizando sistemas para escala
Ver post completo no X →5 anos com Clean Architecture — lições de sistemas em produção
Ver post completo no X →Design de APIs resilientes — retry, backoff e idempotência juntos
Ver post completo no X →Monolito vs Microsserviços — como escolher para cada contexto
Ver post completo no X →O que dizem