Article
Filas não são bala de prata
Saiba quando filas ajudam e quando adicionam risco: garantias de entrega, DLQs, poison messages, ordenação e consumidores idempotentes na prática.
Article details
Published
August 19, 2026
Reading time
6 min
Main sections
14
Filas resolvem um problema real: desacoplam trabalho, absorvem picos e impedem que os caminhos voltados ao usuário fiquem esperando sistemas lentos a jusante. Mas elas não resolvem confiabilidade por conta própria. Se você adiciona uma fila sem idempotência, observabilidade, política de retry e um caminho de redrive, muitas vezes está apenas movendo a falha para um canto mais escuro do sistema.
O modelo mental útil é simples: uma fila é um buffer, não uma garantia. Ela pode melhorar resiliência e throughput, mas também introduz semânticas de entrega, processamento duplicado, ambiguidade de ordenação, poison messages e sobrecarga operacional.
Por que os times recorrem a filas
Os times costumam adicionar filas porque querem:
- tirar trabalho lento do caminho da requisição
- absorver picos sem falhar rápido demais
- repetir automaticamente as falhas transitórias (retry)
- isolar integrações caras ou instáveis
São boas razões. O erro é assumir que a fila removeu a falha, em vez de apenas realocá-la.
Garantias de entrega na prática
A primeira pergunta é qual garantia de entrega você está comprando de fato.
- at-most-once: mensagens podem se perder, mas duplicatas são raras
- at-least-once: duplicatas são esperadas, mas a perda é reduzida
- exactly-once: normalmente um efeito em nível de aplicação, não uma propriedade gratuita do transporte
Se os seus efeitos colaterais não toleram duplicatas, a fila não é onde a mágica acontece. Você precisa de consumidores idempotentes.
A Amazon documenta a entrega at-least-once do SQS diretamente, o que é útil porque elimina a última desculpa para fingir que entrega duplicada é algo incomum.
Matriz de decisão prática
| Necessidade | Fila é um bom encaixe | Fila é um mau encaixe |
|---|---|---|
| Absorção de picos | Sim | Não |
| Desacoplamento temporário de uma dependência lenta | Sim | Não |
| Execução única garantida sem salvaguardas na aplicação | Não | Sim |
| Ordenação determinística em todo o trabalho | Raramente | Normalmente |
| Trabalho longo com checkpoints | Sim | Não |
| Consistência imediata visível para o usuário | Não | Sim |
Esta matriz não é contra filas. É contra o pensamento mágico.
Os custos ocultos que os times subestimam
Processamento duplicado
Se um worker executa o efeito colateral e cai antes do acknowledgement, a mensagem pode ser entregue de novo. Esse é o comportamento normal de at-least-once, não um caso raríssimo.
Poison messages
Uma poison message falha repetidamente e queima retries, tempo e capacidade de worker em silêncio. Se não for isolada numa DLQ ou caminho equivalente, ela pode transformar um payload ruim em um incidente amplo.
Suposições de ordenação
A ordenação costuma quebrar assim que você adiciona retries, consumidores paralelos ou particionamento. Se a ordem importa, defina exatamente qual entidade precisa de ordem e como o processamento fora de ordem é corrigido.
Tempestades de retry
Retries ajudam até começarem a amplificar a carga. Uma dependência lenta dispara mais retries, o backlog cresce, a latência sobe e a fila começa a fabricar a própria indisponibilidade.
DLQs e redrive são recursos de operação
Dead-letter queues não são armazenamento. São uma válvula de segurança.
O guia da AWS sobre o uso de dead-letter queues no SQS é uma boa referência operacional porque trata a DLQ como um caminho de falha configurado, com comportamento explícito de redrive — e não como um depósito permanente de mensagens ruins.
O fluxo sadio é:
- mover falhas repetidas para uma DLQ após um limiar definido
- classificar a causa raiz
- corrigir o problema sistêmico, se existir
- fazer redrive apenas das mensagens seguras para reprocessar
- adicionar um teste ou alerta para que a mesma classe de falha fique visível na próxima vez
Se as entradas da DLQ acumulam sem revisão, o sistema não é resiliente. Está apenas escondendo trabalho.
Consumidores idempotentes são inegociáveis
A forma mais limpa de tornar uma fila segura é desenhar o consumidor para que a entrega repetida seja inofensiva.
| Padrão | O que protege | Trade-off |
|---|---|---|
| Unique constraint no ID do evento | Inserts duplicados | Exige identificadores estáveis |
| Tabela de deduplicação com TTL | Processamento repetido dentro de uma janela | Precisa de política de retenção |
| Máquina de estados com transições permitidas | Updates repetidos ou fora de ordem | Exige modelagem de domínio mais forte |
| Padrão inbox | Segurança de replay no lado do consumidor | Armazenamento e consultas extras |
| Padrão outbox | Publicação confiável no lado do produtor | Adiciona complexidade ao caminho de escrita |
Se você quer a versão mais profunda desse princípio, leia Idempotência para webhooks.
O padrão idempotent consumer é a referência externa mais limpa para esta seção porque deixa explícita a responsabilidade em nível de aplicação: a entrega pode se repetir, então o efeito não pode.
Como é um runbook sadio de fila
Este checklist deveria existir antes de a fila ficar importante:
- defina o propósito da fila em uma frase
- documente as garantias de entrega esperadas
- defina a política de retry e o número máximo de tentativas
- especifique o limiar de DLQ e o processo de redrive
- registre quais mensagens são seguras para reprocessar
- defina quais efeitos colaterais precisam ser idempotentes
- acompanhe a profundidade do backlog, a idade da mensagem mais antiga, a taxa de falha e a contagem de redrives
- designe um responsável pela intervenção manual
Esse runbook deveria viver perto do código, não num wiki esquecido.
Quando filas ajudam
Filas ajudam quando o trabalho é:
- assíncrono por natureza
- seguro para retry
- não imediatamente visível para o usuário
- delimitado por uma política clara de falha
Exemplos incluem notificações, enriquecimento em background, processamento de mídia e integrações instáveis com terceiros.
Quando a fila é a resposta errada
Uma fila costuma ser a resposta errada quando:
- o fluxo precisa de consistência imediata
- o efeito colateral não pode ser repetido com segurança
- a ordenação estrita é um requisito de negócio
- o time não consegue se comprometer a operar retries e DLQs
Se qualquer um desses pontos for verdade, um fluxo síncrono, uma fronteira transacional mais forte ou um design diferente de workflow pode ser a melhor escolha.
Como este tema se conecta
Se você quer a lente mais ampla da arquitetura async, leia Sistemas event-driven sem folclore. Se você quer a camada de deduplicação e processamento repetido, leia Idempotência para webhooks. E se você quer a camada de visibilidade operacional, leia Observabilidade para engenheiros de produto.
Related articles
Article
Sistemas event-driven sem folclore
Leia também: Sistemas event-driven sem folclore, Idempotência para webhooks e Arquitetura serverless AWS para integrações.
Article
Idempotência para webhooks
Leia também: Sistemas event-driven sem folclore, Idempotência para webhooks e Arquitetura serverless AWS para integrações.
Article
Arquitetura serverless AWS para integrações
Leia também: Sistemas event-driven sem folclore, Idempotência para webhooks e Arquitetura serverless AWS para integrações.
Need help applying this?
Turn the trade-off into a practical product decision.
Se o seu time está decidindo se a fila está ajudando ou só escondendo falha, vale olhar o sistema inteiro antes de adicionar mais uma. Comece com um get in touch.
FAQ
Common questions before committing to the pattern.
Filas são mais confiáveis que chamadas síncronas?+
Não automaticamente. Filas trocam uma classe de falha por outra. Só ajudam se retries, idempotência e monitoramento forem desenhados juntos.
Qual é a diferença entre retries e DLQ?+
Retries são tentativas repetidas de processar uma mensagem. Uma DLQ é para onde a mensagem vai após falha repetida, ou quando não é mais seguro continuar tentando.
Como sei se o meu consumidor é idempotente?+
Se processar a mesma mensagem duas vezes pode criar efeitos colaterais duplicados, ele não é idempotente.
Toda fila deveria preservar a ordem?+
Não. Ordenação é cara e frequentemente desnecessária. Exija apenas quando a lógica de negócio realmente depende dela.
O que monitorar primeiro?+
Profundidade do backlog, idade da mensagem mais antiga, taxa de falha, volume da DLQ e tentativas de redrive. Eles dizem rapidamente se a fila está absorvendo trabalho ou escondendo um incidente.