Scheduled Job Ran Twice: Prevent Duplicate Work
Investigate duplicate scheduled work through scheduler identity, overlap, retries and time zones, then protect the business operation from repetition.
The essentials
- A duplicate scheduled action can come from overlapping runs, multiple scheduler instances, retries or ambiguous time handling.
- Preventing two processes from starting simultaneously is not enough: the business operation also needs a durable identity.
On this page
A duplicate scheduled action can come from overlapping runs, multiple scheduler instances, retries or ambiguous time handling. Preventing two processes from starting simultaneously is not enough: the business operation also needs a durable identity.
Identify the two runs
Record scheduled time, actual start time, scheduler identity, job identity and attempt number. Distinguish two attempts of one occurrence from two independently scheduled occurrences.
Kubernetes' CronJob documentation discusses scheduling limits, concurrency policy and the need for idempotent jobs. Other schedulers have different guarantees; use their actual contract.
Check whether deployment created a second scheduler or left an old scheduled task active.
Define one intended occurrence
For a daily report, the operation identity might include report type, recipient and reporting date. For a cleanup job, it might include a bounded period and scope.
Do not use process start time alone: a delayed retry would look like a different operation. Store the intended occurrence before executing external effects.
| Cause | Evidence |
|---|---|
| Overlap | Prior run still active |
| Multiple schedulers | Different scheduler identities |
| Retry | Same intended occurrence, new attempt |
| Time-zone confusion | Different interpretation of scheduled time |
| Manual rerun | Operator-triggered execution |
Choose overlap behavior deliberately
Decide whether a late run should be skipped, queued or allowed to overlap. A report and a maintenance task may need different policies.
A lock can reduce simultaneous work, but it needs safe expiry and crash handling. It does not by itself solve a process that completed an external action and then died before recording completion.
Protect the action with a unique operation record and provider idempotency where available. Reconcile uncertain outcomes before repeating them.
Make time explicit
Record the scheduler's configured time zone and the business period the job represents. Consider daylight-saving changes and delayed execution.
A job that starts after midnight may still belong to the previous reporting day. Calculate that period from the intended occurrence, not blindly from the worker's current clock.
For globally fixed schedules, UTC can simplify interpretation; for local business deadlines, use the appropriate named time zone and test transitions.
Test the failure paths
Run the same occurrence twice, start two workers concurrently and simulate a crash after the business effect. Verify the intended outcome and an understandable audit record.
For AI agent workflows, protect the scheduled trigger before starting another expensive run. Keep prompts and generated output separate from the durable job ledger so a retry can reuse completed work instead of recreating it.
Related troubleshooting
This guide draws on the linked documentation. Examples are illustrative unless explicitly identified as measured results.
Practical guides published by Lucivo, developed with AI assistance and references to official documentation. Examples are illustrative unless a guide explicitly documents a hands-on test. Check the linked sources for current product details.
Related articles
AI Streaming Arrives All at Once Behind NGINX
API Key Committed to Git: What to Do Next
API Timeout: Is It Safe to Retry?
The Weekly Breakdown
High signal AI & software stories.
Direct to your inbox. No hype.
Independent analysis of AI models, developer tools, and computing architectures. Delivered every Sunday morning. 100% free.