Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › CronJob

Cron Fires on Every Replica: Why Scaled Services Run Scheduled Jobs Twice and How to Stop It

By Freedom251 Team · · 7 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If a cron scheduler lives inside your application process, every replica you add gets its own copy of that scheduler, and each copy fires the same job at the same wall-clock time. The fix is to give the schedule a single owner, either a platform scheduler such as a Kubernetes CronJob or one elected leader among your replicas, and then make the job safe to run more than once.

Why one replica becomes several schedulers

An in-process scheduler is a loop or timer started when the process boots. It has no knowledge of other copies of the same application. With one replica, the loop fires once per trigger. With three, the image starts three loops, and nothing asks whether another loop already claimed the run. The scheduler is replicated along with the code, which is why the duplicate feels like a surprise even though the design does exactly what it was written to do.

As an Amazon Associate I earn from qualifying purchases.

The symptom usually appears after a scale-up, during a rolling deployment that briefly overlaps old and new Pods, or when a crashed replica restarts while its siblings keep running. A nightly invoice run, an email digest, or a cache rebuild then executes several times, and the logs show near-identical timestamps from different instances.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Three layers that are easy to confuse

Most of the confusion comes from treating “scheduling” as one thing. In a Kubernetes cluster, three components are involved, and each does a different job.

#1 Best Overall
Tecmojo 12U Open Frame Network Rack for IT & AV Gear, AV Rack Floor Standing or Wall Mounted,with 2 PCS 1U Rack Shelves & Mounting Hardware,Network Rack for 19" Networking,Audio and Video Device
  • 【Powerful Load-bearing】12U Network Rack Open Frame is constructed from durable cold rolled steel; Rack shelf supports enhance stability, wall-mounted capacity of 130lbs, the ground-mounted up to 260lbs
  • 【Considerate Designs】Open-frame layout, including a top panel adding space, anti-slip shelf stops fixing devices and compatible racks for stack and expansion to meet requirements of home server rack
  • 【Complete Accessories】A 12U open frame server rack, two ventilated shelves, four shelf stops, four velcro straps and a set of equipment mounting screws
  • 【Versatile Application】Ideal for space-efficient multi-device setups in warehouses, retail, classrooms, offices and more; Excellent choices as AV Rack/IT Rack
  • 【Effortless Setup】 Network Rack includes hardware, a comprehensive manual, mounting hole drilling template and an online assembly video to simplify setup
Layer What it does What it does not do
Application replica (your code, including any in-process cron library) Runs its own timer and executes the task when the timer fires Know that other replicas exist, unless you add coordination
CronJob controller Creates a Job object on the schedule defined in a CronJob resource Run your code inside your web or API Pods
Job controller Creates and tracks the Pods belonging to each Job, and creates replacements when Pods fail or are deleted Decide when a schedule fires
kube-scheduler Assigns Pods to Nodes Decide whether an application’s internal cron loop should run in each replica

Moving work from the application into a CronJob removes the timer from every replica, but it adds a new object you must configure correctly. The kube-scheduler is rarely the cause of duplicate runs: it places Pods, and a duplicate-run bug is almost always about which component starts the work.

What a Kubernetes CronJob does and does not guarantee

The Kubernetes CronJob documentation, checked on 7 October 2026, is explicit about two limits. First, scheduling is approximate: in some circumstances the controller can create more than one Job for a single scheduled time, or none. Second, it states that “the Jobs that you define should be idempotent.” A CronJob is a better home for scheduled work than a timer in every replica, but it does not turn a scheduled task into an exactly-once operation.

Rank #2
Sale
StarTech 42U 4-Post Open Frame Rack, 19in, 22-40in, 1323lb/600kg | Mobile or floor mount IT rack, Cage nuts & screws, U & depth markings, Cable management, 80.3in tall
  • ADJUSTABLE DEPTH: 4-Post 42U open frame server rack with 4 vertical rails and adjustable mounting depth 22" to 40" (56,0cm to 101,7cm); Compatible with various servers / switches / data / AV and other IT equipment; EIA/ECA-310-E Compliant
  • EASY ASSEMBLY: Mobile network rack with easy-to-follow assembly instructions and online video; Compact flat-pack shipping to avoid damage and facilitate installation; Total product height of 80.3in (204 cm) with casters, 78in (198cm) without casters
  • COLD ROLLED STEEL: Durable 4 Post 19in open frame rack designed for ventilation with 42U mounting height and 1320lb (600kg) weight capacity (stationary); 3 install options included: casters, levelling feet, or base-plate to secure rack to the floor
  • HARDWARE INCLUDED: Rolling computer/data rack includes cage nuts and screws to mount equipment, easy to read Units (U) and depth adjustment markings, cable management hooks for organization, and required assembly tools
  • THE IT PRO'S CHOICE: Designed and built for IT Professionals, this 42U rack is backed for 2-years, including free lifetime 24/5 multi-lingual technical assistance

Job retries are a second source of repeats. A Kubernetes Job can start another Pod when a Pod fails or is deleted, so a task that partly completed before failing may run again. The task has to tolerate retries, whichever component started it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choosing a fix by architecture

Option A: the work is a batch operation and you run on Kubernetes

This is usually the cleanest route. Move the schedule out of the application into a batch/v1 CronJob, and use the application image as the Job’s container. A minimal manifest looks like this:

Rank #3
VEVOR 12U Open Frame Server Rack, 23-40 in Adjustable Depth, Free Standing or Wall Mount Network Server Rack, 4 Post AV Rack with Casters, Holds All Your Networking IT Equipment AV Gear Router Modem
  • Adjustable Depth: 23-40'' adjustable depth is used for servers and network equipment, ensuring enough space for AV equipment, components, and cabling, while allowing you to access ports and equipment from multiple sides.
  • Strong Load Capacity: Ground-Mounted Load Capacity: 500 lbs, Wall-Mounted Load Capacity: 150 lbs. The av rack is made of carbon steel for better weldability performance and can help save space while meeting your need to place multiple devices.
  • User-friendly Design: Ergonomic design makes the open frame av rack easier to use. The additional top panel is able to place other items with more available space. Roller design moves anywhere and anytime, is convenient, and is more energy-saving.
  • Complete Accessories: We provide the accessories you need, including 2 x Pallets, 145 x M5*10 Cross Head Screws, 4 x Casters, 4 x M10*50 Expansion Screws,10 x M6*12 Cage Nuts, 1 x Grounding Wire, 1 x User Manual.
  • Wide Application: The server rack wall mount maximizes the use of available space, suitable for retail venues, classrooms, offices, and other places where space is limited.
apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-invoice-run
spec:
  schedule: "0 2 * * *"
  timeZone: "Europe/Berlin"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  jobTemplate:
    spec:
      backoffLimit: 2
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: invoice-run
            image: registry.example.com/billing:1.8.2
            args: ["--task", "nightly-invoice-run"]

Apply it with kubectl apply -f nightly-invoice-run.yaml, then confirm the schedule with kubectl get cronjob nightly-invoice-run and watch Job creation with kubectl get jobs --watch. Remove the in-process timer in the same release, or the duplicate will persist.

Three fields need deliberate choices:

  • timeZone: set spec.timeZone explicitly. Without it, the controller interprets the schedule in its own local zone, which may not match what your team means. The field is stable from Kubernetes v1.27.
  • concurrencyPolicy: choose it from the table below.
  • startingDeadlineSeconds: limits how late a missed run may still start. Without a deadline, a long outage can lead the controller to try to catch up on many missed runs.

Choosing a concurrencyPolicy

Policy Behavior when the previous Job is still running Use it when
Allow (default) Starts a new Job, so runs can overlap Runs are independent and idempotent, and overlap is harmless
Forbid Skips the new occurrence until the earlier Job finishes Overlap would corrupt data or double-send messages, and skipping one run is acceptable
Replace Cancels the running Job and starts a new one Only the latest run matters and a stale run should be discarded

These policies apply only among Jobs created by the same CronJob resource. Forbid is not a cluster-wide lock. If two CronJob objects, or two clusters, can run the same logical task, you need a lock or unique key in your own system.

Rank #4
AxcessAbles 12U Network Rack with Wheels - 500lb Capacity, 18" Depth | 19-Inch Open Frame AV Rack Case with 3” Caster Wheels | Screws, Spacer, Tool Included
  • Universal 19” Rack Mount Compatibility – Perfect for pro audio, video, IT, and network gear. Compatible with mixers, routers, patch panels, servers, power amps, and more.
  • Heavy-Duty Load Capacity – Built to support up to 550 lbs. Ideal for studio gear, DJ setups, server equipment, and AV components that demand serious stability.
  • Robust Steel Frame & Design – Made with 1.5mm thick steel and weighs 36 lbs for maximum durability, reduced vibration, and long-term reliability in any setting.
  • Mobile & Secure – Preinstalled with 3” industrial-grade caster wheels (lockable), making it easy to move and position your rack exactly where you need it.
  • All-In-One Setup Kit Included – Comes with 34 rack screws (5mm & 6mm), a 1U blank spacer, and an assembly tool—ready for fast installation out of the box.

Option B: the process must remain the scheduler

Sometimes the schedule depends on application state, or the team cannot move it. In that case, keep the timer but let only one replica act on it. The Kubernetes Lease documentation describes Leases as a way to “select or elect a leader” among controller replicas, and the same mechanism works for custom workloads. The lease records its current holder and renewal time. If the holder stops renewing, another candidate can take over once the lease expires.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A workable pattern:

  1. Create a dedicated Lease name for this scheduler, such as billing-invoice-scheduler, tied to the component so unrelated installations do not collide.
  2. Grant the application’s ServiceAccount permission to get, create, and update that Lease in its namespace, through a Role and RoleBinding.
  3. Have every replica attempt to acquire the lease on each tick. Only the holder runs the scheduled work; the others return without acting.
  4. Keep the renewal interval well below the lease duration so a healthy leader does not lose the lease by accident.

Leader election reduces duplicates but does not make a side effect happen once. A leader can lose connectivity or stop partway through a write, and its successor can retry the same run. Use the lease to choose the active scheduler, and protect the work itself as described next.

Best Value
VEVOR 9U Open Frame Server Rack Network Rack 23-40 in Adjustable Depth | Free Stand or Wall Mount, with 2Pcs 1U Rack Shelves & 4 Casters, Holds All 19'' Networking IT Equipment AV Gear Router Modem
  • Adjustable Depth: Depth adjustable from 23" to 40", this open frame server rack accommodates servers and network equipment while providing ample space for A/V gears and cable management. Enjoy easy access to ports and devices from multiple angles.
  • High Weight Capacity: Supports up to 300 lbs on the floor (200 lbs when adjusted to maximum depth) and 200 lbs when wall-mounted (depth cannot be adjusted in wall-mounted mode). Made from carbon steel for superior welding performance and durability, this open frame rack is designed to save space while accommodating multiple devices.
  • User-Friendly Design: Designed with your convenience in mind, this open frame server rack features an top shelf for extra storage and improved space utilization. The rolling casters let you move it effortlessly wherever you need it, making setup and movement a breeze.
  • Widely Applicable: Maximize your space with this adaptable open frame server rack, designed to make the most of every inch. Ideal for retail spots, classrooms, offices, and any area where space is at a premium, it delivers practical solutions for your storage needs.
  • Everything You Need: Our open-frame rack comes with fully equipped accessory kit for easy setup and secure installation: 2 x Trays, 4 x Casters, 1 x set of Screws, 16 x M6*12 Cage Nuts, 1 x Grounding Wire, 1 x Internal & External Hex Wrenches, and 1 x User Manual.

Option C: the runtime is not Kubernetes

The principle is the same on any platform. Either elect one scheduler across replicas through a coordination store you already run, or move the schedule into a single dedicated scheduling service. The right primitive depends on your database, your deployment model, and how you want the system to behave during a network partition. Some teams accept a skipped run during a partition; others prefer a delayed run after recovery. Decide that before choosing a tool.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make the work safe to run twice

Whichever option you choose, the task should produce the same result when it runs more than once for the same logical period. Three techniques cover most cases:

  • Idempotency key per run: derive a key from the task name and the scheduled period, for example nightly-invoice-run:2026-10-09, and pass it to every external call that accepts one.
  • Durable run record with a unique constraint: insert a row before doing the work, so a second attempt fails on the constraint.
  • Transaction boundary: where your database allows it, write the business effect and the run record in the same transaction.
CREATE TABLE scheduled_runs (
  task_name   text NOT NULL,
  run_period  date NOT NULL,
  started_at  timestamptz NOT NULL DEFAULT now(),
  PRIMARY KEY (task_name, run_period)
);

-- Each replica or retry attempts this first.
-- Zero rows returned means another run already claimed the period.
INSERT INTO scheduled_runs (task_name, run_period)
VALUES ('nightly-invoice-run', '2026-10-09')
ON CONFLICT DO NOTHING
RETURNING task_name;

This guard also covers cases the scheduling mechanisms miss: a second CronJob object, a manual re-run, or a retry after a timeout. The database does not care which scheduler asked.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting duplicate runs

  • Duplicates appear only after a scale-up: an in-process timer is still active in the new replicas. Log the scheduler start message with the Pod name and check whether every replica prints it.
  • Duplicates appear during a rolling update: old and new versions overlap briefly. Keep the timer in only one version of the workload, or gate it behind the leader lease for the whole rollout.
  • Two Jobs appear for one scheduled time: this is the approximate-creation behavior described in the CronJob documentation. Make the Job idempotent rather than trying to stop the controller from creating it.
  • A run is missing: check startingDeadlineSeconds, whether concurrencyPolicy: Forbid skipped it because a previous Job was still active, and whether the time zone matches your expectation.
  • A Job retried after partial success: the task is not idempotent. Add the run-record guard before changing the schedule.

Sources and check dates

The Kubernetes statements in this article come from the official documentation pages for CronJob, Jobs, Leases, Coordinated Leader Election, and the Kubernetes scheduler, as checked on 7 October 2026. Version-specific fields and behavior can change, so confirm them against the documentation for your cluster version before relying on them.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

CronJobDevOpsdistributed systemsKubernetesleader electionscheduled jobs

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.