What is Scheduled Cloud Code (Cron Jobs)?

Last updated: July 2026

A cron job is a task that runs automatically on a time schedule; scheduled Cloud Code applies the idea to serverless functions. The lineage runs from Version 7 Unix through Vixie cron (1987) to today’s platform schedulers, and the model barely changed: a daemon wakes every minute, reads a table of schedule + command lines — the crontab — and fires what matches. What changed is everything around the model: where the clock lives, what happens when a run fails, and whether anyone notices.

Key takeaways

QuestionAnswer
The syntaxFive fields — minute · hour · day-of-month · month · day-of-week
The floorOne-minute granularity; seconds need a different scheduler
The gotchasDST skips and double-fires · the day-of-month/day-of-week OR rule
The reliability gapClassic cron: no retries, no catch-up, no cluster, silent failure
The modern formSchedule as platform config on a function — clock, logs, and retries managed

Cron in one screen

┌ minute (0–59)   ┌ hour (0–23)   ┌ day of month (1–31)   ┌ month   ┌ day of week (0–7)
*                 *               *                        *         *        command

0 2 * * *        daily at 02:00          */15 * * * *   every 15 minutes
0 9 * * 1-5      weekdays at 09:00       0 6,18 * * *   06:00 and 18:00
0 0 1,15 * *     the 1st and 15th        @daily         = 0 0 * * *
@reboot          once at daemon start    @hourly        = 0 * * * *

crontab -e   edit your table      crontab -l   list it
crontab -ri  remove (with prompt — bare -r wipes it, no questions asked)

The modern equivalent — the job in code, the schedule in a dashboard, the client just reading results:

// JavaScript — Cloud Code (cloud/main.js)
// A scheduled job: defined in code, scheduled in the dashboard
Parse.Cloud.job('nightlyReport', async (request) => {
  const since = new Date(Date.now() - 24 * 60 * 60 * 1000);

  // Idempotent by date key: a rerun overwrites tonight's report, not duplicates
  const existing = await new Parse.Query('DailyReport')
    .equalTo('runDate', dateKey(new Date()))
    .first({ useMasterKey: true });
  const report = existing ?? new Parse.Object('DailyReport');

  report.set('runDate', dateKey(new Date()));
  report.set('summary', await summarizeOrdersSince(since));
  await report.save(null, { useMasterKey: true });
  request.message('Report written'); // shows in the dashboard's job status
});

The gotchas the man page knows

Four semantics from crontab(5) that surprise nearly everyone. The OR rule: when both day-of-month and day-of-week are restricted, the job fires when either matches — 0 0 13 * 5 runs on the 13th and every Friday, not only on Friday the 13th. DST, verbatim: jobs scheduled in the spring-forward “missing hour” never run; times that occur twice at fall-back run twice — schedule in UTC, keep critical work out of the local small hours. Steps reset at field boundaries: */90 in the minute field cannot mean “every 90 minutes” — the counter resets each hour; true odd intervals need a real scheduler. The minute floor: the daemon scans once a minute; anything finer is another tool’s job.

The reliability gap

Classic cron is a scheduler, not a reliability system, and the gap has a shape: no retries (a failed run is a failed run); no catch-up (a machine asleep at 02:00 skips the run — anacron and systemd timers’ persistence option exist precisely for this); no cluster story (two servers with the same crontab run everything twice; one server is a single point of failure); silent failure (output mails a local account nobody reads). Modern schedulers answer each gap with named policy: misfire policies (Quartz’s fire-now vs. skip), concurrency policies (Kubernetes’ allow/forbid/replace for overlapping runs), and deadline-based skip semantics — while honestly documenting that distributed scheduling is approximately once: a run may occasionally double or not fire at all. Which yields the discipline both worlds share: scheduled jobs must be idempotent — keyed on their period (the code tabs’ report keyed by date) so a rerun overwrites rather than duplicates, and a missed run is recoverable by running late.

A scheduled serverless function with monitoringA schedule configured in the platform dashboard fires a cloud job at the set recurrence. The job runs with logs and status recorded by the platform, writes its idempotent results to the database, and pings a heartbeat monitor on success, so a missed or failed run is detected by the absence of the ping.

idempotent write
keyed by date

on success

ping absent past grace
period → alert

Dashboard schedule
02:00 UTC daily

Platform clock fires

Cloud Job runs
status + logs recorded

Database

Heartbeat ping

Monitor

A schedule configured in the platform dashboard fires a cloud job at the set recurrence. The job runs with logs and status recorded by the platform, writes its idempotent results to the database, and pings a heartbeat monitor on success, so a missed or failed run is detected by the absence of the ping.

Classic cron vs. systemd timers vs. distributed schedulers vs. scheduled functions

Classic cronsystemd timersDistributed (Quartz/K8s-style)Scheduled cloud functions
LivesOne machine’s crontabOne machine, unit filesA clusterPlatform config on a function
Catch-upNone (anacron bolts it on)Persistent=trueMisfire policiesPlatform policy
OverlapStarts another copySerialized per unitallow / forbid / replacePlatform policy
RetriesNoneService restart rulesConfigurableBuilt in
Failure visibilityLocal mail, unreadjournaldJob status objectsDashboard status + logs
Server to keep aliveYes — and it’s the SPOFYesThe clusterNo

Watching schedules

Scheduled failure is the quietest failure in computing: a job that never fired emits nothing — no exception, no log line, no email — because nothing ran. The pattern that fixes it inverts the alarm: heartbeat monitoring — the job pings a URL on successful completion, the monitor expects the ping within a grace period, and absence triggers the alert. Pair it with the mundane hygiene classic cron never had: run duration tracked over time (the report that took 4 minutes last month and 40 tonight is telling you something), output captured to real logs instead of local mail, and the schedule inventory documented — because a crontab scattered across five servers is how organizations discover jobs they forgot they ran.

Common use cases

  • Reports and digests — the nightly rollup the code tabs sketch: aggregate, write, notify.
  • Cleanup and expiry — TTL sweeps, orphan pruning, session and token expiration passes.
  • Data synchronization — periodic pulls from third-party systems that offer no webhooks.
  • Reminders and re-engagement — time-based sends: trial endings, abandoned carts, renewal notices.
  • Health and reconciliation — the scheduled audit that catches what event-driven paths missed.

Which scheduler should you use? A decision matrix

SituationReach for
One Linux box you already operateClassic cron — with locks and a heartbeat
Laptop-grade or intermittent machinesanacron / systemd timers with persistence
A cluster you run anywayIts native scheduled-job controller
App backend on a BaaSScheduled Cloud Jobs — no server, logs included
Sub-minute or odd intervalsA real scheduler or queue, not crontab arithmetic
Event-shaped work mislabeled as scheduledThe job queue — cron only feeds it

Limitations and trade-offs

  • Time triggers describe when, not whether. A schedule fires regardless of whether there’s work; event-driven triggers and queues fit work that arrives irregularly.
  • Approximate-once is the honest contract. Even managed schedulers occasionally double-fire or skip; idempotency is the job’s responsibility everywhere.
  • Timezones are a policy decision. UTC schedules survive DST; local-time schedules serve humans — pick deliberately, document loudly.
  • Frequency has a floor and a price. Minute-level classic cron, platform-dependent floors elsewhere; polling-by-cron at high frequency is usually a queue wearing a clock.
  • Schedules accumulate silently. Every “temporary” nightly job is permanent until inventoried; the dashboard listing them all is an underrated feature.

Scheduled Cloud Code on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. Scheduling here is the modern column of the comparison table made concrete: define Parse.Cloud.job in Cloud Code — the code tabs’ nightly report, idempotent by date key, master-key access for the cross-user aggregation — then schedule it in the dashboard’s Background Jobs panel: job name, start time, recurrence, no crontab syntax and no server whose crontab it would live in. Runs, status, and errors land in the server logs and jobs panel — the failure-visibility column answered by default — and the disciplines this article closes with remain yours by design: key jobs to their period, keep them idempotent, and let a heartbeat confirm the platform’s clock and your logic agreed tonight, like every night.

Frequently asked questions

What is a cron job?

A task scheduled to run automatically at fixed times or intervals — classically by the cron daemon on Unix systems reading a crontab, and by extension any time-triggered job on any platform. The name comes from chronos, Greek for time.

What do the five fields in a cron expression mean?

Minute (0–59), hour (0–23), day of month (1–31), month (1–12), day of week (0–7, where both 0 and 7 are Sunday), followed by the command. Asterisk means every value; commas list, dashes range, slashes step.

What are @daily, @hourly, and @reboot?

Shorthand strings replacing the five fields: @hourly, @daily, @weekly, @monthly, @yearly map to their obvious expressions, and @reboot runs once when the daemon starts — a nonstandard but widely supported extension.

How do I create and manage cron jobs?

crontab -e edits your table, crontab -l lists it, and crontab -r removes it entirely — famously adjacent to -e on the keyboard and unprompted, so prefer -ri. Each line is a schedule plus a command; the daemon checks every minute.

What happens if the machine is off at the scheduled time?

Classic cron simply skips the run — there is no catch-up. That is why anacron exists for intermittently powered machines, why systemd timers offer a persistence option, and why modern schedulers make catch-up policy an explicit setting rather than a surprise.

How does cron handle daylight saving time?

Badly, by default: per the manual itself, jobs scheduled in the springtime "missing hour" never run, and times that occur twice at fall-back run twice. The standing advice: schedule in UTC and keep critical jobs out of the local 00:00–03:00 window.

What if a job is still running when the next run starts?

Classic cron happily starts a second copy — and a third. Overlap needs an explicit answer: a lock file that makes the late run skip, or the formalized policies of modern schedulers — allow, forbid, or replace the running instance.

How do I know when a cron job fails?

By default, you don't — output goes to local mail nobody reads, and a schedule that never fires produces no error at all, because nothing ran. The pattern that fixes it: heartbeat monitoring — the job pings a URL on success, and the absence of the ping raises the alarm.

Can cron run a job more often than once a minute?

No — one minute is classic cron's floor; the daemon wakes, scans, and fires per minute. Second-level granularity needs a different scheduler: Quartz-style six-field expressions, a loop inside a service, or an event queue rather than a clock.

Do I need a server to run cron jobs?

Not anymore. Serverless platforms attach a schedule directly to a function: the platform owns the clock, fires the job, records logs and status, and retries per policy — a schedule as configuration rather than a file on a machine you must keep alive.

Related terms

Compare with

Further reading

Ready to build your backend?

Start your project on Back4app in minutes — database, auth, APIs, and Cloud Code included. No credit card required.

Written and reviewed by Back4app Engineering, Back4app Engineering · Published 2026-07-30