Working with Timers

1. Using setTimeout for Delays

FormNotes
setTimeout(fn, ms, ...args)Returns Timeout
timeout.unref()Don't keep loop alive
timeout.ref()Reverse
timeout.refresh()Restart

2. Using setInterval for Repetition

Example

const id = setInterval(() => checkHealth(), 30_000);
process.on("SIGTERM", () => clearInterval(id));

3. Using setImmediate for Next Cycle

Use CaseWhy
Yield to I/ORun after current poll phase
Avoid nextTick starvationSpreads work across ticks

4. Using process.nextTick for Microtasks

OrderDetail
Highest priorityDrained before microtasks/macrotasks
Use forDefer logic to "after current op completes"

5. Clearing Timeouts (clearTimeout)

Example

const t = setTimeout(work, 1000);
clearTimeout(t);

6. Clearing Intervals (clearInterval)

APIUse
clearInterval(id)Stop repeating timer

7. Clearing Immediate (clearImmediate)

APIUse
clearImmediate(id)Cancel scheduled setImmediate

8. Understanding Timer Order

Same delayTie break
setTimeout(fn, 0)Min 1ms; runs in timers phase
setImmediateAlways runs in check phase
From within I/O cbsetImmediate runs first

9. Using Timers/Promises

Example: Promise-based timers v15+

import { setTimeout, setInterval } from "node:timers/promises";
await setTimeout(1000);                 // sleep 1s
for await (const _ of setInterval(500)) // tick every 500ms
  console.log("tick");

10. Handling Timer Drift

IssueMitigation
Event loop blocking delays callbacksUse absolute timestamps + adjust
Long intervals accumulate driftReschedule using Date.now()
OS sleep affects timersDetect via wall-clock check

11. Scheduling Delayed Tasks

ToolUse
node-cron / cronCron-style schedules
node-scheduleOne-shot + recurring
BullMQ / AgendaPersistent job queues