intermediate

Timers

Use setTimeout, setInterval, setImmediate, timer promises, ref/unref, cancellation, and scheduling limits deliberately.

Node timers schedule callbacks on the event loop — they are not real-time guarantees.

| API | Phase / behavior | |-----|------------------| | `setTimeout` | timers phase; minimum delay, not exact | | `setInterval` | repeats; can overlap if callback slower than interval | | `setImmediate` | check phase; after I/O in same turn | | `timers.promises.setTimeout` | Promise-based; integrates with async/await |

`timeout.unref()` lets the process exit if only that timer remains — useful for background housekeeping. `ref()` keeps the event loop alive.

					const t = setInterval(() => work(), 100);
// clear on shutdown
function shutdown() {
  clearInterval(t);
}
				

Timer drift accumulates under load: a 100 ms interval does not mean 10 calls per second if `work()` takes 80 ms.

On interviews: contrast `setTimeout(0)` vs `setImmediate`, explain `unref` for graceful exit, and why `setInterval` is risky for precise scheduling.

Common pitfalls: orphaned timers preventing shutdown; recursive `setTimeout` vs `setInterval` for backoff; forgetting `clearTimeout` on hot paths.

The trade-off is balancing simplicity, performance, safety, and operability — name which axis you optimized and what cost you accepted.

Checklist:

  • Map each timer API to event-loop phase.
  • Clear timers on shutdown and test teardown.
  • Use `unref` only when exit semantics are intentional.
  • Prefer scheduled queues for heavy periodic work.