Pular para o conteudo principal

Fila justa vs throughput em semáforos por recurso sem fingir que dá para maximizar tudo

Quando o backend protege recurso escasso, tentar ser perfeitamente justo e perfeitamente eficiente ao mesmo tempo costuma produzir o pior dos dois mundos.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

O problema

Quando o recurso fica escasso, não basta limitar concorrência.

Também precisa decidir:

  • quem entra primeiro
  • quem espera mais
  • quem pode ser ultrapassado

É aí que aparece um conflito real:

  • fila mais justa
  • throughput maior

Muita gente trata isso como detalhe de implementação.

Não é.

É política operacional.

Modelo mental

Fila justa tenta preservar previsibilidade de atendimento.

Fila otimizada para throughput tenta maximizar quantas unidades o sistema fecha por janela.

Essas duas metas às vezes andam juntas.

Às vezes não.

Se um job pesado bloqueia dez leves atrás dele, justiça estrita machuca throughput.

Se o sistema só prioriza o que termina rápido, certos trabalhos envelhecem na fila até virarem starvation.

A arquitetura precisa escolher qual injustiça aceita.

Exemplo simples

Imagine um worker que processa exportações.

Há dois tipos de trabalho:

  • relatórios pequenos que acabam em segundos
  • exportações gigantes de contas enterprise

Se a fila for estritamente FIFO:

  • ordem fica simples
  • relatórios pequenos podem esperar atrás de exportações longas

Se a fila favorecer só jobs curtos:

  • throughput médio sobe
  • os jobs longos podem ficar sendo empurrados indefinidamente

Nenhum dos dois lados é neutro.

O erro comum

O erro comum é dizer:

  • “a fila decide isso sozinha”

Não decide.

A fila só executa a política que alguém embutiu nela, mesmo que sem querer.

Outro erro comum é buscar justiça perfeita e throughput máximo como se desse para ter tudo ao mesmo tempo.

Quase sempre, o sistema precisa escolher:

  • previsibilidade maior
  • vazão maior
  • prioridade de certas classes

Sem assumir isso explicitamente, a arquitetura vira refém do comportamento default.

O que normalmente ajuda

Normalmente ajuda separar:

  • tráfego online
  • trabalho de fundo
  • jobs longos
  • jobs curtos

Também ajuda combinar mecanismos como:

  • FIFO por classe
  • prioridade por tipo de trabalho
  • envelhecimento para evitar starvation
  • limite de tamanho por fila
  • recusa ou degradação para extremos

A ideia não é achar a fila perfeita.

É evitar que a política fique implícita.

Como um senior pensa

Quem já operou backend sob pressão costuma perguntar:

  • o que eu estou otimizando aqui: previsibilidade ou vazão?
  • existe classe de trabalho que pode ficar invisivelmente para trás?
  • esse ganho de throughput está machucando qual grupo?
  • a fila que escolhi ainda faz sentido para o produto ou só para a métrica média?

Essa conversa impede muita arquitetura de parecer eficiente só porque esconde quem perdeu.

Ângulo de entrevista

Esse tema aparece em semáforos, workers, schedulers, filas internas e multi-tenant.

O entrevistador quer ver se você entende:

  • que política de fila é decisão de produto e operação, não só de infraestrutura
  • que fairness e throughput nem sempre são compatíveis
  • que starvation é bug de arquitetura, não azar

Resposta forte costuma soar assim:

“Eu escolheria a política de fila conforme o tipo de trabalho e o que o sistema quer proteger. Se throughput bruto começar a empurrar uma classe inteira para starvation, eu prefiro perder um pouco de vazão e ganhar previsibilidade controlada.”

Takeaway direto

Toda fila favorece alguém.

Arquitetura madura decide isso de forma explícita.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Transação e fechamento de fronteira: o que fica dentro e o que deve sair Artigo anterior Feature flag no backend sem espalhar if pelo sistema inteiro

Continue explorando

Artigos relacionados