The Runtime Theory
RuntimeInternalsconcurrency

Trace a Node.js async Function Resuming

Follow synchronous JavaScript, a pending promise, an I/O completion, and the queued continuation without treating await as a new thread.

The Runtime Theory Team1 min read04 steps

layer stack

Runtime

HWHardware
KKernel
RTRuntime
APPApplication
SYSSystem
CLIClient
NETNetwork
TLSCrypto
SRVServer

adjacent altitudes in this subsystem are still being traced

trace spine

  1. 01 Run JavaScript until the awaited promise is pending
  2. 02 Let the runtime or operating system progress the I/O
  3. 03 Settle the promise and enqueue its continuation
  4. 04 Run the continuation when JavaScript can make progress
▸ On this page

Consider const response = await fetch(url);. This trace describes the scheduling boundary, not every native networking implementation detail. The source code after await is a continuation that runs only after the awaited promise settles.

1. Execute the current JavaScript

The function runs synchronously until it reaches await. It evaluates fetch(url) and receives a promise. If the promise is still pending, the async function suspends and returns control to its caller; it does not block the JavaScript thread waiting at that line.

2. Progress the operation

The runtime initiates the operation through native bindings and platform facilities. Network progress may be handled by the operating system and runtime event mechanisms. Other work may use worker threads or a runtime worker pool; the path varies by API and platform.

3. Settle and schedule

When the operation produces a result or error, the promise is fulfilled or rejected. The async function's continuation becomes runnable according to the runtime's job-queue rules. The event loop cannot run that JavaScript while a long synchronous callback still occupies the thread.

4. Resume the function

The continuation runs later and receives the response or throws the rejection at the await point. This sequencing makes asynchronous code readable, but it does not parallelize CPU-heavy JavaScript. Move CPU-bound work to a worker or another process when parallel execution is needed, and account for message-copying and lifecycle costs.

Node.js documents the event loop and worker pool; use those runtime-specific rules rather than assuming every language schedules promises identically.

One dispatch a week

If tracing at this altitude interests you, subscribe. One technical explanation per week — no noise, no course spam.

One technical dispatch per week. No noise.

Not started

Sign in to save your learning progress.

Sign in to save