The Context: "The Double Payroll Run"
On the morning of September 4, 2026, at 06:00:00 AM, our automated monthly merchant settlement job ran twice across our Kubernetes production cluster.
The architecture relied on a standard Spring @Scheduled cron job running across four replicated microservice pods. To avoid duplicate execution, developers had added an in-memory lock: if (!isLocked) { isLocked = true; run(); }.
Naturally, because the pods ran in isolated JVM containers, all four pods evaluated isLocked as false simultaneously! Two of the four pods successfully acquired the DB transaction, executing duplicate settlement batches and disbursing ₹38 Million twice to 1,200 merchant accounts.
When the incident commander arrived, the team tried to fix it by setting replicas: 1 in the Kubernetes deployment. At 09:00 PM, the single worker pod crashed due to an OOMKilled event during report generation. Because there was only one replica, the entire evening settlement batch failed to trigger at all. Total baigan ka scheduler (an unreliable, fragile mess).
The Problem Statement
Designing an enterprise distributed cron scheduling engine that guarantees exactly-once execution without single points of failure:
- Schedule Density: Over 25,000 distinct cron schedules executing daily.
- Concurrency Invariant: Under no circumstances may two worker pods execute the same scheduled task slice concurrently.
- Failover SLA: If the elected scheduler leader crashes mid-execution, an active standby must detect the failure and resume execution within 5 seconds.
Visual Architecture
The Core Logic / Process
1. The Distributed Lease vs Task-Level Fencing
A robust distributed scheduler separates Cluster Leadership from Individual Task Execution:
- Cluster Leader: Coordinates what tasks are due by scanning the schedule index. It holds a global distributed lease in Redis or Consul (
SET scheduler_leader pod_uuid NX EX 5). - Task-Level Fencing: Individual tasks must never rely purely on the cluster leader's health. Each execution instance is guarded by a task-level conditional lease:
UPDATE scheduled_tasks
SET
locked_by = 'pod_worker_a',
lock_expires_at = CURRENT_TIMESTAMP + INTERVAL '30' SECOND,
status = 'EXECUTING',
execution_epoch = execution_epoch + 1
WHERE
task_id = 'merchant_settlement_daily'
AND (status = 'IDLE' OR lock_expires_at < CURRENT_TIMESTAMP);
If the update returns ROWS_AFFECTED == 1, that pod holds the exclusive cryptographic lock for that specific scheduled slice. If it returns 0, another pod has already claimed the slice, and the current pod immediately stands down.
2. Autonomous Heartbeat Lease Extension
What if a batch task takes 45 seconds to complete?
- We do not set a static 60-second lock, because if the worker dies after 2 seconds, the task is locked for the remaining 58 seconds.
- Instead, the worker acquires a short 10-second lease.
- A background virtual thread pulses a renewal heartbeat every 3 seconds:
UPDATE ... SET lock_expires_at = CURRENT_TIMESTAMP + 10s. - If the worker pod dies or suffers an unrecoverable crash, the lease naturally expires after 10 seconds, allowing standby workers to safely take over.
3. Idempotent Execution Handshake
Every scheduled execution produces a deterministic execution key:
job_id:scheduled_time_bucket (e.g. settlement:2026-09-04T06:00:00Z).
Before committing any business state (e.g. initiating a bank wire), the worker records this execution key in an immutable audit ledger with a unique constraint. Even if an unannounced network partition causes two pods to claim the lock, the database's unique constraint ensures that only one can commit the final payload.
The "Baigan" Take (Expert Insights)
Many developers use @Scheduled in Spring Boot with replicas: 1 in production and call it a day.
That is pure baigan ki umeed (hoping for miracles). A single-replica pod is not high availability. The node will get upgraded, the spot instance will get reclaimed, or the kubelet will reschedule it, and your critical midnight financial settlement will fail to run.
Run at least 3 scheduler pods. Use Task-Level Distributed Leases with optimistic locking in your database, and guard your business logic with deterministic execution keys. You get 100% high availability, zero single points of failure, and absolute zero-duplicate execution guarantees.
Performance Checklist
- Eliminate all in-memory static lock flags from scheduled task implementations.
- Enforce atomic SQL
UPDATE ... WHERE locked_by IS NULLtask claiming semantics. - Deploy active-standby scheduler clusters with a minimum of 3 replicas.
- Implement heartbeat lease extension with short (5–10 second) rolling TTLs.
- Anchor business transactions with deterministic
job:timestamp_bucketunique keys.