Remix.run Logo
teagee 13 hours ago

Any code or blog written by Adam is worth spending some time on.

It will be interesting to see how the tasks framework develops and expands. I am sad to see the great Django-Q2 lumped in with the awful Celery though.

tmarice 33 minutes ago | parent | next [-]

Celery is the worst background task framework, except for all the others.

There are bugs and issues, but because so many people are using it, you’re rarely the first to stumble upon a problem. We processed double-digit millions of messages daily with Celery + RabbitMQ without major obstacles. Regardless of what people say, it should be your first go-to.

adamchainz 12 hours ago | parent | prev | next [-]

OP here, thanks for the praise!

Yeah, I mentioned Celery due to its popularity, no other reason ;)

ryanisnan 11 hours ago | parent [-]

You are a great writer - thanks for putting this together!

sgt 2 hours ago | parent | prev | next [-]

I've been using Celery for years. What is the major issues you have with it and how does Django Q2 help?

I also use Kafka on other tech stacks but that's another level completely and use case.

blorenz 10 hours ago | parent | prev | next [-]

I’m currently stuck with the tech debt of Celery myself. I understand that! Does Django Tasks support async functions?

hintoftime 12 hours ago | parent | prev | next [-]

Why is celery awful?

JimDabell 7 hours ago | parent | next [-]

> The Many Problems with Celery:

https://steve.dignam.xyz/2023/05/20/many-problems-with-celer...

> The problems with (Python’s) Celery:

https://docs.hatchet.run/blog/problems-with-celery

> Dramatiq motivation:

https://dramatiq.io/motivation.html

Here are some alternatives:

Dramatiq: https://github.com/Bogdanp/dramatiq

RQ: https://github.com/rq/rq

Huey: https://github.com/coleifer/huey

Hatchet: https://github.com/hatchet-dev/hatchet

hda111 2 hours ago | parent [-]

django-q2: https://github.com/django-q2/django-q2

leobuskin 9 hours ago | parent | prev | next [-]

It's okay till it's not. Everyone I know who had Celery in production was looking for a substitution (custom or third-party) on a regular basis. Too many moving pieces and nuances (config × logic × backend), too many unresolved problems deep in its core (we've seen some ghosts you can't debug), too much of a codebase to understand or hack. At some point we were able to stabilize it (a bunch of magic tricks and patches) and froze every related piece; it worked well under pressure (thanks, RabbitMQ).

tclancy 10 hours ago | parent | prev | next [-]

Because it’s a seducer. It does what you need to do and you two are happy together. So you shower more tasks on Celery and it becomes cold and non-responsive at random times.

And debugging is a pain in the ass. Most places I’ve been that have it, I’ve tried to sell them on adding Flower to give better insight and everyone thinks that’s a very good idea but there isn’t time because we need to debug these inscrutable Celery issues.

https://flower.readthedocs.io/en/latest/

akoumjian 9 hours ago | parent | prev [-]

Celery is great and awful at the same time. In particular, because it is many Python folks' first introduction to distributed task processing and all the things that can go wrong with it. Not to mention, debugging can be a nightmare. Some examples:

- your function arguments aren't serializable - your side effects (e.g. database writes) aren't idempotent - discovering what backpressure is and that you need it - losing queued tasks during deployment / non-compatible code changes

There's also some stuff particular to celery's runtime model that makes it incredibly prone to memory leaks and other fun stuff.

Honestly, it's a great education.

ffsm8 7 hours ago | parent | next [-]

> your side effects (e.g. database writes) aren't idempotent

What does idempotent mean in this context, or did you mean atomic/rollback on error?

I'm confused because how could a database write be idempotent in Django? Maybe if it introduced a version on each entity and used that for crdt on writes? But that'd be a significant performance impact, as it couldn't just be a single write anymore, instead they'd have to do it via multiple round trips

teaearlgraycold an hour ago | parent [-]

In my experience async job idempotency is implemented as upserts. Insert all job outputs on the first run. Do (mostly) nothing on subsequent runs. Maybe increment a counter or timestamp.

saaspirant 8 hours ago | parent | prev [-]

From your experience, what is a better alternative guys?

leobuskin 7 hours ago | parent | next [-]

There’s no alternative (while prototyping), and anything else is better (when you properly defined your case).

walthamstow 2 hours ago | parent [-]

DjangoQ2 is a fine alternative during early development

boxed 2 hours ago | parent | prev [-]

Not the comment that you replied to but I use my own Urd. It's a fancier Cron that you can stop fast. Which is imo what you normally want.

Task queues are like email. It's what everyone is used to so people ask for more of it, but it's not actually good/the right tool.

boxed 2 hours ago | parent | prev | next [-]

I tried django-q and I thought it was pretty terrible. The worst was that I couldn't get it to stop retrying stuff that was broken. Sometimes you ship code that does something unexpected, and being able to stop something fast is critical imo.

Fundamentally I think the entire idea behind celery and django-q is mostly misguided. People normally actually need a good scheduler and a bring-your-own queue in tables that you poll. I wrote Urd to cover my use cases and it's been rock solid.

gnatman 11 hours ago | parent | prev | next [-]

Computer, load up Celery Man please.

jonatron 12 hours ago | parent | prev [-]

I'm of the opinion that django task apps should only support a single backend. For example, django-rq for redis only. There's too many differences in backends to make a good app that can handle multiple. That said, I've only used celery in production before, and I'm willing to change my mind.

themerone 6 hours ago | parent [-]

With that logic, the Django orm should only support one database.