SOFTWARE / SYSTEMS / AIEngineering news. Technical depth.
Architecture / 3 MIN READ

What should happen when a Kubernetes CronJob is still running at its next scheduled time?

Pick skip, overlap, or replacement from the job’s side effects and freshness requirements instead of inheriting Kubernetes defaults by accident.

If a Kubernetes CronJob is still running when the next schedule arrives, decide the outcome from the job’s business effect. Use Forbid when duplicate execution would be harmful, Allow when overlapping runs are independently safe, and Replace when stale work should be abandoned for fresher output. Kubernetes exposes these choices through .spec.concurrencyPolicy, and also lets you skip starts that are too late with .spec.startingDeadlineSeconds in the official CronJob documentation.

Which CronJob policy should you choose?

The Kubernetes CronJob documentation defines three concurrency policies. Allow permits concurrent runs. Forbid skips the new run if the previous one is still active. Replace terminates the current run by replacing it with a new one.

That means the policy should follow the kind of mistake you can tolerate.

Choose Forbid for duplicate-sensitive work: invoice creation, payout files, entitlement backfills, or any task where two overlapping runs could create conflicting writes. In these cases, a skipped run is usually safer than two writers operating at once.

Choose Allow only when overlap is safe by design. Good examples are jobs that process partitioned inputs or claim work through a single enforced ordering boundary, such as a database uniqueness constraint, or a compare-and-set update on the record being claimed, together with idempotent effects. A queue acknowledgment alone does not serialize claims or prevent redelivery. A preflight check like “see whether a row exists, then write it” is not enough, because two runs can pass that check before either commits.

Choose Replace for freshness-driven work where partial progress is disposable: cache rebuilds, report snapshots, or periodically regenerated search data. If the value comes from having the newest result, replacing stale work is cleaner than letting old and new runs compete.

What does Kubernetes guarantee, and what does it not?

A CronJob “starts one-time Jobs on a repeating schedule” and a Job represents “one-off tasks that run to completion and then stop,” according to the official CronJob documentation and Job documentation.

That is a scheduling and retry model, not a business-correctness model. Setting Forbid reduces overlap for one CronJob. It does not make writes idempotent, coordinate unrelated services, or create an atomic transaction across systems. If a run can be retried, interrupted, or replaced, the application still needs a commit boundary that makes each side effect safe.

How should deadlines affect the decision?

Use .spec.startingDeadlineSeconds to define how late a run may start before Kubernetes skips it. The CronJob documentation states that after missing this deadline, “the CronJob skips that instance of the Job.”

This matters especially with Forbid. If the previous run blocks the next schedule and finally finishes later, Kubernetes still checks the deadline before starting the missed run. So ask two questions together: is overlap unsafe, and is a late run still useful?

Worked example:

  • A nightly invoice generator should usually use Forbid. Duplicate execution is dangerous, and a late run may still be acceptable if accounting can tolerate delay.
  • A five-minute dashboard cache refresh should usually use Replace. The newest snapshot matters more than preserving partial work from the previous run.

What about missed runs and catch-up?

If catching up late still delivers value, set a deadline long enough to absorb controller delay or a short outage. If stale output is useless, keep the deadline short and skip the missed run deliberately. Do not treat catch-up as a substitute for application logic that knows which business period has and has not been processed.

Questions about CronJob overlap and replacement

Should I default to Allow because it is the Kubernetes default?
No. Defaulting to Allow is reasonable only when overlapping runs are already safe at the data boundary.

Does Replace preserve progress from the run it interrupts?
No documented CronJob behavior guarantees that. Use it only when interrupted work can be discarded or rebuilt safely.

Next step: classify your CronJob as duplicate-sensitive, overlap-safe, or freshness-driven, then set both concurrencyPolicy and startingDeadlineSeconds explicitly in the manifest.

Reviewed: 2026-09-05

SOURCES & REVIEW

Sources are linked throughout this guide. Product capabilities can change; consult the linked documentation for your deployment.

Read our editorial approach ↗