Home › Cron Jobs with Django

Cron Jobs in Django

Three approaches: raw crontab, django-crontab or Celery Beat. Which one depends on your project's complexity and existing infrastructure.

Option 1: Raw Crontab with a Management Command

The simplest approach that works for any Django version. Create a management command and call it from cron. No extra dependencies, no magic.

Create myapp/management/commands/send_reports.py:

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Send weekly reports'

    def handle(self, *args, **kwargs):
        # your task logic here
        self.stdout.write('Reports sent.')

Add to crontab:

0 8 * * 1 /home/user/project/venv/bin/python /home/user/project/manage.py send_reports >> /var/log/reports.log 2>&1

Use the virtualenv Python. The manage.py command loads Django's environment automatically, so your models, settings and database are all available.

Option 2: django-crontab

Defines all your cron jobs in settings.py and installs them with one command. Good for projects with multiple scheduled tasks - keeps everything in one place. Package: django-crontab on PyPI.

Install:

pip install django-crontab

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    'django_crontab',
]

Define jobs in settings.py:

CRONJOBS = [
    ('0 2 * * *', 'myapp.cron.daily_backup'),
    ('*/15 * * * *', 'myapp.cron.process_queue', '>> /var/log/queue.log 2>&1'),
    ('0 9 * * 1', 'django.core.management.call_command', ['send_reports']),
]

Install and manage:

python manage.py crontab add     # installs all CRONJOBS into the system crontab
python manage.py crontab show    # lists installed cron jobs
python manage.py crontab remove  # removes all installed jobs

Option 3: Celery Beat

If your project already uses Celery for async tasks, Celery Beat is the natural choice for periodic tasks. More setup, but you get distributed execution, retries and monitoring out of the box. Official docs: Celery Beat - Periodic Tasks.

pip install celery django-celery-beat

Define periodic tasks in settings.py:

from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'daily-backup': {
        'task': 'myapp.tasks.daily_backup',
        'schedule': crontab(hour=2, minute=0),
    },
    'process-queue': {
        'task': 'myapp.tasks.process_queue',
        'schedule': crontab(minute='*/15'),
    },
    'weekly-report': {
        'task': 'myapp.tasks.send_report',
        'schedule': crontab(hour=9, minute=0, day_of_week=1),
    },
}

Run Celery Beat alongside your workers:

celery -A myproject beat -l info
celery -A myproject worker -l info

Comparison

ApproachSetupDependenciesBest for
Raw crontab Minimal None Simple projects, 1-2 jobs
django-crontab Easy django-crontab Multiple jobs, no Celery
Celery Beat Complex Celery + broker (Redis/RabbitMQ) Production, distributed systems

Start simple, scale when needed

Most Django projects start with a management command and a crontab entry, and that is enough for years. Only move to Celery Beat when you need distributed execution, per-job retries or dynamic schedule management from a database. django-crontab sits in between - it is a good middle ground if you want schedule definitions in code but do not need Celery's complexity.

Django Cron Job Not Running - Checklist

Test the management command manually

/home/user/project/venv/bin/python \
  /home/user/project/manage.py send_reports

Run the exact command from the crontab. If Django raises an error here, that same error will happen silently in cron.

Using the system Python, not the virtualenv

The most common Django cron mistake. The system Python does not have Django or your project's packages installed. Always use the full path to the Python binary inside your virtualenv:

source venv/bin/activate && which python
# copy that path into the crontab

DJANGO_SETTINGS_MODULE not set

If your project uses a non-default settings module, set it explicitly in the crontab:

DJANGO_SETTINGS_MODULE=myproject.settings.production
0 2 * * * /home/user/venv/bin/python manage.py backup

django-crontab jobs not running

After changing CRONJOBS in settings, you must re-run python manage.py crontab add - changes to settings.py do not automatically update the system crontab. Run crontab -l to verify the entries were actually installed.

Build the cron expression for your Django job

Both django-crontab and Celery Beat accept standard cron expressions. Use the generator and paste the result directly.