0Pricing
JavaScript Academy · Lesson

Macrotasks and the Task Queue

Understand how timers and I/O are scheduled.

Macrotasks and the Task Queue is a free JavaScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the JavaScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is a Macrotask?

A macrotask (also called a task) is a unit of work scheduled to run later, after the current synchronous code finishes. setTimeout callbacks are the classic example.

Macrotasks wait in the task queue until the call stack is empty.

setTimeout Defers Work

setTimeout registers a callback to run later. Even with a delay of 0, it runs after all current synchronous code.

console.log('first');
setTimeout(() => console.log('third (timeout)'), 0);
console.log('second');

The Task Queue

When a timer fires, its callback is placed in the task queue. The event loop takes one task from this queue only when the call stack is empty, runs it to completion, then checks again.

console.log('sync start');
setTimeout(() => console.log('task 1'), 0);
setTimeout(() => console.log('task 2'), 0);
console.log('sync end');

Tasks Run In Order Queued

Tasks with the same delay run in the order they were scheduled. The task queue is FIFO: First In, First Out.

setTimeout(() => console.log('A'), 0);
setTimeout(() => console.log('B'), 0);
setTimeout(() => console.log('C'), 0);
console.log('sync');

Delay Is a Minimum, Not Exact

The delay you pass is the minimum time before the callback is eligible to run. The actual run happens only once the stack clears and earlier tasks finish, so it may be later.

setTimeout(() => console.log('100ms'), 100);
setTimeout(() => console.log('0ms'), 0);
console.log('synchronous runs first');

Sorting By Delay

Different delays change ordering: shorter delays become eligible sooner, so they generally run before longer ones, regardless of scheduling order.

setTimeout(() => console.log('50'), 50);
setTimeout(() => console.log('10'), 10);
setTimeout(() => console.log('30'), 30);
console.log('start');

One Task Per Loop Turn

The event loop runs exactly one macrotask per turn, then performs other work before the next. This keeps the system responsive between tasks.

console.log('1');
setTimeout(() => {
  console.log('2');
  setTimeout(() => console.log('4'), 0);
}, 0);
setTimeout(() => console.log('3'), 0);

Nested Timers Queue Later

A timer scheduled inside a task joins the queue behind tasks that are already waiting, so it runs in a later loop turn.

setTimeout(() => {
  console.log('outer');
  setTimeout(() => console.log('inner nested'), 0);
}, 0);
setTimeout(() => console.log('sibling'), 0);

setInterval Is Also Macrotasks

setInterval schedules a repeating macrotask. Here we run a few iterations and stop with clearInterval to keep the output bounded.

let count = 0;
const id = setInterval(() => {
  count++;
  console.log('tick ' + count);
  if (count === 3) clearInterval(id);
}, 10);
console.log('interval scheduled');

Synchronous Always Wins

No matter how small the delay, every macrotask waits behind all synchronous code in the current run. The stack must empty first.

setTimeout(() => console.log('macrotask'), 0);
for (let i = 1; i <= 3; i++) console.log('sync ' + i);
console.log('done sync');

Why Macrotasks Matter

Macrotasks let you defer work without blocking. Breaking a heavy job into timed chunks keeps an app responsive. But macrotasks are not the highest priority: microtasks (Promises) run before the next macrotask, as you will see next.

console.log('schedule');
setTimeout(() => console.log('runs after sync'), 0);
console.log('still sync');

Quick Check

When does a setTimeout(cb, 0) callback run?

Recap: Macrotasks

You learned how deferred work is scheduled:

  • Macrotasks (setTimeout, setInterval) wait in the task queue.
  • The queue is FIFO; the event loop runs one task per turn.
  • Delay is a minimum, and synchronous code always runs first.
  • Microtasks have higher priority, which you will explore next.

Frequently asked questions

Is the “Macrotasks and the Task Queue” lesson free?

Yes — the full text of “Macrotasks and the Task Queue” is free to read here on the web, and the JavaScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the JavaScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Macrotasks and the Task Queue”?

Understand how timers and I/O are scheduled. You practise JavaScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start JavaScript Academy?

No prior experience is required. JavaScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Macrotasks and the Task Queue” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this JavaScript Academy lesson?

Yes. Every JavaScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The Call Stack
  2. Macrotasks and the Task Queue
  3. Microtasks and Promises
  4. queueMicrotask and Ordering
← Back to JavaScript Academy