16 points par GN⁺ 2026-01-15 | 2 commentaires | Partager sur WhatsApp
  • Rails 8 supprime la dépendance à Redis de sa stack par défaut et bascule tous les traitements vers une base de données relationnelle (RDB) via SolidQueue·SolidCache·SolidCable
  • Redis est rapide et fiable, mais entraîne une complexité opérationnelle liée à la configuration, la sécurité, la gestion de cluster et les sauvegardes
  • SolidQueue s’appuie sur la fonctionnalité PostgreSQL FOR UPDATE SKIP LOCKED pour mettre en œuvre un traitement parallèle sans contention
  • Des fonctionnalités payantes de Redis+Sidekiq comme les tâches récurrentes, le contrôle de concurrence et le tableau de bord de monitoring (Mission Control) sont fournies gratuitement
  • Pour la plupart des applications Rails, SolidQueue suffit, et Redis ne reste nécessaire que dans certains cas demandant un traitement temps réel ultra-rapide

Le coût caché de Redis

  • Au-delà du simple coût d’hébergement, Redis impose une charge continue de gestion : installation, maintenance, configuration de sécurité, gestion de cluster HA
    • Il faut mettre en place la connexion réseau et les règles de pare-feu entre Rails et Redis, l’authentification client et l’orchestration des processus Sidekiq
  • En cas d’incident, il faut déboguer simultanément Redis et le SGBDR, avec en plus une stratégie de sauvegarde double
  • À l’inverse, une stack Rails sans Redis permet de se contenter de gérer uniquement PostgreSQL, ce qui simplifie l’exploitation

Fonctionnement de SolidQueue

  • SolidQueue utilise la fonctionnalité PostgreSQL FOR UPDATE SKIP LOCKED afin que plusieurs workers récupèrent des tâches en parallèle sans conflit de verrouillage (lock contention)
  • Structure principale des tables
    1. solid_queue_jobs : stockage des métadonnées des tâches
    2. solid_queue_scheduled_executions : attente des tâches planifiées
    3. solid_queue_ready_executions : file des tâches prêtes à être exécutées
  • Les processus worker, dispatcher, scheduler et supervisor coopèrent en interrogeant périodiquement différentes tables
  • Grâce à la conception MVCC de PostgreSQL et à autovacuum, même de gros volumes d’insertions et de suppressions sont traités de manière stable

Planification des tâches récurrentes

  • SolidQueue fournit nativement des tâches récurrentes de style cron, configurées dans le fichier config/recurring.yml
  • Le scheduler place en file les tâches arrivées à échéance, puis programme automatiquement leur prochaine exécution
  • Il s’appuie sur la bibliothèque Fugit pour analyser des plannings en langage naturel, et sur Concurrent::ScheduledTask pour créer des threads
  • Il reprend l’approche de planification déterministe de GoodJob, afin de préserver le planning même après redémarrage du processus

Contrôle de concurrence

  • SolidQueue utilise le pattern de sémaphore POSIX pour prendre en charge la limitation des exécutions simultanées par tâche
    • Exemple : avec limits_concurrency to: 1, key: ->(user) { user.id }, une seule tâche par utilisateur peut s’exécuter à la fois
  • La définition d’une expiration du sémaphore (duration) permet d’éviter les conflits et les deadlocks
  • Tables associées
    • solid_queue_semaphores : suivi des limites de concurrence
    • solid_queue_blocked_executions : stockage des tâches en attente

Monitoring avec Mission Control

  • Mission Control Jobs est un tableau de bord open source gratuit pour Rails 8, qui peut être monté simplement sur la route /jobs
  • Fonctionnalités principales
    • état des files en temps réel, suivi des tâches en échec, contrôle des retries et de l’abandon
    • visualisation de la chronologie des tâches planifiées et récurrentes
    • graphiques de débit et de métriques par file
  • Les requêtes basées sur SQL permettent une analyse directe dans la base de données sans outil supplémentaire

Migration de Sidekiq vers SolidQueue

  • Étape 1 : définir config.active_job.queue_adapter = :solid_queue
  • Étape 2 : exécuter bundle add solid_queue, puis rails solid_queue:install et db:migrate
  • Étape 3 : convertir les plannings cron de sidekiq.yml vers recurring.yml
  • Étape 4 : ajouter jobs: bundle exec rake solid_queue:start au Procfile
  • Étape 5 : supprimer les gems liées à Redis et Sidekiq
  • Le code ActiveJob existant continue de fonctionner sans modification

Cas où Redis reste nécessaire

  • traitement soutenu de plusieurs milliers de tâches par seconde
  • systèmes temps réel où une latence inférieure à 1 ms est indispensable
  • besoin d’une architecture pub/sub complexe ou d’opérations avancées de rate limiting et de compteurs
  • Par exemple, Shopify exploite une infrastructure Redis avec 833 requêtes par seconde et 1 172 processus workers

Guide d’implémentation concret

  • Lors de la création d’une nouvelle application Rails 8, SolidQueue, SolidCache et SolidCable sont configurés automatiquement
  • Il est recommandé de définir dans config/database.yml une connexion de base de données distincte pour la queue
  • Ajouter l’authentification de Mission Control et monter la route /jobs
  • Ajouter jobs: bundle exec rake solid_queue:start dans Procfile.dev, puis lancer l’ensemble avec bin/dev
  • Après création de tâches de test, leur état peut être vérifié dans Mission Control

Problèmes fréquents et solutions

  • Une configuration sur base de données unique est possible, mais réduit la flexibilité en production
  • En production, il faut impérativement ajouter une authentification à Mission Control
  • Les intervalles de polling par défaut sont de 1 seconde pour les tâches planifiées et de 0,2 seconde pour les tâches immédiates, ce qui convient à la plupart des applications
  • En cas d’utilisation de ActionCable/Turbo Streams, il faut configurer SolidCable avec une connexion DB distincte

Scalabilité et performances

  • SolidQueue est suffisamment scalable pour la plupart des applications Rails
  • Avec PostgreSQL, il peut traiter 200 à 300 tâches par seconde, et 37signals traite 20 millions de tâches par jour sans Redis
  • Tableau comparatif
    Élément Redis + Sidekiq SolidQueue
    Complexité de configuration Service séparé nécessaire Utilise la DB intégrée
    Langage de requête Commandes Redis SQL
    Monitoring Tableau de bord séparé Mission Control
    Scénarios de panne 6 ou plus 2
    Débit Plusieurs milliers/s 200–300/s
    Cas adaptés 99,9 % des apps 95 % des apps

Conclusion

  • Redis et Sidekiq sont d’excellentes technologies, mais elles entraînent une complexité et un coût excessifs pour la plupart des applications Rails
  • SolidQueue permet, avec une base de données unique, de simplifier l’exploitation, réduire les coûts et améliorer la maintenance
  • À l’ère de Rails 8, il est recommandé d’adopter SolidQueue comme choix par défaut

2 commentaires

 
kaydash 2026-01-17

Redis, c’est bien.

 
GN⁺ 2026-01-15
Avis Hacker News
  • Je pense que tous les auteurs open source ont le droit de contrôler le périmètre de leur projet
    Mais notre équipe regrette d’être passée de good_job à SolidQueue
    Basecamp est centré sur MySQL, donc ils n’acceptent pas les requêtes spécifiques au moteur RDBMS. En regardant les issues GitHub, on voit qu’ils se concentrent uniquement sur les performances de MySQL
    De plus, il n’y a toujours pas de prise en charge des traitements par lot (PR liée)

    • Ça a l’air d’être la pire combinaison. Nous aussi on utilise MySQL, mais on ne pourrait pas vivre sans requêtes spécifiques au moteur
      Sur les JOIN complexes, MySQL construit souvent un mauvais plan d’exécution, donc j’impose l’ordre avec STRAIGHT_JOIN. C’est une précaution pour l’avenir
    • Si vous êtes à ce point liés à MySQL, ce n’est pas logique d’utiliser des fonctionnalités réservées à MySQL ? J’ai l’impression qu’il manque quelque chose
    • J’aimerais entendre plus concrètement pourquoi tu recommandes GoodJob plutôt que SolidQueue
      Je compare justement les deux comme candidats pour migrer depuis resque. GoodJob n’est pas compatible avec le mode transaction de pgbouncer à cause de ses fonctionnalités propres à pg
      Le besoin de persistance de session est pénible, mais le gain de performances n’a pas beaucoup d’importance à la plupart des échelles
      Malgré ça, le modèle de développement et la lisibilité du code de GoodJob inspirent bien davantage confiance
    • D’accord. good_job est une approche idéale pour une file basée sur Postgres
    • Je ne connais pas encore très bien SolidQueue, mais j’ai utilisé good_job et c’est vraiment un plaisir. Ça fonctionne bien
  • C’est toujours une bonne chose si l’environnement de production peut être simplifié
    Dans Rails, je pense que la situation idéale est une architecture qui permet de basculer facilement vers Redis
    Ce serait bien de pouvoir commencer avec SolidQueue puis migrer vers Redis si on finit par atteindre des limites de scalabilité
    La plupart des applications Rails n’ont pas un trafic énorme, donc maintenir les deux systèmes ajoute plutôt de la complexité

    • Rails fournit une API abstraite appelée Active Job, donc passer à Redis est assez simple
      Bien sûr, certaines applications dépendent d’une implémentation de file précise, mais dans le cas général il suffit de changer la configuration
    • Je me demande si le mode AOF de Redis enregistre toutes les modifications comme un WAL
      J’aimerais savoir s’il combine aussi des snapshots pour éviter que le journal ne devienne trop gros, et si cela fonctionne aussi en mode distribué
    • Si on dépend trop des transactions, les migrations deviennent difficiles
      En particulier quand la création des jobs se produit en même temps que d’autres changements en base, perdre cette garantie pose problème
    • Rails ne sépare pas le processeur de jobs en arrière-plan de la base de production, ce qui prête à confusion
      Redis avait ici l’avantage d’être un stockage d’état léger et indépendant
      SolidQueue ne semble pas clarifier cette séparation (riverqueue.com)
  • J’ai testé SolidQueue sur mon projet perso
    Ma conclusion, c’est que s’il n’y a pas de problème avec Sidekiq, il n’y a pas de raison de changer
    Ça ne vaut la peine d’être envisagé que si on veut supprimer l’infrastructure Redis
    Pour un nouveau projet, GoodJob est plus mature et bénéficie d’une meilleure communauté
    L’UI de SolidQueue est trop basique, ce qui m’a gêné. Les index n’étaient pas optimisés, et avec beaucoup de données la page se figeait
    Il faut aussi prendre en compte le coût de gestion du pool de connexions supplémentaire quand on utilise un RDBMS

  • Pour ceux qui s’inquiètent de la scalabilité, si on regarde les benchmarks d’Oban en Elixir,
    il traite un million de jobs par minute sur un seul nœud. La plupart des applications ont un volume bien inférieur

    • Notre entreprise utilise aussi Oban, mais Oban utilise Redis comme notifier ou recommande le polling (documentation sur la montée en charge)
    • Mais ce benchmark est assez éloigné d’une vraie application
      Il insère les 5000 jobs en une seule fois par lots, donc le TPS réel est d’environ 200
      Sans batch, si on insère les jobs individuellement, la charge des transactions SQL augmente beaucoup
  • Avant SolidQueue, nous stockions déjà les jobs en base
    L’avantage, c’est qu’on peut faire un snapshot de l’état de production tel quel vers l’environnement de développement
    En revanche, nous gardons le rate limiter dans Redis, pour éviter de surcharger la base

  • La limite des files basées sur une base de données, c’est la taille importante des payloads
    Mettre de gros JSON dans la file est inefficace à cause du surcoût d’écriture en base
    Redis (Sidekiq) est bien plus rapide dans ce cas
    SolidQueue + SQLite peut convenir si c’est simplement pour transmettre une clé primaire
    Mais si plusieurs workers interrogent la même base en polling, on arrive vite à un goulot d’étranglement

    • En pratique, on transmet généralement un ou deux identifiants seulement comme paramètres du job. Au-delà, c’est inefficace
    • Redis aussi est peu adapté aux gros payloads à cause de ses limites mémoire
      Je pense qu’il vaut mieux mettre les grosses données dans un stockage externe comme S3 et ne transmettre qu’une référence
    • De toute façon, le système a besoin de stockage ailleurs aussi, donc utiliser un stockage temporaire comme S3 ou garage est réaliste
      Je me demande s’il existe un document qui résume les résultats de benchmarks
    • La documentation de Sidekiq recommande aussi de ne transmettre que des identifiants
    • Stocker de gros payloads dans Redis est une mauvaise pratique, car la mémoire est limitée
  • SolidQueue mentionne SKIP LOCKED, mais garder une transaction ouverte pour un job de 15 minutes est risqué
    Les transactions longues dégradent les performances de la base et sont vulnérables aux coupures réseau
    Ce genre de structure peut mener à des anti-patterns. En regardant ensuite de plus près, cela semble fonctionner avec un système de lease

  • Je me reconnais dans la philosophie Postgres for everything
    Je pense que c’est bien de tout unifier autour de PostgreSQL pour rester simple

    • Moi aussi j’aime l’idée du tout-PG, mais on me ressort souvent la phrase « quand on n’a qu’un marteau, tout ressemble à un clou »
      Je ne sais pas vraiment comment répondre à cette analogie
    • Aujourd’hui, le stockage NVMe est devenu si rapide que j’ai l’impression que l’avantage de Redis diminue
      Je me demande s’il y a encore une raison d’utiliser Redis au prix d’une complexité supplémentaire
  • « Une activité où une latence inférieure à 1 ms est importante » : on parle de faire du HFT avec Rails ?

    • Bien sûr que non. Si on regarde le cas client de SimpleThread, cette entreprise est loin du HFT
    • Le moteur de trading ne tournerait pas sur Rails, mais une UI de supervision des transactions pourrait très bien être faite en Rails
  • Postgres va dévorer le monde

    • Je suis d’accord. Un jour, quand une extension pg_kernel sortira, on supprimera peut-être Linux
    • Mais dans quelques années, on se rendra peut-être compte que « Postgres for everything » était aussi une mode excessive que « MongoDB for everything »
    • Malgré tout, MySQL reste facile à maintenir et offre des performances tout à fait correctes (je dis ça en tant qu’utilisateur de Postgres)
    • En ce moment j’utilise PGQM et PG_CRON, et c’est bien plus propre que l’ancienne combinaison MySQL + Redis + AWS
    • Au final, ce qui compte, c’est l’ensemble des fonctionnalités. Les RDBMS vont dévorer le monde