Você clica no botão de pagamento, mas a tela fica travada por um bom tempo. Dá ansiedade. Você quer clicar de novo.
Mas clicar duas vezes não vai cobrar duas vezes?
Em um sistema bem projetado, não. A propriedade que garante isso tem nome.
Idempotência.
Esse conceito aparece em documentação de backend, especificações HTTP e guias de API de pagamento, mas a definição cabe em uma linha. O difícil é entender “por que isso é tão importante” e “como implementar”.
Este artigo responde às duas perguntas.
Veja o resumo principal.
- Idempotência: propriedade de obter o mesmo resultado ao enviar uma requisição uma ou várias vezes
- Por que importa: redes falham, falhas exigem tentativas novamente e elas só são seguras quando a operação é idempotente
- No HTTP, GET, PUT e DELETE são idempotentes; POST não é
- O mecanismo prático que torna POST seguro é a Idempotency-Key
Definição: fazer várias vezes equivale a fazer uma vez
Idempotência é um termo da matemática. Se uma operação f satisfaz f(f(x)) = f(x), ela é idempotente.
A função valor absoluto é um bom exemplo. |−5| = 5 e |5| = 5.
O resultado é o mesmo, seja aplicada uma vez ou cem vezes.
Aplicando isso a uma API, temos o seguinte.
O estado do servidor é o mesmo, seja a mesma requisição enviada 1 vez ou N vezes.
Atenção: a resposta não precisa ser igual; o estado do servidor é que precisa ser. Mesmo que a segunda requisição DELETE retorne 404, ela é idempotente porque o estado “o recurso não existe” permanece igual.
Uma analogia cotidiana é o botão do elevador. Mesmo pressionando cinco vezes o botão do quinto andar, o elevador vai ao quinto andar uma única vez.
Por outro lado, se fosse um botão de “subir mais cinco andares”, o resultado mudaria a cada clique. O primeiro é idempotente; o segundo, não idempotente.
Por que importa: redes inevitavelmente falham
A importância da idempotência pode ser explicada por um único cenário.
O cliente envia uma requisição de pagamento. O servidor processa o pagamento.
Mas a rede cai enquanto a resposta está voltando.
O cliente não tem como saber se a requisição falhou antes de chegar ao servidor (pagamento não realizado) ou se apenas a resposta foi perdida depois do processamento (pagamento realizado).
Nos dois casos, o resultado parece exatamente um timeout.
Só existem duas opções: desistir da tentativa novamente (o pagamento pode não ter acontecido) ou tentar novamente (se já aconteceu, haverá cobrança duplicada). As duas são péssimas.
A idempotência elimina esse dilema. Se a requisição for idempotente, “se não souber, envie de novo” será sempre uma estratégia segura.
Tentativas automáticas, entrega pelo menos uma vez (at-least-once) em filas de mensagens e atualizações repetidas no cliente deixam de ser motivo de preocupação.
É por isso que documentos de arquitetura de sistemas distribuídos repetem: “configure tentativas novamente apenas para operações idempotentes”.
Idempotência nos métodos HTTP
A especificação HTTP (RFC 9110) define a idempotência de cada método.
| Método | Idempotente? | Motivo |
|---|---|---|
| GET | O | A consulta não altera o estado |
| PUT | O | “Substituir por este valor” produz o mesmo valor todas as vezes |
| DELETE | O | “Excluir” deixa o estado excluído todas as vezes |
| POST | X | “Criar um novo” aumenta um a cada chamada |
| PATCH | Condicional | “Definir este campo como X” é idempotente; “somar 1” não é |
O contraste entre PUT e POST é essencial. PUT especifica o “estado resultante”, então é idempotente; POST especifica uma “ação”, então não é.
PATCH depende do conteúdo.
Quando o navegador volta a uma página POST pelo botão Voltar e pergunta “Deseja reenviar este formulário?”, é porque sabe que reenviar POST não é seguro.
O mecanismo prático: chaves de idempotência
Mas cadastro, criação de pedido e pagamento são essencialmente operações POST. Não é possível evitar operações não idempotentes.
Por isso surgiu um mecanismo para tornar requisições não idempotentes idempotentes: a Idempotency-Key.
O funcionamento é simples.
- O cliente gera uma chave exclusiva para cada requisição (geralmente um UUID) e a envia em um cabeçalho
- Se for a primeira vez que vê a chave, o servidor processa normalmente e armazena a resposta junto com ela
- Se a mesma chave chegar novamente, o servidor não processa e devolve exatamente a resposta armazenada
Seja uma tentativa novamente ou um clique duplo, o servidor processa apenas uma vez enquanto a mesma chave for usada. APIs de pagamento como Stripe e Toss Payments oferecem suporte a esse cabeçalho e o tratam como item obrigatório em seus guias de integração.
Um detalhe no cliente: “use a mesma chave ao tentar novamente”.
Se você gerar uma chave nova a cada tentativa, o servidor verá cada uma como uma requisição diferente. A chave deve ser criada por “requisição com a mesma intenção”.
Resumo
- Idempotência é a propriedade de manter o mesmo estado do servidor, independentemente de quantas vezes a mesma requisição seja enviada (f(f(x)) = f(x))
- Quando uma falha de rede deixa você sem saber se algo foi concluído, a tentativa novamente só é segura se a operação for idempotente
- HTTP: GET, PUT e DELETE são idempotentes; POST não é; PATCH depende do conteúdo
- PUT é idempotente porque especifica o estado resultante; POST não é porque indica uma ação
- Torne um POST não idempotente idempotente com Idempotency-Key — a mesma chave é processada apenas uma vez
- Ao tentar novamente, sempre reutilize a mesma chave. A chave representa uma “requisição com a mesma intenção”

