.. _guide-beat: ================ Periodic Tasks ================ .. contents:: :local: Introduction ============ :program:`celerybeat` is a scheduler. It kicks off tasks at regular intervals, which are then executed by the worker nodes available in the cluster. By default the entries are taken from the :setting:`CELERYBEAT_SCHEDULE` setting, but custom stores can also be used, like storing the entries in an SQL database. You have to ensure only a single scheduler is running for a schedule at a time, otherwise you would end up with duplicate tasks. Using a centralized approach means the schedule does not have to be synchronized, and the service can operate without using locks. .. _beat-entries: Entries ======= To schedule a task periodically you have to add an entry to the :setting:`CELERYBEAT_SCHEDULE` setting. Example: Run the ``tasks.add`` task every 30 seconds. .. code-block:: python from datetime import timedelta CELERYBEAT_SCHEDULE = { "runs-every-30-seconds": { "task": "tasks.add", "schedule": timedelta(seconds=30), "args": (16, 16) }, } Using a :class:`~datetime.timedelta` for the schedule means the task will be executed 30 seconds after ``celerybeat`` starts, and then every 30 seconds after the last run. A crontab like schedule also exists, see the section on `Crontab schedules`_. .. _beat-entry-fields: Available Fields ---------------- * ``task`` The name of the task to execute. * ``schedule`` The frequency of execution. This can be the number of seconds as an integer, a :class:`~datetime.timedelta`, or a :class:`~celery.schedules.crontab`. You can also define your own custom schedule types, by extending the interface of :class:`~celery.schedules.schedule`. * ``args`` Positional arguments (:class:`list` or :class:`tuple`). * ``kwargs`` Keyword arguments (:class:`dict`). * ``options`` Execution options (:class:`dict`). This can be any argument supported by :meth:`~celery.execute.apply_async`, e.g. ``exchange``, ``routing_key``, ``expires``, and so on. * ``relative`` By default :class:`~datetime.timedelta` schedules are scheduled "by the clock". This means the frequency is rounded to the nearest second, minute, hour or day depending on the period of the timedelta. If ``relative`` is true the frequency is not rounded and will be relative to the time when :program:`celerybeat` was started. .. _beat-crontab: Crontab schedules ================= If you want more control over when the task is executed, for example, a particular time of day or day of the week, you can use the ``crontab`` schedule type: .. code-block:: python from celery.schedules import crontab CELERYBEAT_SCHEDULE = { # Executes every Monday morning at 7:30 A.M "every-monday-morning": { "task": "tasks.add", "schedule": crontab(hour=7, minute=30, day_of_week=1), "args": (16, 16), }, } The syntax of these crontab expressions are very flexible. Some examples: +-------------------------------------+--------------------------------------------+ | **Example** | **Meaning** | +-------------------------------------+--------------------------------------------+ | crontab() | Execute every minute. | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, hour=0) | Execute daily at midnight. | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, hour="\*/3") | Execute every three hours: | | | 3am, 6am, 9am, noon, 3pm, 6pm, 9pm. | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, | Same as previous. | | hour=[0,3,6,9,12,15,18,21]) | | +-------------------------------------+--------------------------------------------+ | crontab(minute="\*/15") | Execute every 15 minutes. | +-------------------------------------+--------------------------------------------+ | crontab(day_of_week="sunday") | Execute every minute (!) at Sundays. | +-------------------------------------+--------------------------------------------+ | crontab(minute="*", | Same as previous. | | hour="*", | | | day_of_week="sun") | | +-------------------------------------+--------------------------------------------+ | crontab(minute="\*/10", | Execute every ten minutes, but only | | hour="3,17,22", | between 3-4 am, 5-6 pm and 10-11 pm on | | day_of_week="thu,fri") | Thursdays or Fridays. | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, hour="\*/2,\*/3") | Execute every even hour, and every hour | | | divisible by three. This means: | | | at every hour *except*: 1am, | | | 5am, 7am, 11am, 1pm, 5pm, 7pm, | | | 11pm | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, hour="\*/5") | Execute hour divisible by 5. This means | | | that it is triggered at 3pm, not 5pm | | | (since 3pm equals the 24-hour clock | | | value of "15", which is divisible by 5). | +-------------------------------------+--------------------------------------------+ | crontab(minute=0, hour="\*/3,8-17") | Execute every hour divisible by 3, and | | | every hour during office hours (8am-5pm). | +-------------------------------------+--------------------------------------------+ .. _beat-starting: Starting celerybeat =================== To start the :program:`celerybeat` service:: $ celerybeat You can also start ``celerybeat`` with ``celeryd`` by using the ``-B`` option, this is convenient if you only intend to use one worker node:: $ celeryd -B Celerybeat needs to store the last run times of the tasks in a local database file (named ``celerybeat-schedule`` by default), so it needs access to write in the current directory, or alternatively you can specify a custom location for this file:: $ celerybeat -s /home/celery/var/run/celerybeat-schedule .. note:: To daemonize celerybeat see :ref:`daemonizing`. .. _beat-custom-schedulers: Using custom scheduler classes ------------------------------ Custom scheduler classes can be specified on the command line (the ``-S`` argument). The default scheduler is :class:`celery.beat.PersistentScheduler`, which is simply keeping track of the last run times in a local database file (a :mod:`shelve`). ``django-celery`` also ships with a scheduler that stores the schedule in the Django database:: $ celerybeat -S djcelery.schedulers.DatabaseScheduler Using ``django-celery``'s scheduler you can add, modify and remove periodic tasks from the Django Admin.