Skip to main content

How to Implement a Cooldown Period Between Script Runs in Batch Script

Automation is powerful, but sometimes it is too powerful. If a user (or an automated task) triggers a script too frequently, it can overwhelm a server, hit API rate limits, or cause resource conflicts. A "Cooldown Period" ensures that once a script finishes, it cannot be run again until a specific amount of time has passed. This protects your infrastructure and ensures that your automation remains stable and predictable.

This guide will explain how to use a timestamp file and simple Batch math to implement a cooldown guard.

The Logic: Timestamp Comparison​

To enforce a cooldown, the script must:

  1. Read: Find the time the script last finished (stored in a text file).
  2. Compare: Check if the current time is greater than LastRunTime + Cooldown.
  3. Execute: Either run the task or show a "Wait" message and exit.

Method 1: The Short Cooldown (Seconds-Based)​

This script ensures that at least 60 seconds pass between successful executions. Best for cooldowns under 24 hours.

@echo off
setlocal enabledelayedexpansion

set "CooldownSec=60"
set "TimeFile=%temp%\cooldown_%~n0.txt"

:: Support a --force flag to bypass the cooldown
if /i "%~1"=="--force" (
echo [INFO] Force flag detected. Bypassing cooldown.
goto :RunTask
)

:: 1. Calculate current 'Total Seconds' from %time%
set "t=!time: =0!"
set /a "current_s=(1!t:~0,2!-100)*3600 + (1!t:~3,2!-100)*60 + (1!t:~6,2!-100)"

:: 2. Check if a previous timestamp exists
if exist "%TimeFile%" (
set /p "last_s=" < "%TimeFile%"

:: Validate the stored value is a number
set /a "test_val=last_s" 2>nul
if !test_val! equ 0 if "!last_s!" neq "0" (
echo [WARNING] Corrupted cooldown file. Resetting...
del "%TimeFile%" >nul 2>&1
goto :RunTask
)

set /a "diff=current_s - last_s"

:: Handle midnight crossing
if !diff! lss 0 set /a "diff+=86400"

if !diff! lss %CooldownSec% (
set /a "wait_needed=CooldownSec - diff"
echo [COOLDOWN] You must wait !wait_needed! more seconds before running again.
echo Use "%~nx0 --force" to override.
pause
exit /b 1
)
)

:RunTask
:: 3. Perform the actual task
echo [OK] Cooldown check passed. Running task...

:: === Your task logic goes here ===
echo Working...
timeout /t 5 /nobreak >nul
:: === End of task logic ===

set "TaskExitCode=!errorlevel!"

:: 4. Only save the timestamp if the task succeeded
if !TaskExitCode! equ 0 (
:: Recalculate current time (task may have taken a while)
set "t=!time: =0!"
set /a "current_s=(1!t:~0,2!-100)*3600 + (1!t:~3,2!-100)*60 + (1!t:~6,2!-100)"
echo !current_s! > "%TimeFile%"
echo [DONE] Task complete. Cooldown of %CooldownSec% seconds starts now.
) else (
echo [ERROR] Task failed. Cooldown NOT applied (retry is allowed^).
)

pause
endlocal
Why the math?

Batch cannot easily compare time strings like 12:30 PM. By converting everything to "Total Seconds since Midnight," we can treat time as a simple number that is easy to subtract and compare.

Method 2: Long Cooldown (Minutes/Hours via PowerShell)​

If your cooldown is several hours long, checking only the "Seconds since Midnight" will fail when the date changes. For multi-hour or multi-day cooldowns, use the file's Last Modified Date with PowerShell for accurate cross-day comparison.

@echo off
setlocal

set "CooldownMin=30"
set "TimerFile=%temp%\cooldown_%~n0.done"

:: Support a --force flag
if /i "%~1"=="--force" (
echo [INFO] Force flag detected. Bypassing cooldown.
goto :RunTask
)

if exist "%TimerFile%" (
:: Use PowerShell to check the age of the file in minutes
powershell -NoProfile -Command ^
"$age = ((Get-Date) - (Get-Item '%TimerFile%').LastWriteTime).TotalMinutes;" ^
"if ($age -lt %CooldownMin%) {" ^
" $remaining = [math]::Ceiling(%CooldownMin% - $age);" ^
" Write-Host ('[COOLDOWN] {0} minute(s) remaining. Please wait.' -f $remaining);" ^
" exit 1" ^
"} else { exit 0 }"

if errorlevel 1 (
echo Use "%~nx0 --force" to override.
pause
exit /b 1
)
)

:RunTask
echo [OK] Cooldown check passed. Running task...

:: === Your task logic goes here ===
echo Working...
timeout /t 5 /nobreak >nul
:: === End of task logic ===

:: Only update the timer file on success
if %errorlevel% equ 0 (
echo Done > "%TimerFile%"
echo [DONE] Task complete. Cooldown of %CooldownMin% minutes starts now.
) else (
echo [ERROR] Task failed. Cooldown NOT applied.
)

pause
endlocal

How to Avoid Common Errors​

Wrong Way: Using the current directory for timestamps​

If multiple users run the script from a shared network drive, they might all share the same cooldown file, meaning User A might block User B.

Correct Way: Use %localappdata% or %temp% so each user has their own private cooldown tracker. Include the script name (%~n0) in the filename to prevent collisions between different scripts.

Problem: Clock Jumps​

If a user manually changes their system clock back 10 minutes, they can bypass your cooldown logic. While rare, it's something to keep in mind for security-critical scripts. Method 2's PowerShell approach is more resistant to this because it uses absolute timestamps rather than relative calculations.

Problem: Task failure should not trigger cooldown​

If the script fails after 1 second, the user should be able to retry immediately. Only apply the cooldown after a successful execution.

Best Practice: Update the timestamp file only after the main task completes successfully (as shown in both methods).

Best Practices and Rules​

1. Transparency​

Always tell the user why the script is refusing to run and exactly how long they need to wait. "Access Denied" is confusing; "Wait 45 seconds" is helpful. Show the override command for administrators.

2. Successful Completion Only​

Only update the timestamp if the script finishes successfully. If the script crashes, allow the user to try again immediately without waiting for a cooldown (as demonstrated in both methods).

3. Graceful Override​

Include a command-line flag like --force that allows an administrator to bypass the cooldown for urgent maintenance (as demonstrated in both methods).

Conclusions​

Implementing a cooldown period is a hallmark of "Polite" and stable automation. It prevents runaway loops and ensures that resources are used responsibly. By converting time into manageable numbers or utilizing the file-system's native timestamping, you can build a robust guard that protects your environment from excessive or accidental execution.