Executing a task on an interval or at a specific time is a common problem with application developers.
Many software developers think, I know how to solve this, I’ll use cron.
A few problems with cron:
- Smallest resolution is 1 minute — If a task needs to run every 30 seconds, you can’t do it with cron.
- Error handling — If a job fails, what should happen? Solutions have been built to solve this single problem. Developers love adding more band-aids rather than admitting there is a better way. Deja Vu?
- Logging — Crons don’t log, unless you tell them too. It is rare to see people log output of their cron jobs.
- Working with cron pulls you out of the application — cron is a system level process. Not an application process. It’s challenging to give application developers access to anything at a system level. Developers shouldn’t care where their application runs… A good example of this is timezones. If a system person changes the timezone of a server, the cron may run at a different time than expected. The less the app developers have to worry about what they run on, the better.
- Not enough reasons? You can read more about how cron doesn’t work at this StackExchange thread.
There is a better way.
Background jobs and a scheduler
Developers of Web Applications are aware of a common problem of offloading a task that can hold up a web request by putting it into a background job. Python’s most famous background task worker is Celery. Celery has a built in feature called Beat, which is a scheduler.
Here is how it works.
Create a celery task. This is the same type of task you create when doing background work.
Then add it to the Beat scheduler. Celery Beat is a service which runs and at regular intervals and puts things onto a celery queue.
You however, aren’t limited to “cron style” jobs. You can also run things on regular intervals.
ProTip™ — Tasks can call other tasks.
Please, hear my cry:
Stop using cron for regular application tasks.