Execute specified function every X seconds
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Running a function at regular intervals is a common requirement for monitoring, polling, cleanup tasks, and heartbeat mechanisms. In Python, the main approaches are time.sleep() in a loop (simplest), threading.Timer (non-blocking), sched module (event scheduler), and third-party libraries like schedule and APScheduler (feature-rich). In JavaScript, use setInterval(). Each approach has different tradeoffs in precision, blocking behavior, and error handling. This article covers the idiomatic solution for each language and use case.
Python: time.sleep() Loop
The simplest approach — runs the function in the current thread:
This blocks the thread, so nothing else can run. The actual interval is execution_time + 5 seconds, not exactly 5 seconds.
Drift-Corrected Loop
Python: threading.Timer (Non-Blocking)
Python: schedule Library
The schedule library provides a human-readable API:
Install with pip install schedule.
With Arguments
Python: asyncio (Async)
JavaScript: setInterval()
With Async/Await
Python: APScheduler (Production-Ready)
Install with pip install apscheduler.
Comparison
| Approach | Language | Blocking? | Error Handling | Precision |
time.sleep loop | Python | Yes | Manual try/except | Drifts with execution time |
threading.Timer | Python | No | Manual | Moderate |
schedule | Python | Yes (event loop) | Manual | Second-level |
asyncio.sleep | Python | No (async) | try/except in coroutine | Moderate |
| APScheduler | Python | No (background) | Built-in retry/logging | High |
setInterval | JavaScript | No | Uncaught → console | Millisecond |
Common Pitfalls
- Not handling exceptions in the scheduled function: If the function throws an exception in a
time.sleeploop, the entire loop stops. Wrap the function call in try/except to ensure the loop continues:try: func() except Exception as e: log(e). - Accumulating drift with
time.sleep(interval): The actual interval becomesexecution_time + sleep_time. For precise intervals, compute the next run time and sleep only the remaining duration usingtime.monotonic(). - Using
setIntervalfor async operations in JavaScript:setIntervaldoes not wait for async functions to complete. If the function takes longer than the interval, multiple executions overlap. Use recursivesetTimeoutwithawaitinstead. - Forgetting to make timer threads daemon threads: Non-daemon timer threads prevent the Python process from exiting. Set
timer.daemon = Trueor calltimer.cancel()during shutdown to allow clean process termination. - Using
schedulelibrary without callingrun_pending()in a loop:schedule.every(10).seconds.do(job)only registers the job — it does not execute it. You must callschedule.run_pending()repeatedly in a loop for jobs to actually run.
Summary
- Use
time.sleep()in a loop for simple, blocking periodic tasks - Use
threading.Timeror theschedulelibrary for non-blocking background execution - Use
asyncio.sleep()for async applications with multiple concurrent periodic tasks - Use APScheduler for production systems that need cron scheduling, persistence, and error handling
- In JavaScript, prefer recursive
setTimeoutoversetIntervalfor async operations to prevent overlapping executions

