Skip to content

What Goes Where

Understanding which operations create microtasks vs macrotasks helps you predict execution order.

flowchart LR
subgraph "High Priority ⚡"
Micro["Microtask Queue"]
M1["Promise.then"]
M2["queueMicrotask()"]
M3["MutationObserver"]
end
subgraph "Lower Priority ⏳"
Macro["Macrotask Queue"]
T1["setTimeout"]
T2["setInterval"]
T3["I/O Events"]
T4["UI Rendering"]
end
APIExample
Promise handlers.then(), .catch(), .finally()
queueMicrotask()queueMicrotask(() => {})
MutationObserverDOM mutation callbacks
process.nextTick()Node.js only
APIExample
setTimeoutsetTimeout(() => {}, 0)
setIntervalsetInterval(() => {}, 1000)
I/O operationsNetwork requests, file system
UI renderingPaint, layout
Event handlersClick, scroll, keypress

Microtasks run right after the current synchronous code, before the next macrotask. This means:

setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
// Output: promise, timeout
  • Microtasks: Promise callbacks, queueMicrotask, MutationObserver
  • Macrotasks: setTimeout, setInterval, I/O, rendering
  • Microtasks always run before macrotasks
  • Each event loop cycle processes all microtasks then one macrotask