16 pontos por GN⁺ 2026-01-15 | 2 comentários | Compartilhar no WhatsApp
  • Rails 8 remove a dependência de Redis da stack padrão e passa a processar todo o trabalho com SolidQueue, SolidCache e SolidCable sobre um banco de dados relacional (RDB)
  • Redis é rápido e confiável, mas traz complexidade operacional em configuração, segurança, gerenciamento de cluster, backups etc.
  • SolidQueue implementa processamento paralelo sem contenção usando o recurso FOR UPDATE SKIP LOCKED do PostgreSQL
  • Oferece gratuitamente recursos pagos do Redis + Sidekiq, como tarefas periódicas, controle de concorrência e dashboard de monitoramento (Mission Control)
  • Para a maioria das aplicações Rails, o SolidQueue é suficiente; só alguns casos que exigem processamento ultrarrápido e em tempo real ainda precisam manter o Redis

O custo oculto do Redis

  • Além do custo simples de hospedagem, o Redis também impõe carga contínua de administração, como instalação, manutenção, configuração de segurança e gerenciamento de cluster HA
    • É necessário configurar conexão de rede e firewall entre Rails e Redis, autenticação de cliente e orquestração dos processos do Sidekiq
  • Quando ocorre uma falha, é preciso depurar Redis e RDBMS ao mesmo tempo, e também é necessária uma estratégia de backup dupla
  • Já em uma stack Rails sem Redis, basta gerenciar apenas o PostgreSQL, o que simplifica a operação

Como o SolidQueue funciona

  • Usa o recurso FOR UPDATE SKIP LOCKED do PostgreSQL para permitir que vários workers peguem tarefas ao mesmo tempo sem contenção de locks
  • Estrutura principal de tabelas
    1. solid_queue_jobs: armazena os metadados das tarefas
    2. solid_queue_scheduled_executions: fila de espera das tarefas agendadas
    3. solid_queue_ready_executions: fila de tarefas prontas para execução
  • Os processos de worker, dispatcher, scheduler e supervisor fazem polling periódico em tabelas diferentes e cooperam entre si
  • Graças ao design MVCC e ao autovacuum do PostgreSQL, até grandes volumes de inserções e exclusões podem ser processados com estabilidade

Agendamento de tarefas recorrentes

  • O SolidQueue oferece nativamente tarefas recorrentes no estilo cron, configuradas no arquivo config/recurring.yml
  • O scheduler coloca na fila as tarefas cujo momento de execução chegou e agenda automaticamente a próxima execução
  • Usa a biblioteca Fugit para interpretar agendas em linguagem natural e Concurrent::ScheduledTask para criar threads
  • Adota o modelo de agendamento determinístico do GoodJob, mantendo a agenda mesmo após reinícios do processo

Recurso de controle de concorrência

  • O SolidQueue usa o padrão de semáforo POSIX para limitar a execução simultânea por unidade de trabalho
    • Exemplo: com limits_concurrency to: 1, key: ->(user) { user.id }, apenas 1 tarefa por usuário é executada por vez
  • É possível definir a expiração do semáforo (duration) para evitar conflitos entre tarefas e deadlocks
  • Tabelas relacionadas
    • solid_queue_semaphores: rastreia os limites de concorrência
    • solid_queue_blocked_executions: armazena as tarefas em espera

Monitoramento com o Mission Control

  • Mission Control Jobs é um dashboard gratuito e open source para Rails 8, que pode ser montado facilmente na rota /jobs
  • Principais recursos
    • Estado das filas em tempo real, rastreamento de tarefas com falha e controle de retry/descartar
    • Visualização da linha do tempo de tarefas agendadas e recorrentes
    • Gráficos de métricas e throughput por fila
  • Também permite consultas baseadas em SQL, possibilitando análise direta no banco de dados sem ferramentas adicionais

Migração de Sidekiq para SolidQueue

  • Etapa 1: definir config.active_job.queue_adapter = :solid_queue
  • Etapa 2: executar bundle add solid_queue, depois rails solid_queue:install e db:migrate
  • Etapa 3: converter os agendamentos cron de sidekiq.yml para recurring.yml
  • Etapa 4: adicionar jobs: bundle exec rake solid_queue:start ao Procfile
  • Etapa 5: remover as gems relacionadas a Redis e Sidekiq
  • O código existente em ActiveJob continua funcionando sem modificações

Quando o Redis ainda é necessário

  • Processamento contínuo de milhares de tarefas por segundo
  • Sistemas em tempo real nos quais latência abaixo de 1 ms é indispensável
  • Necessidade de estruturas complexas de pub/sub ou rate limiting/operações de contador sofisticadas
  • Como exemplo, a Shopify opera com 833 requisições por segundo e 1.172 processos worker, usando infraestrutura com Redis

Guia prático de implementação

  • Ao criar um novo app em Rails 8, SolidQueue, SolidCache e SolidCable são configurados automaticamente
  • Recomenda-se configurar uma conexão de banco separada para a fila em config/database.yml
  • Adicionar autenticação ao Mission Control e montar a rota /jobs
  • Adicionar jobs: bundle exec rake solid_queue:start ao Procfile.dev e executar tudo com bin/dev
  • Depois de criar tarefas de teste, é possível verificar o estado no Mission Control

Problemas frequentes e soluções

  • Também é possível usar uma configuração com banco único, mas isso reduz a flexibilidade operacional
  • No Mission Control em produção, é indispensável adicionar autenticação
  • O intervalo padrão de polling é de 1 segundo para tarefas agendadas e 0,2 segundo para tarefas imediatas, adequado para a maioria dos apps
  • Ao usar ActionCable/Turbo Streams, é preciso configurar o SolidCable com uma conexão de banco separada

Escalabilidade e desempenho

  • O SolidQueue pode escalar o suficiente para a maioria dos apps Rails
  • Com base em PostgreSQL, pode processar 200 a 300 tarefas por segundo, e a 37signals processa 20 milhões de tarefas por dia sem Redis
  • Tabela comparativa
    Item Redis + Sidekiq SolidQueue
    Complexidade de configuração Requer serviço separado Usa o banco embutido
    Linguagem de consulta Comandos Redis SQL
    Monitoramento Dashboard separado Mission Control
    Cenários de falha 6 ou mais 2
    Throughput Milhares/segundo 200–300/segundo
    Mais indicado para 99,9% dos apps 95% dos apps

Conclusão

  • Redis e Sidekiq são tecnologias excelentes, mas para a maioria das aplicações Rails geram complexidade e custo excessivos
  • O SolidQueue viabiliza operação mais simples, redução de custos e manutenção mais eficiente com base em um único banco de dados
  • Na era do Rails 8, a migração para SolidQueue é recomendada como escolha padrão

2 comentários

 
kaydash 2026-01-17

Redis é bom, mas.

 
GN⁺ 2026-01-15
Comentários do Hacker News
  • Acho que todo autor de open source tem o direito de controlar o escopo do próprio projeto
    Mas nossa equipe se arrependeu de ter trocado o good_job pelo SolidQueue
    A Basecamp é centrada em MySQL, então não aceita queries específicas do engine de RDBMS. Pelas issues no GitHub, dá para ver que o foco está só em desempenho no MySQL
    Além disso, ainda não há suporte a jobs em lote (PR relacionada)

    • Parece a pior combinação possível. Nós também usamos MySQL, mas não conseguiríamos viver sem queries específicas do engine
      Em JOINs complexos, o MySQL muitas vezes monta mal o plano de execução, então eu uso STRAIGHT_JOIN para forçar a ordem. É uma precaução para o futuro
    • Se vocês estão tão profundamente presos ao MySQL, não faria sentido usar recursos exclusivos do MySQL? Parece que está faltando alguma coisa
    • Queria ouvir de forma mais específica por que você recomenda GoodJob em vez de SolidQueue
      Estou comparando os dois como candidatos para migrar do resque. O GoodJob não é compatível com o modo transaction do pgbouncer por causa de recursos exclusivos do pg
      Precisar de persistência de sessão é incômodo, mas o ganho de desempenho não faz muita diferença na maioria das escalas
      Ainda assim, o modelo de desenvolvimento e a legibilidade do código do GoodJob passam muito mais confiança
    • Concordo. O good_job é a abordagem ideal para uma fila baseada em Postgres
    • Ainda não conheço bem o SolidQueue, mas usei o good_job e foi realmente um prazer. Funciona muito bem
  • Se puder simplificar o ambiente de produção, isso sempre é algo bom
    Acho que, no Rails, o cenário ideal é uma estrutura que permita mudar facilmente para Redis
    Seria bom poder começar com SolidQueue e, ao bater no limite de escalabilidade, migrar para Redis
    A maioria dos apps Rails não tem tráfego tão alto, então manter os dois sistemas acaba sendo mais complexo

    • O Rails oferece uma API abstraída chamada Active Job, então mudar para Redis é relativamente fácil
      Claro, há apps que dependem de implementações específicas de fila, mas no caso geral basta mudar a configuração
    • Fico curioso se o modo AOF do Redis registra todas as mudanças como um WAL
      Também queria saber se ele usa snapshots em conjunto para evitar que o log cresça demais, e se isso funciona também em modo distribuído
    • Depender demais de transações dificulta a migração
      Especialmente quando a criação de jobs acontece junto com outras mudanças no banco, perder essa garantia vira um problema
    • O Rails não separa o processador de jobs em background do banco de produção, e isso gera confusão
      O Redis levava vantagem nisso por ser um armazenamento de estado leve e independente
      O SolidQueue não parece deixar essa separação clara (riverqueue.com)
  • Testei o SolidQueue no meu side project
    A conclusão é: se não há problema com o Sidekiq, não existe motivo para trocar
    Só vale considerar se você quiser eliminar a infraestrutura de Redis
    Em projeto novo, o GoodJob parece mais maduro e tem uma comunidade melhor
    O SolidQueue tinha uma UI simples demais, o que incomodou. Sem otimização de índice, a página travava quando o volume de dados aumentava
    Também é preciso considerar que usar um RDBMS adiciona o custo de gerenciar pool de conexões

  • Para quem se preocupa com escalabilidade, o benchmark do Oban em Elixir mostra
    um único nó processando um milhão de jobs por minuto. A maioria dos apps tem um volume muito menor do que isso

    • Nossa empresa também usa Oban, e o Oban recomenda usar Redis como notifier ou fazer polling (documentação de scaling)
    • Mas esse benchmark está longe de um app real
      A estrutura insere 5000 jobs em lote de uma vez, então o TPS real fica em torno de 200
      Sem lote, ao inserir jobs individualmente, a carga de transações SQL aumenta muito mais
  • Nós já armazenávamos jobs no banco antes mesmo do SolidQueue
    A vantagem é poder fazer snapshot do estado de produção e levar exatamente isso para o ambiente de desenvolvimento
    Mas o rate limiter fica no Redis, para evitar carga excessiva no banco

  • O limite de filas baseadas em banco é o payload grande
    Colocar JSON grande na fila é ineficiente por causa do overhead de escrita no banco
    O Redis (Sidekiq) é muito mais rápido nesses casos
    SolidQueue+SQLite funciona bem se for apenas para passar a primary key
    Mas, se vários workers ficarem fazendo polling no mesmo banco, logo vira gargalo

    • Na prática, o comum é passar só um ou dois IDs como parâmetros do job. Mais do que isso é ineficiente
    • O Redis também não é adequado para payloads grandes por causa do limite de memória
      Acho melhor deixar os dados grandes em um storage externo como S3 e passar só a referência
    • De qualquer forma, outras partes do sistema também precisam de armazenamento, então usar um armazenamento temporário como S3 ou garage parece realista
      Fico curioso se existe algum material reunindo resultados de benchmark sobre isso
    • A documentação do Sidekiq também recomenda passar apenas identificadores
    • Armazenar payload grande no Redis é uma má prática. A memória é limitada
  • O SolidQueue menciona SKIP LOCKED, mas manter uma transação aberta por 15 minutos para um job é arriscado
    Transações longas acabam com o desempenho do banco e também são vulneráveis a quedas de rede
    Esse tipo de estrutura pode levar a um antipadrão. Depois percebi que aparentemente usa um esquema de lease

  • Tenho simpatia pela filosofia de Postgres for everything
    Acho bom unificar tudo em um único PostgreSQL para simplificar

    • Eu também gosto da ideia de ir all-in em PG, mas escuto muito a frase “quando você só tem um martelo, tudo parece prego”
      Não sei bem como responder a essa analogia
    • Hoje em dia, o storage NVMe está tão rápido que sinto que a vantagem do Redis diminuiu
      Fico pensando se ainda vale a pena usar Redis a ponto de aumentar a complexidade
  • “Um negócio em que latência abaixo de 1 ms importa”... estão dizendo que alguém faz HFT em Rails?

    • Claro que não. Pela página de casos da SimpleThread, essa empresa está longe de HFT
    • O engine de negociação não rodaria em Rails, mas uma UI de monitoramento de negociações poderia ser feita em Rails
  • O Postgres vai dominar o mundo

    • Também concordo. Quando surgir uma extensão pg_kernel, talvez a gente até apague o Linux
    • Mas daqui a alguns anos talvez a gente perceba que “Postgres for everything” foi uma moda exagerada, como “MongoDB for everything”
    • Ainda assim, o MySQL é fácil de manter e tem desempenho decente (mesmo eu sendo usuário de Postgres, sinto isso)
    • Hoje uso PGQM e PG_CRON, e está muito mais limpo do que a antiga combinação MySQL + Redis + AWS
    • No fim, o que importa é o conjunto de funcionalidades. O RDBMS vai dominar o mundo