← Lessons

quiz vs the machine

Silver1120

Concurrency

The Event Loop Revisited Deeply

Macrotasks, microtasks, and the order they run.

5 min read · intro · beat Silver to climb

One thread, many phases

An event loop runs callbacks on a single thread by pulling work from queues in a strict order. Understanding that order explains surprising scheduling.

Two kinds of queues

  • The macrotask queue holds timers, input, and most callbacks.
  • The microtask queue holds settled promise reactions and similar urgent work.

After each macrotask the loop drains the entire microtask queue before picking the next macrotask. So a chain of resolved promises all runs before the next timer fires.

Starvation risk

Because microtasks run to exhaustion, a microtask that keeps scheduling more microtasks can starve macrotasks forever. The page or server appears frozen even though the thread is busy.

Practical ordering

Code after an await runs as a microtask, so it executes before a setTimeout of zero scheduled earlier in the same tick. Knowing this lets you reason about race free ordering on a single thread.

Key idea

The event loop runs one macrotask, then fully drains microtasks, then repeats, and microtasks always jump ahead of the next macrotask.

Check yourself

Answer to earn rating on the learn ladder.

1. When are microtasks drained relative to macrotasks?

2. Why can a microtask starve macrotasks?