15 de Maio de 2025
Deduplicação e Idempotencia no Código
Como impedir que retry, mensagem repetida e clique duplicado virem efeito colateral duplo dentro da implementação real.
Andrews Ribeiro
Founder & Engineer
4 min Intermediario Sistemas
O problema
Uma operação chega duas vezes e o sistema faz duas vezes.
Esse resumo parece bobo, mas ele explica muito incidente real.
Exemplos comuns:
- usuário clica duas vezes em “pagar”
- cliente recebe timeout e faz retry
- webhook chega duplicado
- mensagem reaparece na fila
Se o código foi escrito com a fantasia de “isso aqui vai chegar uma vez só”, o estrago aparece rápido:
- cobrança dupla
- email duplicado
- estoque baixado duas vezes
- job processado de novo
Modelo mental
Tem duas ideias parecidas, mas não iguais:
- deduplicação
- idempotencia
Deduplicação responde:
eu consigo reconhecer que essa mesma intenção já apareceu?
Idempotencia responde:
se ela aparecer de novo, o efeito final continua seguro?
Em muitos sistemas as duas andam juntas.
Mas vale separar para pensar melhor.
Quebrando o problema
Onde repetição nasce
Repetição pode nascer em vários pontos:
- no usuário
- no cliente HTTP
- na rede
- no broker
- no próprio backend apos falha parcial
Por isso proteção boa não depende de “educar o cliente”.
Ela entra no desenho do sistema.
Deduplicação reconhece a mesma intenção
Para deduplicar, você precisa de um identificador que represente aquela operação.
Pode ser:
idempotency_keyevent_idjob_id- combinação de campos de negócio
O ponto e conseguir responder:
- isso e realmente a mesma tentativa?
- ou e uma operação nova parecida?
Sem essa distincao, você corre o risco de colapsar coisas diferentes ou repetir o que era igual.
Idempotencia protege o efeito final
Reconhecer repetição não basta.
O sistema precisa garantir que repetir não aplique dano novo.
Exemplos:
- se o pagamento já foi criado, devolve o resultado anterior
- se o evento já foi aplicado, não baixa estoque de novo
- se o email daquele job já foi enviado, não dispara outra vez
Repare no foco:
não e impedir a função de rodar para sempre.
E impedir efeito colateral duplo.
Onde colocar a proteção
A proteção boa costuma morar perto do efeito importante.
Exemplos:
- cobrança: perto da escrita da cobrança
- consumo de evento: junto do registro de evento processado
- job: junto da mudança de status e persistencia do resultado
Se você deixa a proteção só na borda, mas o efeito acontece mais fundo, a janela para bug continua aberta.
Chave sem persistencia não resolve
Outro erro comum e gerar chave bonita e não registrar nada com ela.
Se o sistema não persiste:
- que a operação já ocorreu
- qual foi o resultado
- ou qual evento já foi consumido
entao a chave vira só decoração.
Exemplo simples
Imagine um webhook payment.confirmed com event_id=evt_9.
Fluxo ruim:
- consumidor recebe evento
- baixa estoque
- envia email
- confirma consumo
Se o processo cai depois do passo 3 e antes da confirmação, a mensagem pode reaparecer.
Sem proteção, o estoque cai de novo e o email duplica.
Fluxo melhor:
- consumidor verifica se
evt_9já foi processado - se não foi, aplica o efeito e registra
evt_9 - se já foi, sai sem repetir dano
Dependendo do caso, o registro do event_id e o efeito importante precisam acontecer na mesma transação ou no arranjo mais confiavel que o sistema permitir.
Não porque o sistema vai ficar perfeito.
Mas porque a janela de duplicidade cai bastante.
Erros comuns
- Confiar só em desabilitar botao no frontend.
- Achar que deduplicação e a mesma coisa que lock.
- Guardar identificador sem vincular ao efeito aplicado.
- Fazer retry agressivo sem plano para repetição.
- Usar hash improvisado de payload e chamar isso de certeza de unicidade.
Como um senior pensa
Quem tem mais experiência não pergunta primeiro “como evitar repetir request?”.
Pergunta isto:
“Se repetir, onde o dano acontece e como eu provo para o código que essa intenção já foi aplicada?”
Essa mudança de foco e forte.
Sai da ilusão de controle da entrada e vai para a segurança do efeito.
O que o entrevistador quer ver
Em entrevista, esse assunto aparece muito em pagamento, webhook, fila e job assíncrono.
O avaliador quer ver se você consegue sair da teoria e descer para implementação.
Sinais bons:
- você diferencia deduplicação de idempotencia
- fala de chave ou identificador de negócio
- coloca a proteção perto da escrita importante
- menciona retry e reprocessamento como comportamento normal
Uma resposta forte costuma soar assim:
“Eu assumo que a mesma intenção pode chegar de novo. Entao guardo um identificador estavel, verifico se já foi aplicado e faco a escrita importante de forma que repetir não gere efeito novo.”
Sistema resiliente não e o que nunca recebe repetição. E o que não entra em panico quando ela aparece.
Resumo rápido
O que vale manter na cabeça
- Repetição pode vir de retry, timeout, fila ou clique duplo. O código precisa assumir isso como normal.
- Idempotencia protege o efeito final. Deduplicação ajuda a reconhecer que aquela intenção já apareceu.
- Nem toda operação precisa de lock. Muitas precisam de chave de negócio, registro de processamento e escrita segura.
- O lugar certo da proteção depende de onde o efeito colateral acontece de verdade.
Checklist de pratica
Use isto ao responder
- Consigo diferenciar deduplicação de idempotencia sem misturar os termos?
- Sei apontar onde guardar chave ou identificador de processamento?
- Consigo explicar por que retry sem proteção gera efeito colateral duplo?
- Sei descrever uma implementação segura para webhook, job ou pagamento?
Você concluiu este artigo
Compartilhar esta página
Copie o link manualmente no campo abaixo.