Troubleshooting

How to Resolve ColdFusion Scheduled Task Duplicate Execution

Overview of the Problem

ColdFusion scheduled task duplicate execution occurs when a task runs more than once for a single schedule interval. You may see two or more executions within the same minute, overlapping runs that interfere with each other, or the same job running on multiple servers in a cluster at the same time. This typically happens due to Configuration settings that allow overlap, cluster misconfiguration, network retries, or long-running tasks that collide with the next trigger.

Why it matters: duplicates can cause double billing, duplicate emails, repeated inserts, deadlocks, file corruption, and unpredictable job outcomes. The scheduler in ColdFusion is powerful, but it must be configured and coded defensively to prevent concurrency and multi-node duplication.


Symptoms You Might See

  • Multiple email notifications from the same task in the same interval.
  • Duplicate database rows or duplicate file generation.
  • Overlapping logs showing the same task started twice at nearly the same time.
  • CPU spikes during scheduled intervals.
  • Error logs with locking, deadlock, or “file in use” messages.

Example excerpts:

scheduler.log
“INFO”,”scheduler”,”ScheduledTask”,”Executing task: NightlyJob at 02:00:00″
“INFO”,”scheduler”,”ScheduledTask”,”Executing task: NightlyJob at 02:00:00″ <– duplicate start

application.log
“INFO”,”app”,”NightlyJob”,”Start id=20240901-020000-1″
“INFO”,”app”,”NightlyJob”,”Start id=20240901-020000-2″


Possible Causes

Configuration and Platform Causes

  • Overlap/concurrency settings allow simultaneous runs.
  • The task is configured on each node in a cluster (replicated configuration) instead of using a true clustered job.
  • “Run at server startup” triggers multiple times (multi-instance).
  • The CF service is running more than once (accidental duplicate instances).
  • Time drift/NTP issues or DST shifts cause misfires or duplicate triggers.
  • Misfire handling re-fires tasks after downtime or resource contention.
  • Older ColdFusion updates with scheduler bugs not patched.

Application- and Network-Level Causes

  • The task URL is publicly accessible and hit by external monitors or health checks.
  • Load balancer retries (e.g., on 5xx) result in duplicate requests to the same URL.
  • Long-running job overlaps with its next scheduled start.
  • Code is not re-entrant safe; it lacks serialization or idempotency.
  • Multiple tasks with different names point to the same URL.
See also  How to Resolve CFScript Compilation Issues

Step-by-Step Troubleshooting Guide

Step 1: Confirm duplicates with logs

  • Check ColdFusion logs:
    • scheduler.log for task start times
    • application.log/console (coldfusion-out.log) for your own job instrumentation
    • exception/error logs for locking and retries
  • Add request correlation to the job URL if not already present:



If you see multiple “Start” entries for the same scheduled time, the job is duplicating.

Step 2: Determine overlap vs multi-node

  • Compare timestamps: if two executions start within milliseconds/seconds on the same node, it’s likely an overlap/concurrency issue.
  • If you have multiple ColdFusion instances or a cluster, verify which instance logs the execution. Duplicates across different nodes indicate cluster-level duplication.

Tip: Include the hostname/instance name in logs.

<cfset writeLog(file=”NightlyJob”, text=”Start on #cgi.SERVER_NAME# / #createObject(‘java’,’java.net.InetAddress’).getLocalHost().getHostName()#”)>

Step 3: Inspect the scheduled task configuration

  • ColdFusion Administrator:
    • Ensure the task is not defined multiple times with different names hitting the same URL.
    • Review concurrency/overlap settings: choose “Disallow concurrent execution” or “Skip if running.” Avoid “Run concurrently.”
    • Check misfire policy (e.g., “Ignore,” “Fire now,” “Next scheduled time”) and adjust to avoid unexpected catch-up spikes.
    • Confirm the frequency and timeouts. If the job runs for 12 minutes, don’t schedule it every 5 minutes without overlap protection.

Note: In code, the cfschedule tag supports attributes to control concurrency and misfires. Attribute names can vary by CF version. Look for overlap/concurrent and onMisfire equivalents.

<cfschedule
action=”update”
task=”NightlyJob”
url=”http://127.0.0.1/scheduled/NightlyJob.cfm?token=SECURE
startDate=”#dateFormat(now(),’mm/dd/yyyy’)#”
startTime=”02:00 AM”
interval=”daily”
timeout=”1800″
onMisfire=”ignore”
overlap=”false”>

Step 4: Check cluster and instance topology

  • Enterprise/clustered deployments:
    • If you want only one execution across the cluster, configure a “clustered” scheduled task in the Administrator rather than separate tasks per node.
    • Verify that the task isn’t cloned on each node (common mistake during manual setup or export/import).
    • If clustered scheduling is not available, use a distributed lock (database or cache) to ensure a single active runner.

Step 5: Validate time sync and DST

  • Ensure all nodes use NTP and the same timezone.
  • Review DST transitions around schedules; adjust jobs to safe times or use cron expressions that avoid ambiguous hours.
  • Review misfire behaviors after restarts or pauses.

Step 6: Scan for external triggers and retries

  • Confirm that only ColdFusion’s scheduler calls the URL:
    • Use a secret token in the query string or header.
    • Set firewall rules or IP allowlists.
    • Point the task URL to 127.0.0.1 or a local connector to avoid going through the load balancer.
  • Check load balancer/monitor settings for URL probes that may hit your task endpoint.
  • Inspect web server and access logs for unexpected clients calling the task.

Step 7: Look for code-level reentrancy and long runtimes

  • Instrument start/end logs with durations.
  • If runtime often exceeds the interval, either increase the interval or enforce a lock/skip mechanism in code.
  • Ensure the job is idempotent, so duplicates cause no harm.

Solutions You Can Apply

Quick configuration fixes

  • In ColdFusion Administrator for the task:

    • Set concurrency to disallow overlap or to “skip if running.”
    • Use a safe misfire policy (“ignore” or “next”) to avoid batch duplicates.
    • If clustered: configure a single clustered task rather than per-node tasks.
    • Use a loopback URL (http://127.0.0.1/…) to prevent load balancer retries.
  • Patch ColdFusion to the latest update to benefit from scheduler fixes.

See also  How to Troubleshoot ColdFusion Cluster Synchronization Issues

Code-level serialization with CF locks

When configuration alone isn’t enough or to protect across multiple paths, add a named lock.

Using cfmutex (preferred) or cflock:









    <cfset application.nightlyJobRunning = true>
    <cfset start = getTickCount()>

    <!--- Do the work --->
    <!--- ... your job code ... --->

    <cfset writeLog(file="NightlyJob", text="Completed in #getTickCount()-start# ms")>
    <cfset application.nightlyJobRunning = false>
</cfmutex>







Notes:

  • Use a consistent lock name.
  • Keep the critical section as small as possible.
  • This protects within a single instance; for a cluster-wide guarantee, use a distributed lock.

Single-execution via database lock (cluster-safe)

Use your database as the source of truth to ensure only one node proceeds.

  • SQL Server example (sp_getapplock):



EXEC sp_getapplock @Resource = ‘NightlyJob’, @LockMode = ‘Exclusive’, @LockTimeout = 1000;

<cfif getLock.recordcount EQ 1>

<!--- ... job ... --->

<!--- Release --->
<cfquery name="releaseLock" datasource="AppDSN">
    EXEC sp_releaseapplock @Resource = 'NightlyJob';
</cfquery>



  • MySQL example (GET_LOCK):


SELECT GET_LOCK(‘NightlyJob’, 1) AS gotLock;




SELECT RELEASE_LOCK(‘NightlyJob’);



  • PostgreSQL example (advisory lock):


SELECT pg_try_advisory_lock(123456789) AS gotLock;




SELECT pg_advisory_unlock(123456789);



This approach ensures only one node can run the task at a time.

Idempotent job design

  • Use upsert patterns instead of blind inserts.
  • Checkpoints: write progress markers so re-runs know what’s already processed.
  • Make file writes atomic (write temp + rename) to avoid partial overlaps.
  • Use unique keys and conflict handling to prevent duplicates.

Harden the trigger URL

  • Require a secret token or header, verify server-side:




  • Restrict to loopback IP or specific subnets in your web Server config.
  • Ensure monitoring tools don’t ping the job URL.

Cause / Solution Quick reference

  • Overlap enabled or long runtimes

    • Solution: Set “Disallow concurrent execution” or implement cfmutex/cflock; increase interval or reduce runtime.
  • Task defined on each cluster node

    • Solution: Use a single clustered task or a database lock to serialize across nodes.
  • Misfire after downtime

    • Solution: Adjust misfire policy to “ignore” or “next,” avoid “fire now” for heavy jobs.
  • External hits or load balancer retries

    • Solution: Loopback URLs, tokens, IP allowlists, and remove task URL from health checks.
  • Time drift/DST confusion

    • Solution: NTP sync across nodes; schedule around DST; use cron with care.
  • Old CF scheduler bugs

    • Solution: Patch ColdFusion to the latest update.

Common mistakes and How to Avoid Them

  • Mistake: Relying on cflock scoped to application/session for cluster safety.

    • Avoid: Use database advisory locks or a distributed cache lock (e.g., Redis) for cluster-wide serialization.
  • Mistake: Creating two tasks with different names pointing to the same URL.

    • Avoid: Keep a single source of truth and Audit the task list per environment.
  • Mistake: Letting the scheduled task URL be public.

    • Avoid: Restrict to loopback or require a secret token; deny via web server rules.
  • Mistake: Assuming “skip if running” is set, but it’s not (or not supported).

    • Avoid: Verify the actual task settings in the Administrator and test behavior.
  • Mistake: Locking only part of the job.

    • Avoid: Include all side-effect-causing operations within the serialized block.
  • Mistake: Forgetting to release DB locks on error.

    • Avoid: Use cftry/cfcatch/cffinally to release locks reliably.
See also  How to Fix Datasource Connection Failure in ColdFusion

Prevention Tips / Best practices

  • Prefer one centralized job execution per function; if clustered, use clustered tasks or distributed locks.
  • Enforce no-overlap at two levels:
    • Configuration: “Disallow concurrent execution.”
    • Code: cfmutex or DB advisory locks.
  • Design jobs to be idempotent and checkpoint-driven.
  • Use loopback URLs and a secret token/header to avoid external triggers.
  • Stagger schedules to prevent resource contention; avoid “top of the hour” pile-ups.
  • Right-size timeouts and intervals; if the job takes 10 minutes, schedule it for 15+ minutes or make it resumable.
  • Implement structured logging with correlation IDs; persist start/end with durations.
  • Keep ColdFusion updated; review release notes for scheduler fixes.
  • Synchronize time via NTP across all nodes; plan for DST transitions.
  • Treat scheduled task definitions as code (export, version, document changes).

Monitoring and Verification

  • Add health dashboards showing:
    • Last success timestamp, duration, and result count.
    • Whether the job skipped due to lock or overlap detection.
  • Alert if:
    • The job hasn’t run successfully in N minutes/hours.
    • Duration spikes beyond a threshold.
  • Periodically test misfire behavior by pausing and resuming the scheduler in a non-production environment.

Key Takeaways

  • Duplicate scheduled task executions stem from overlap settings, cluster duplication, long runtimes, misfires, and external retries.
  • Fixes span configuration (disallow concurrency, clustered tasks, loopback URLs), code-level locks (cfmutex/cflock), distributed locks (DB advisory locks), and idempotent design.
  • Harden the task endpoint against external triggers; always log with correlation IDs and instance info.
  • Keep CF patched, time synchronized, and schedules staggered; monitor and alert on anomalies.

FAQ

Why does my task run twice only on our clustered environment?

Usually because each node is running its own non-cluster-aware task. Configure a single clustered task in ColdFusion Enterprise or implement a distributed lock (database advisory lock) so that only one node proceeds at each interval.

Can I rely only on cflock to prevent duplicates across servers?

No. cflock and cfmutex prevent overlap inside a single JVM/instance. To protect across multiple instances or servers, use a distributed mechanism such as database advisory locks or a cluster-aware scheduler configuration.

What should I set for misfire handling?

For heavy or non-idempotent jobs, prefer “ignore” or “next scheduled time” to avoid a burst of catch-up runs. Use “fire now” only if the job is designed for it and can handle backlogs.

How do I stop external systems from triggering the task URL?

Use a loopback URL (http://127.0.0.1/…), require a secret token or custom header, apply IP allowlists/firewall rules, and ensure monitoring tools do not call the job endpoint.

Our job sometimes takes longer than its interval. What’s the safest pattern?

Increase the interval or add a lock that skips if already running. Combine with idempotent operations and checkpoints so that partial runs can resume cleanly without duplication.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.