Kafka ou Sidekiq ? Choisir le bon outil asynchrone pour votre backend Ruby on Rails
Un chemin de décision concret pour savoir quand une application Rails a réellement besoin d'un message broker, et quand Sidekiq couvre déjà tout ce dont vous avez besoin.
Publié le 15 juin 2025 · 4 min de lecture
Tous les quelques mois, un client nous propose d'ajouter Kafka à une application Rails qui compte peut-être trois jobs en arrière-plan. L'argument est presque toujours le même : « nous aurons peut-être besoin de monter en charge sur le traitement d'événements plus tard ». Ce « plus tard » arrive rarement, et en attendant l'équipe exploite et supervise un log distribué dont elle n'avait pas besoin.
Ce que Sidekiq vous apporte réellement
Sidekiq résout un problème plus étroit qu'on ne le croit, et c'est sa force. Il prend un objet Ruby, sérialise ses arguments, les pousse dans une liste Redis, et garantit qu'un worker finira par le récupérer et l'exécuter, avec des retries et un backoff en cas d'échec. Une seule dépendance (Redis), un seul modèle mental (un job, en at-least-once), et une interface que vous pouvez confier à un ingénieur du support dès le premier jour.
class ChargeInvoiceJob
include Sidekiq::Job
sidekiq_options retry: 10, queue: :billing
def perform(invoice_id)
invoice = Invoice.find(invoice_id)
return if invoice.paid?
PaymentGateway.charge(invoice)
end
end
C'est tout le contrat. Pas de topic à provisionner, pas de consumer group à rééquilibrer, pas de schema registry à maintenir.
Ce qui change quand Kafka devient le bon choix
Kafka justifie sa complexité lorsqu'un même événement métier doit atteindre plusieurs systèmes qui ne se connaissent pas, chacun devant le traiter de façon indépendante, à son rythme, avec la possibilité de rejouer l'historique si un consumer était à l'arrêt ou si un bug a été livré. La facturation, la détection de fraude et un data warehouse qui réagissent tous au même événement « PaymentCaptured » constituent un cas d'usage légitime de Kafka. Une seule application Rails qui débite une carte et envoie un reçu n'en est pas un.
- Les garanties d'ordre s'appliquent par partition, pas globalement, ce qui change la façon de choisir la clé des messages.
- Les consumers gèrent leurs propres offsets : un consumer lent ne bloque jamais un consumer rapide, mais vous devenez responsable du rééquilibrage et de la surveillance du lag.
- Le rejeu est une fonctionnalité, mais aussi une contrainte : les consumers doivent rester idempotents, pour toujours.
L'hybride que nous livrons le plus souvent
Sur la plupart des codebases Rails où nous intervenons, la réponse n'est pas « Sidekiq ou Kafka ». C'est Sidekiq pour tout ce qui reste interne à l'application, et une fine couche outbox qui ne publie sur un topic Kafka que les quelques événements dont d'autres équipes ont réellement besoin. Cela garde la surface d'exploitation réduite tout en offrant au reste de l'organisation un flux fiable. Nous expliquons dans un autre article comment construire cet outbox correctement, sans perdre d'événements.
Si vous hésitez sur le côté de la ligne où se situe votre projet, le test est simple : comptez combien de systèmes indépendants ont besoin du même événement, aujourd'hui, pas hypothétiquement. Si la réponse est un, vous n'avez pas encore besoin d'un broker.
Articles liés
Idempotence par conception : rendre vos jobs Sidekiq sûrs à rejouer
Sidekiq garantit une livraison au moins une fois (at-least-once), pas exactement une fois. Tout job qui n'est pas sûr à exécuter deux fois est un bug qui attend le bon chevauchement.
Gérer Sidekiq en production : jobs planifiés, débogage et nettoyage
Sidekiq est facile à mettre en place et facile à perdre de vue, deux ans et quarante classes de jobs plus tard. Les pratiques qui le gardent maîtrisable sur la durée.