Skip to the content

Performance

The mean time of six benchmarks, with plain JavaScript, the transform only, and the library.

The benchmarks

The command pnpm bench starts each case in a separate Node.js process. Each process measures each benchmark with tinybench. A value is the mean time of one operation of the benchmark. The command does 5 rounds, with a different order of the cases in each round, and a value is the median of the rounds. The rounds decrease the effect of other work on the machine.

BenchmarkWhat it does
await loopOne async function with 10,000 await steps.
async calls10,000 async functions in sequence, each with one await.
then chainA chain of 10,000 then callbacks.
concurrent tasks1,000 async functions at the same time, each with 10 await steps, in one context.
request handlers1,000 request handlers, each in its own context, with three await steps and one read of the context.
get in nested contexts100,000 reads with get(), 5 contexts deep.

The cases

CaseWhat it measures
Plain JavaScriptThe same code without the library. A Variable class without propagation gives the same API.
Transform onlyThe Babel preset with a plain coroutine. This case shows the cost of the transform without the cost of the context.
LibraryThe Babel preset and the browser runtime.

The tools wrote this data at 8 Oct 2026, 22:10 UTC.

Node.js v25.2.1, Windows_NT 10.0.26200, AMD Ryzen AI 7 PRO 350 w/ Radeon 860M.

The mean time of each benchmark

Plain JavaScriptTransform onlyLibrary
await loopasync callsthen chainconcurrent tasksrequest handlersget in nested contexts0.00.20.40.60.81.01.2Mean time (ms) →1×1.22×1.56×1×1.61×1.99×1×1.04×1.77×1×1.24×1.75×1×1.3×1.9×1×1×3.74×
Show the data as a table
BenchmarkCaseMean timeFactor
await loopPlain JavaScript0.26 ms1×
await loopTransform only0.31 ms1.22×
await loopLibrary0.4 ms1.56×
async callsPlain JavaScript0.61 ms1×
async callsTransform only0.99 ms1.61×
async callsLibrary1.2 ms1.99×
then chainPlain JavaScript0.19 ms1×
then chainTransform only0.19 ms1.04×
then chainLibrary0.33 ms1.77×
concurrent tasksPlain JavaScript0.39 ms1×
concurrent tasksTransform only0.49 ms1.24×
concurrent tasksLibrary0.68 ms1.75×
request handlersPlain JavaScript0.31 ms1×
request handlersTransform only0.41 ms1.3×
request handlersLibrary0.6 ms1.9×
get in nested contextsPlain JavaScript0.1 ms1×
get in nested contextsTransform only0.11 ms1×
get in nested contextsLibrary0.39 ms3.74×

What the results tell

  • The transform. Each async function of transformed code is a generator that the coroutine operates. This costs more than a native async function. The number of microtask steps of each await does not change.
  • The context. Each then callback and each step of the coroutine sets the context and sets it again after the step. Each then call makes two small wrappers.
  • get(). One read takes approximately 4 ns. The plain case reads one field, so the factor is large, but the time is small.

Note

The values are microbenchmarks. The benchmarks do no other work, so the factors are the largest possible factors. Measure your own application before and after you add the library.

To change this page, edit site/content/testing/performance.mdx.

async-browser-context: AsyncLocalStorage and the TC39 AsyncContext API for browsers. The source code is on GitHub.

To change a page, edit its file in site/content/. The writing style guide tells you how.

An AI model (Claude, from Anthropic) wrote most of the text and the code of this site and of the library, under the direction of the author. The tests and the STE linter examine them.