Learning objectives
After reading this article you will be able to:
- Read and write a five-field cron expression
- Avoid the traps around time zones, intervals and weekdays
- Schedule a task inside a Node.js application
Cron is the classic job scheduler of Unix and Linux systems. You tell it when something should run and what to run, and it fires the command by itself, with nobody pressing a button. Each scheduled task is called a cron job.
Almost every project ends up needing one: clearing temporary files every night, sending a daily digest, refreshing a token, syncing data with another API. The concept is easy. The hard part is getting the schedule expression right and remembering the details that make a job run at the wrong time.
What does a cron expression look like?#
An expression has five fields separated by spaces, followed by the command:
┌───────── minute (0-59)
│ ┌─────── hour (0-23)
│ │ ┌───── day of month (1-31)
│ │ │ ┌─── month (1-12)
│ │ │ │ ┌─ day of week (0-6, Sunday = 0)
│ │ │ │ │
* * * * * command to runEach field takes a number, a list (1,15), a range (1-5) or *, meaning "every value". These elements are part of the POSIX standard. Linux cron adds steps (*/5), month and day names (mon, jan), and accepts 7 as Sunday. The shortcuts @daily, @hourly, @weekly, @monthly, @yearly and @reboot are also Linux extensions, not POSIX.
Which expressions will you use most?#
| Expression | When it runs |
|---|---|
* * * * * |
Every minute |
*/5 * * * * |
Every 5 minutes |
0 * * * * |
At the start of every hour |
0 3 * * * |
Every day at 03:00 |
30 8 * * 1-5 |
Monday to Friday at 08:30 |
0 0 1 * * |
The first day of each month, at midnight |
0 9 * * mon |
Every Monday at 09:00 |
0 0 1 1 * |
Once a year, on January 1 (same as @yearly) |
When in doubt, read the expression aloud field by field: "minute 30, hour 8, any day of month, any month, Monday to Friday".
How do you install a cron job on Linux?#
Open your crontab with crontab -e and add one line per task. This one clears temporary files every day at 03:00 and appends the output to a log:
0 3 * * * /usr/local/bin/clean-temp.sh >> /var/log/clean.log 2>&1List what is scheduled with crontab -l. Three habits prevent most problems:
- Use absolute paths. Cron runs the command with
/bin/shin a minimal environment, without your shell profile. Anodebinary or script that works in your terminal may not be found. - Redirect the output. By default cron tries to email a job's output to the crontab owner. With no mail set up, the output (and the error) is usually lost. Write to a log file, as above.
- Make the script executable (
chmod +x).
What are the most common traps?#
A step is not a continuous interval. A step only applies inside its own field. */35 * * * * runs at minutes 0 and 35 of every hour, not every 35 minutes. For intervals that do not divide 60 or 24 evenly, plain cron will not do: schedule a more frequent task that decides whether to act.
Day of month and day of week form an "OR". When both fields are restricted, the job runs if either one matches. 30 4 1,15 * 5 runs at 04:30 on the 1st and 15th and also every Friday. Anyone expecting an "AND" gets a surprise. If you need "every Friday between the 1st and the 7th", schedule every Friday and test the date inside the script.
Time zones. Cron uses the server's time zone, which is often UTC in cloud environments. There, 0 3 * * * runs at 03:00 UTC, not 03:00 where you live. Implementations such as cronie support a CRON_TZ variable in the crontab, and application libraries have a time zone option. Set the zone explicitly whenever local time matters.
Overlapping runs. If a run takes longer than the interval, the next one starts on top of it. Protect long tasks with a lock file or an "already running" flag.
Daylight saving time. In zones that change clocks, an hour can be skipped or repeated. cronie compensates for fixed-time jobs, but not every scheduler does, and the job for that hour may run twice or not at all. Prefer UTC for critical tasks.
How do you schedule tasks inside a Node.js app?#
Not every environment lets you edit a crontab. On application hosting, the usual route is scheduling inside the process itself with a library. One of the most used in Node.js is node-cron:
npm install node-cron// index.js (needs "type": "module" in package.json)
import cron from "node-cron";
const task = cron.schedule(
"0 3 * * *",
() => {
console.log("03:00 routine in New York:", new Date().toISOString());
// clean files, sync data, send a report...
},
{ timezone: "America/New_York" },
);
// task.stop() pauses and task.start() resumesThe expression is the same five fields. node-cron also accepts an optional seconds field at the start (*/10 * * * * * fires every 10 seconds), which Unix cron cannot do.
This requires the process to stay always on: if the app is stopped or asleep at the scheduled time, the job does not run. That is why an in-process scheduler needs hosting that keeps the container running, with no idle suspension. If you run several instances of the same app, each one fires the job, so run the scheduler in only one. Keep keys and URLs in environment variables, never in code.
When is cron not the right tool?#
Cron is great for clock-driven routines. It is weak when a task depends on an event ("when the user pays, send the receipt"), when it needs automatic retries after a failure, or when the work is heavy and should be spread across several processes. Queues and workers fit those cases better. For the groundwork, see how to host a Node.js application or a Python script that keeps running all the time.
How to do this on Square Cloud#
An in-process scheduler depends on one thing: the process being alive at the scheduled time. On Square Cloud the container stays on, with no sleep mode and no inactivity rule, so the node-cron job above fires on time even if nobody visits the app. With automatic restart, on by default for dashboard deploys, the process comes back by itself when it exits with an error.
In practice:
- Write the job with the library and pass the zone in the
timezoneoption instead of relying on the server clock. - Deploy with a ZIP in the dashboard, the CLI or GitHub. The
squarecloud.appfile is optional: the dashboard generates it with runtime, memory and main file. - Store the job's keys and URLs as the app's environment variables and follow each run in the real-time logs.
A standalone scheduler runs as a background application, with no subdomain. A small app with node-cron fits in 256 MB, the minimum for that kind of application, and Hobby starts at R$12.49 per month with 1 GB of RAM shared across your applications. If your API splits its domain across several applications with load balancing, each copy fires the job: keep the scheduler in a single application. See the options for hosting APIs and jobs on API hosting and the runtime on Node.js.
API hosting
APIs in always-on containers, with no cold starts
FAQs
Are a cron job and a crontab the same thing?
No. A crontab is the file (and the command) where you list schedules. A cron job is each scheduled task inside it. Cron is the program that reads the crontab and fires the jobs.
How do I run a task every 5 minutes?
Use `*/5 * * * *`. The `*/5` step in the minute field fires at minutes 0, 5, 10 and so on, every hour.
What does 0 0 * * * mean?
It runs every day at midnight, in the time zone cron is configured with. Minute 0, hour 0, and the other fields open.
Can cron run at intervals of seconds?
Unix cron cannot, since its smallest unit is the minute. Application libraries such as node-cron accept an optional seconds field at the start of the expression.
More in APIs
See all 15 articles- How to host an APIHosting an API means running its HTTP server around the clock at a public address with HTTPS. Step-by-step with Node.js and Python, testing and common errors.
- How to host a Node.js appTo host a Node.js app, prepare package.json, read the port and secrets from the environment, pick an LTS version and run it with node. Step-by-step guide.
- How to host a FastAPI, Flask or Django appTo host a FastAPI, Flask or Django app, run it with a production server (Uvicorn or Gunicorn) on 0.0.0.0. Commands, Django settings and common errors included.
- How to host a Python app or scriptTo host a Python app or script, pin the version, isolate dependencies in a venv, read secrets from the environment and handle SIGTERM. Step-by-step guide.