Django Celery Bug Silently Corrupts Production Data

This Django + Celery bug has silently corrupted data in more production apps than you think. And most engineers don't even know they're hitting it. Here's the scenario. User registers. You fire a Celery task to send a welcome email. task = send_welcome_email.delay(user.pk) Looks fine. Works in dev. Works in staging. Then in production — random users never get their email. No errors. No exceptions. Task succeeds. Email just... doesn't send. The bug? Your Celery task ran before Django committed the transaction to the database. The task woke up, queried User.objects.get(pk=user.pk) — and the user didn't exist yet. This is the classic Django + Celery race condition. It's been silently wrecking production apps for years. The old fix was ugly: transaction.on_commit(lambda: send_welcome_email.delay(user.pk)) It worked. But it was boilerplate you had to remember everywhere. Celery 5.4 shipped a proper fix — .delay_on_commit(): send_welcome_email.delay_on_commit(user.pk) One method. Zero boilerplate. Task only fires after the DB transaction commits. Race condition gone. I hit this on a large-scale project handling thousands of user signups. Switched every task trigger to .delay_on_commit() and the ghost failures disappeared overnight. If you're using Celery with Django and still calling .delay() directly in views — check your logs. You might be losing tasks you don't know about. Drop a comment if this has burned you before. I know I'm not the only one. 👇 #Django #Celery #Python #BackendEngineering #DjangoTips #WebDevelopment #BuildingInPublic #SoftwareEngineering

  • graphical user interface, diagram, text, chat or text message

To view or add a comment, sign in

Explore content categories