JavaScript Microtask Queue: Definition and Flush Timing

The JavaScript microtask queue is a high-priority queue within the event loop designed to handle short, asynchronous tasks that must execute immediately after the currently running script finishes. Unlike standard macrotasks (such as setTimeout or I/O events), microtasks guarantee execution before the browser performs any rendering updates or proceeds to the next macrotask. This article explains what the microtask queue is, the common APIs that use it, and the exact rules governing when and how it is flushed.

What Is the Microtask Queue?

The microtask queue is an internal First-In, First-Out (FIFO) data structure managed by the JavaScript runtime environment (like V8 in Node.js and Chromium browsers). It holds callback functions that are deferred but need to run before control is returned to the event loop’s main cycle.

Common sources that enqueue microtasks include:

When Does the Microtask Queue Flush?

The microtask queue flushes whenever the JavaScript call stack becomes completely empty (i.e., when the currently running synchronous execution context finishes).

Specifically, the flush occurs:

  1. After the completion of a synchronous script block: As soon as the global or top-level execution context finishes, all pending microtasks are immediately processed.
  2. After every macrotask callback: When a standard task (such as a DOM event listener, setTimeout, or setInterval callback) finishes and its execution frame is popped off the call stack, the microtask queue is flushed immediately.
  3. Before UI rendering: In web browsers, the microtask queue is completely drained before the browser recalculates styles, executes layout, and repaints the screen.
  4. Before picking the next macrotask: The event loop will never move to the next item in the macrotask queue until the microtask queue has reached a count of zero.

How the Flushing Process Works

When the runtime begins draining the microtask queue, it processes tasks continuously until the queue is completely empty.

If a running microtask enqueues another microtask, that newly scheduled microtask is appended to the current queue and will execute within the same flush cycle. Consequently, an infinite or recursive chain of microtasks will starve the event loop, preventing the UI from updating and blocking all subsequent macrotasks from executing.

Event Loop Execution Order

To understand the flush timing in context, the event loop processes tasks in the following strict order:

  1. Execute synchronous code on the call stack until it is empty.
  2. Flush the microtask queue: Run all queued microtasks sequentially until none remain.
  3. Perform rendering and painting steps (if required by the browser).
  4. Pick the next macrotask from the task queue.
  5. Repeat from Step 1.