Search code examples
pythonceleryconfigcelerybeat

Schedule task to run once daily at specific time | Celery


I want to schedule running two tasks at 16h UTC once per day.

To do so, I've implemented this celery config:

from celery.schedules import crontab


CELERY_IMPORTS = ('api.tasks')
CELERY_TASK_RESULT_EXPIRES = 30
CELERY_TIMEZONE = 'UTC'

CELERYBEAT_SCHEDULE = {
    'book-task': {
        'task': 'api.tasks.get_data',
        # At 16h UTC everyday
        'schedule': crontab(hour=16),
        'args': ({'book'}),
    },
    'pencils-task': {
        'task': 'api.tasks.get_data',
        # At 16h UTC everyday
        'schedule': crontab(hour=16),
        'args': ({'pencil'}),
    }
}

I run celery worker -A app.celery --loglevel=info --pool=solo to run the celery worker after running celery beat -A app.celery to launch celery beat.

With the config above, I have my two tasks running every minute starting 16h UTC. What is wrong with my config and how to fix ?


Solution

  • You need to specify minute in your crontab, not passing minute means the default value * is used which runs the job every minute.

    Pass minute=0 to run at the start of the hour

    from celery.schedules import crontab
    
    
    CELERY_IMPORTS = ('api.tasks')
    CELERY_TASK_RESULT_EXPIRES = 30
    CELERY_TIMEZONE = 'UTC'
    
    CELERYBEAT_SCHEDULE = {
        'book-task': {
            'task': 'api.tasks.get_data',
            # At 16h UTC everyday
            'schedule': crontab(minute=0, hour=16),
            'args': ({'book'}),
        },
        'pencils-task': {
            'task': 'api.tasks.get_data',
            # At 16h UTC everyday
            'schedule': crontab(minute=0, hour=16),
            'args': ({'pencil'}),
        }
    }