DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. Macrotasks vs Microtasks: Understanding JavaScript's Execution Order
XLinkedInReddit
MediumFrontend Engineering

Macrotasks vs Microtasks: Understanding JavaScript's Execution Order

D
DevPrep Team
February 9, 2026·2 min read·0
Table of Contents
  • Why This Matters
  • The Event Loop — Simplified
  • What Goes Where?
  • Macrotasks
  • Microtasks
  • The Classic Interview Question
  • The Dangerous Part: Microtask Queue Draining
  • Real Production Example
  • async/await and Microtasks
  • Best Practices
  • Summary

By Rahul — Google Frontend Engineer

Why This Matters

If you do not understand microtasks and macrotasks, you cannot predict when your code runs. This leads to race conditions, UI freezes, and bugs that only appear under load.

The Event Loop — Simplified

The browser event loop follows this cycle:

  1. Pick ONE macrotask from the queue (or wait for one)
  2. Execute it completely
  3. Execute ALL microtasks in the microtask queue (including any new ones added during this step)
  4. Render (if needed — approximately every 16ms)
  5. Go to step 1

What Goes Where?

Macrotasks

  • setTimeout / setInterval
  • setImmediate (Node.js only)
  • I/O operations
  • UI rendering events
  • MessageChannel
  • requestAnimationFrame (technically before render, but after microtasks)

Microtasks

  • Promise.then/catch/finally
  • queueMicrotask()
  • MutationObserver
  • async/await (the code after await)

The Classic Interview Question

console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve().then(() => console.log('3'));

queueMicrotask(() => console.log('4'));

console.log('5');

// Output: 1, 5, 3, 4, 2
// Synchronous first (1, 5)
// Then ALL microtasks (3, 4)
// Then macrotask (2)

The Dangerous Part: Microtask Queue Draining

// This will FREEZE the browser
function freezeForever() {
  Promise.resolve().then(freezeForever);
}
freezeForever();
// Microtasks keep adding microtasks
// The queue NEVER empties
// The browser NEVER gets to render

Compare with setTimeout:

// This will NOT freeze — each call is a new macrotask
function safeRecursion() {
  setTimeout(safeRecursion, 0);
  // Browser renders between each call
}

Real Production Example

// Updating DOM then reading layout
element.style.height = '100px';
// BAD: Reading layout in microtask — may not reflect the change
Promise.resolve().then(() => {
  console.log(element.offsetHeight); // Might be old value
});

// GOOD: Use requestAnimationFrame for layout reads after changes
element.style.height = '100px';
requestAnimationFrame(() => {
  console.log(element.offsetHeight); // After render, correct value
});

async/await and Microtasks

async function foo() {
  console.log('A');
  await Promise.resolve();
  console.log('B'); // This runs as a microtask
}

console.log('C');
foo();
console.log('D');

// Output: C, A, D, B
// 'B' is a microtask — runs after all sync code

Best Practices

  • Use queueMicrotask() when you need something to run after current code but before rendering
  • Use setTimeout(fn, 0) when you need to yield to the browser for rendering
  • Never create infinite microtask loops
  • Use requestAnimationFrame for visual updates

Summary

Microtasks run after the current task but before rendering. Macrotasks run one at a time with rendering between them. Understanding this determines whether your UI stays responsive.

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • Why This Matters
  • The Event Loop — Simplified
  • What Goes Where?
  • Macrotasks
  • Microtasks
  • The Classic Interview Question
  • The Dangerous Part: Microtask Queue Draining
  • Real Production Example
  • async/await and Microtasks
  • Best Practices
  • Summary

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.