2023-12-19 (updated 2026-05-31)
In-building
The application needs to send time-based notifications to users (e.g. upcoming vet visits). Key constraints:
- Avoid overwhelming the database with frequent polling.
- Support at least one external channel (Discord is the primary target).
- Work within the existing Django monolith (ADR-03) without adding a separate service.
Options evaluated:
- django-crontab — OS-level cron wrapper; simple but couples scheduling to the server's cron daemon. No retry logic, no visibility into task state.
- Celery Beat — distributed periodic task scheduler; integrates with the Celery worker (Redis broker) already used for async tasks. Supports retry, monitoring via Flower, and dynamic schedule updates.
- Django Background Tasks API (
ImmediateBackend) — lightweight in-process runner; no separate worker process needed; suitable for short, non-critical tasks.
django-crontab was chosen initially but has since been removed. The current stack uses two complementary mechanisms:
-
Celery Beat (periodic tasks via
celery_notifications/cron.py) — handles scheduled checks (e.g. scan for upcoming vet visits and enqueue notification tasks). Runs as a separatecelery_beatDocker service with Redis 7 as the broker. -
Django Background Tasks API (
ImmediateBackend) — used for lightweight in-process tasks that do not need a separate worker. Configured insettings.py.
Notification channel: Discord via discord.py. Additional channels (e-mail, SMS) are deferred.
- The
homepage.CronJobmodel (the django-crontab leftover) was dropped in migrationhomepage/0004_delete_cronjob.py— the orphan-table follow-up this ADR originally flagged is resolved. - Celery Beat requires two running processes: the Celery worker (
queueservice) and the Beat scheduler (celery_beatservice). Both are defined indocker/docker-compose.yml. - Task visibility is available via Celery Flower (port 5555).
- Adding a new notification type means: (a) write a task function in
celery_notifications/cron.py, (b) register it in the Celery Beat schedule incelery_notifications/config.py.
- Celery, Celery Beat, notifications, Discord, cron, queue, broker, background tasks
[2026-05-31]
https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html
[2023-12-19]
https://docs.djangoproject.com/en/stable/topics/db/multi-db/ (database routing reference)