Run certain code every n seconds
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Running code every n seconds sounds simple, but the right implementation depends on what "every n seconds" actually means. Do you want fixed-delay repetition, fixed-rate scheduling, UI-safe callbacks, or background work that survives restarts? Those are different problems.
A good timer loop also needs cancellation and error handling. Without those, a periodic task may drift, overlap, or keep running after the rest of the application is trying to shut down.
Understand Fixed Delay Versus Fixed Rate
There are two common timing behaviors.
Fixed delay means the program waits n seconds after one run finishes before starting the next run. The runtime of the task is part of the interval.
Fixed rate means the task aims for a clock-based schedule such as once every 5 seconds regardless of how long the last run took. If the task runs too slowly, executions may bunch up or fall behind.
For many applications, fixed delay is the safer default because it avoids overlapping executions.
A Simple Python Loop
For small scripts, a while True loop with time.sleep is often enough:
This is simple and readable. It behaves like a fixed-delay loop because the sleep happens after the work.
The downside is that this design is single-threaded and blocks the current flow. That is fine in a script but not ideal inside servers or GUI programs.
Add Stop Control and Error Handling
A better pattern wraps the loop so it can stop cleanly:
This keeps the loop responsive to shutdown and makes failures visible instead of silently killing the scheduler thread.
Use Async Scheduling in Async Programs
If the rest of the application already uses asyncio, keep the timer async too:
This avoids blocking the event loop and plays nicely with other asynchronous tasks.
For more precise control, you can measure time explicitly and schedule against the clock rather than sleeping blindly after each iteration.
Browser and UI Example With JavaScript
In browser or Node.js code, setInterval is the obvious starting point:
This is convenient, but it can become problematic if the task sometimes takes longer than the interval. In that case, a recursive setTimeout often behaves more predictably because it naturally creates fixed-delay scheduling.
Avoid Overlapping Work
One of the biggest design mistakes is allowing a periodic task to start again before the previous run finished. A simple guard prevents accidental overlap:
If your interval is shorter than the task duration, you need to decide whether to skip runs, queue them, or run them concurrently. That is a product decision, not only a coding detail.
Common Pitfalls
The biggest mistake is assuming "every n seconds" has one universal implementation. The right answer depends on whether the environment is synchronous, asynchronous, UI-bound, or server-side.
Another common issue is ignoring cancellation. A timer without a stop path tends to become a shutdown bug later.
People also forget about task duration. If the work takes longer than the interval, naïve scheduling can overlap executions and create subtle state corruption.
Finally, do not use a sleep loop where a real scheduler or job system is required. Long-lived production scheduling often deserves infrastructure beyond an in-process timer.
Summary
- Decide first whether you need fixed-delay or fixed-rate behavior.
- A simple sleep loop is fine for small scripts but not for every environment.
- Add cancellation and error handling to any real periodic task.
- Keep the scheduling model aligned with the runtime, such as
asynciofor async Python orsetIntervalin JavaScript. - Prevent overlapping runs unless concurrency is intentionally part of the design.

