Back to blog

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

6 min read5 FAQs

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:

  1. tirar trabalho lento do caminho da requisição
  2. absorver picos sem falhar rápido demais
  3. repetir automaticamente as falhas transitórias (retry)
  4. 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

NecessidadeFila é um bom encaixeFila é um mau encaixe
Absorção de picosSimNão
Desacoplamento temporário de uma dependência lentaSimNão
Execução única garantida sem salvaguardas na aplicaçãoNãoSim
Ordenação determinística em todo o trabalhoRaramenteNormalmente
Trabalho longo com checkpointsSimNão
Consistência imediata visível para o usuárioNãoSim

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 é:

  1. mover falhas repetidas para uma DLQ após um limiar definido
  2. classificar a causa raiz
  3. corrigir o problema sistêmico, se existir
  4. fazer redrive apenas das mensagens seguras para reprocessar
  5. 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ãoO que protegeTrade-off
Unique constraint no ID do eventoInserts duplicadosExige identificadores estáveis
Tabela de deduplicação com TTLProcessamento repetido dentro de uma janelaPrecisa de política de retenção
Máquina de estados com transições permitidasUpdates repetidos ou fora de ordemExige modelagem de domínio mais forte
Padrão inboxSegurança de replay no lado do consumidorArmazenamento e consultas extras
Padrão outboxPublicação confiável no lado do produtorAdiciona 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

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.