// the find
celery/django-celery-beat
Celery Periodic Tasks backed by the Django ORM
django-celery-beat stores Celery's periodic task schedule in your Django database instead of a static config file, letting you create and modify schedules at runtime through Django Admin or the ORM. It's the standard solution for any Django+Celery project that needs dynamic scheduling. If you're already running both Django and Celery, this is effectively required.
Admin UI integration works well out of the box — non-technical users can manage schedules without a deploy. Per-schedule timezone support via zoneinfo is genuinely useful and not something you'd want to implement yourself. The change-detection mechanism (the PeriodicTasks counter table) is simple but efficient — beat only reloads the schedule when something actually changed, not on every poll. Docker Compose dev setup with a working admin user ships in the repo, so local testing takes minutes.
The migration history has diverging branches (three different 0006_* files) — a sign of messy past maintenance that required squashing and leaves you wondering about upgrade paths. Changing TIME_ZONE breaks all existing schedules silently; you have to manually null out last_run_at across the board, and the warning is buried in the README rather than enforced anywhere in the code. No built-in observability: there's nothing tracking missed runs, execution latency, or drift between scheduled and actual fire time. Running beat as a separate process from workers is correct but the docs still show the combined --beat --worker command as an option, which will cause you pain in production if someone copies it.