✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes CronJob Schedule Management

Kubernetes CronJob Schedule Management ensures reliable task execution through precise scheduling, leveraging Cron syntax and resource allocation for automated operations.

Kubernetes CronJob Schedule Management is the discipline of correctly expressing, interpreting, and operating the time-based recurrence rules that determine when a batch/v1 CronJob creates new Jobs. It centers on the .spec.schedule field and its cron syntax, but extends to time zone handling, missed-schedule recovery, and the operational practices needed to keep recurring workloads firing reliably and predictably as clusters, controllers, and time zones change underneath them.

Because a misconfigured schedule silently produces wrong behavior — running too often, too rarely, or at the wrong time — rather than an obvious error, schedule management requires deliberate verification, not just correct syntax at authoring time.


Cron Schedule Syntax

Standard Five-Field Format

.spec.schedule follows the traditional Unix cron format: minute hour day-of-month month day-of-week, each field accepting a specific value, a * wildcard, a range (1-5), a list (1,15,30), or a step (*/15).

schedule: "0 2 * * *"      # daily at 02:00
schedule: "*/15 * * * *"   # every 15 minutes
schedule: "0 9 * * 1-5"    # weekdays at 09:00
schedule: "0 0 1 * *"      # first day of every month at midnight

Non-Standard Extensions

Kubernetes also accepts a small set of convenience aliases in place of a five-field expression: @yearly, @monthly, @weekly, @daily, @hourly. These are less commonly used in production manifests because their exact meaning is less immediately visible than an explicit cron expression, but they are useful for quick, unambiguous schedules where the exact minute does not matter.

Common Authoring Mistakes

The day-of-month and day-of-week fields are combined with an implicit OR when both are restricted (not both *), which surprises authors expecting an AND — for example, 0 0 1 * 1 runs both on the first of the month and every Monday, not only on a Monday that happens to be the first of the month.


Time Zone Handling

The timeZone Field

.spec.timeZone explicitly sets the IANA time zone (for example, "America/Bogota" or "UTC") the schedule is evaluated against. Before this field was introduced, CronJob schedules were evaluated in the time zone of the kube-controller-manager process, which is often UTC but is not guaranteed to be, making cross-cluster or cross-region schedule behavior inconsistent unless explicitly pinned.

spec:
  schedule: "0 6 * * *"
  timeZone: "America/Bogota"

Daylight Saving Considerations

Time zones with daylight saving transitions can cause a schedule to be skipped or run twice around the transition boundary (for example, a schedule set for a time that does not exist during a spring-forward transition). Workloads sensitive to exact timing across DST boundaries are best scheduled in UTC, which has no daylight saving transitions, and converted to local time only for display purposes.


Missed Schedule Recovery

startingDeadlineSeconds

If the CronJob controller is unavailable when a scheduled tick occurs (due to a control-plane outage or an apiserver disruption), Kubernetes will attempt to start the missed run once the controller recovers, but only if the delay is within .spec.startingDeadlineSeconds. Beyond that deadline, the missed run is simply skipped and counted as a missed schedule rather than started late.

spec:
  startingDeadlineSeconds: 300

Bounded Catch-Up Behavior

Without startingDeadlineSeconds set, Kubernetes bounds catch-up attempts internally (historically limited to 100 missed schedules before giving up entirely and logging an error), which mainly matters for very frequent schedules (sub-minute intervals) during extended controller outages. Setting an explicit deadline is the more predictable way to control this behavior rather than relying on the internal default limit.


Verifying Schedule Behavior

Confirming Last and Next Run

kubectl get cronjob codartium-nightly-report -o jsonpath='{.status.lastScheduleTime}'
kubectl describe cronjob codartium-nightly-report

kubectl describe reports both the schedule and the last scheduled time in human-readable form, which is the fastest way to confirm a CronJob actually fired at the expected time after a schedule change.

Testing a Schedule Without Waiting

kubectl create job --from=cronjob/codartium-nightly-report codartium-test-run-$(date +%s)

Manually creating a Job from the CronJob template validates the Job side of the configuration (image, resources, command) immediately, without needing to wait for or manipulate the actual cron schedule.


Example

apiVersion: batch/v1
kind: CronJob
metadata:
  name: codartium-schedule-example
spec:
  schedule: "0 3 * * *"
  timeZone: "UTC"
  startingDeadlineSeconds: 600
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: nightly-task
              image: codartium/nightly-task:latest