ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 80

  1. Blog

nock vs msw: Should You Switch? 2.9ms vs 0.5ms

nock 14.0.17 vs msw 2.15.0 on 2,000 sequential mocked fetch calls in Node 20: 2.85 ms vs 0.49 ms per request (~5.8x); via axios 3.80 ms vs 1.41 ms (~2.7x). nock sets up faster (97 vs 208 ms), crossover near 50 requests per process.

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is msw faster than nock?
  3. Why is axios slower under both?
  4. Should you switch from nock to msw?
  5. Sources
  6. Related

I mocked the same 2,000 sequential fetch calls in Node 20 with nock 14.0.17 and msw 2.15.0: nock took a median 2.85 ms per request, msw took 0.49 ms (about 5.8x faster). Through axios, which goes through Node's http module instead of fetch, the gap shrank to 3.80 ms versus 1.41 ms per request (about 2.7x).

Short answer: switch to msw if your Node tests mock hundreds of fetch calls, or if you want the same handlers in the browser. Stay on nock if your suite is small, leans on nock-only features like scope.done() and recorder mode, and runs fast enough today. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, Node 20.19.2, tested 5 Oct 2026 (about 23:38 to 23:43 IST). Shared box; each run in a fresh Node process, one warmup per variant, then seven interleaved rounds.
  • Fixture: /workspace/bench-msw-nock/run.mjs. One mocked endpoint GET https://api.example.test/users/:id returning a small JSON object. After one check request, the script awaits 2,000 requests in a row and checks each response id. All 2,000 came back correct in every run.
  • Tools: msw 2.15.0 (setupServer, onUnhandledRequest: 'error'), nock 14.0.17 (persist(), regex path, disableNetConnect()), axios 1.20.0. Baseline: a real node:http server on 127.0.0.1 with no mocking library.
  • Timing: performance.now() around the 2,000-request loop, plus a separate number for import + setup + first request, plus the full process wall clock.
  • Findings: loop medians were msw fetch 987 ms, nock fetch 5,710 ms, real loopback fetch 955 ms; msw axios 2,813 ms, nock axios 7,594 ms, real loopback axios 1,031 ms. Setup plus first request: nock 97 ms, msw 208 ms (fetch).
  • One surprise: both libraries depend on @mswjs/interceptors 0.41, yet nock was still 5.8x slower on fetch. A static reply object instead of a reply function did not change it (5.67 to 5.73 s across three runs).
  • Not tested: msw 3.x (3.0.2 needs Node 22.12 or newer, so it would not run here), browser or service worker mode, Vitest or Jest wiring, concurrent requests, GraphQL handlers, nock recorder, Windows/macOS.

Is msw faster than nock?

VariantMedian per requestLoop for 2,000Setup + first request
msw 2.15 + fetch0.49 ms987 ms208 ms
nock 14 + fetch2.85 ms5,710 ms97 ms
msw 2.15 + axios1.41 ms2,813 ms306 ms
nock 14 + axios3.80 ms7,594 ms187 ms
real loopback server + fetch0.48 ms955 ms80 ms
real loopback server + axios0.52 ms1,031 ms165 ms

On this fixture, yes, per request. msw on fetch was about as fast as hitting a real server on loopback. nock loads faster, so a process that makes only ten requests finishes first under nock: about 126 ms (97 + 29) versus 213 ms (208 + 5). The crossover in my numbers is around 50 requests per process. A suite that mocks 500 fetch calls would spend about 1.4 s in nock versus 0.25 s in msw.

If you are also choosing the test runner, see the Jest vs Vitest post and the jsdom vs happy-dom for Vitest post.

Why is axios slower under both?

Axios in Node uses the http module, not fetch. Both libraries intercept that path by patching http.ClientRequest, and that layer cost more than fetch interception in my runs: msw went from 0.49 to 1.41 ms per request, nock from 2.85 to 3.80 ms. Without mocking, axios over loopback was 0.52 ms, so most of that extra time came from interception, not from axios. If your code calls an http-based client, expect a smaller gap between the two libraries than the fetch numbers suggest.

Should you switch from nock to msw?

SituationMy pick
Node tests with hundreds of mocked fetch callsmsw
Same request mocks wanted in browser dev and in testsmsw
Small suite, under about 50 mocked requests per test fileStay on nock; the gap is noise
You rely on scope.done() assertions or nock's recorderStay on nock, or plan to rebuild those checks
Already on Node 22.12+ and starting freshmsw 3.x is an option, but I did not test it here

Bottom line: 2,000 fetch calls took 0.99 s with msw and 5.71 s with nock on the same box. Who should not switch yet: teams with a large nock suite built on persist() chains and isDone() checks, where rewriting every mock costs more than the seconds you would save. For related test-speed choices, see the Vitest 5 upgrade post and the c8 vs nyc coverage post; for running TypeScript tests directly, the tsx vs ts-node post.

How this was made: I wrote the fixture, installed both libraries on the ShopperCove test box, timed interleaved runs in fresh processes and kept the JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • https://mswjs.io/docs/
  • https://www.npmjs.com/package/msw
  • https://github.com/mswjs/msw
  • https://github.com/nock/nock
  • https://www.npmjs.com/package/nock
  • https://github.com/mswjs/interceptors

Related

  • https://www.shoppercove.com/blog/jest-vs-vitest
  • https://www.shoppercove.com/blog/jsdom-vs-happy-dom-vitest
  • https://www.shoppercove.com/blog/vitest-5-should-you-upgrade-october-2026
  • https://www.shoppercove.com/blog/c8-vs-nyc
  • https://www.shoppercove.com/blog/tsx-vs-ts-node
  • https://www.shoppercove.com/blog/playwright-1-63-test-locks-october-2026
  • https://www.shoppercove.com/blog/nodejs-26-lts-october-2026-schedule-change
  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
nockmswnodejsbenchmarkinghttp-mockingfetchaxiostesting

Lab evidence

What I found running this

Hands-on on ShopperCove box 5 Oct 2026 ~23:38-23:43 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: run.mjs, GET https://api.example.test/users/:id JSON, 1 check request then 2000 sequential awaited requests, ids verified (2000/2000 every run). msw 2.15.0 setupServer onUnhandledRequest error; nock 14.0.17 persist + regex + disableNetConnect; axios 1.20.0; baseline node:http server on 127.0.0.1. Fresh process per run, 1 warmup, 7 interleaved rounds. Loop medians: msw fetch 987.1 ms (0.49 ms/req), nock fetch 5709.6 ms (2.85 ms/req), real fetch 955.3 ms; msw axios 2813.1 ms (1.41 ms/req), nock axios 7594.1 ms (3.80 ms/req), real axios 1031.1 ms. Setup+first request: msw fetch 207.8 ms, nock fetch 96.5 ms, msw axios 306.4, nock axios 187.3. nock static reply: 5671/5726/5689 ms (no change). Both use @mswjs/interceptors 0.41. msw 3.0.2 needs Node >=22.12 (not run). Raw: /workspace/bench-msw-nock/res-msw-nock.json. Not tested: browser/service worker, Vitest/Jest wiring, concurrency, GraphQL, recorder, Windows/macOS. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 44

    Playwright vs Cypress: 1.47s vs 4.24s Smoke

    Playwright 1.55.1 Chromium vs Cypress 14.5.4 Electron on one local smoke (visit /, assert h1, click, assert). Warm medians (7 rounds after 1 warm-up): Playwright 1,466 ms vs Cypress 4,243 ms (~2.9x). Disk: PW node_modules ~12 MB + cache ~918 MB; Cypress node_modules ~23 MB + cache ~601 MB. Fixture /workspace/bench-pw-cy/.

    5 Oct 2026

  • Plate 12

    Yarn Berry vs pnpm: 1.3s vs 0.24s Install

    Yarn 4.9.2 (Berry PnP + node-modules linker) vs pnpm 12.9.1 on one 22-dependency React+Vite app. Isolated caches (Yarn enableGlobalCache false; pnpm --store-dir). Warm medians (5): Yarn PnP 1.307 s, Yarn nm 2.471 s, pnpm 0.240 s. Lock+empty medians 1.656 / 2.789 / 0.725 s. Clean disk: Yarn PnP 246 MB; Yarn nm modules 189 MB; pnpm hardlink project 167 MB. Fixture /workspace/bench-yarn-pnpm/. Distinct from pnpm-vs-npm-vs-bun (no Yarn).

    5 Oct 2026

  • Plate 48

    Zod vs Valibot: 1.14M vs 0.97M Parses

    zod 4.6.5 vs valibot 1.5.0 on one nested user schema (uuid/email/age/tags/profile/enum). Warm medians after 2k warmup + 9×50k: zod.parse 1,144,494 ops/s vs valibot.parse 968,187 (~1.18×). safeParse fail: valibot 697,760 vs zod 415,523 (~1.7×). esbuild minify+gzip9: 452,999/92,636 B vs 85,126/15,422 B. Package trees ~6.1 MB vs ~1.9 MB. Fixture /workspace/bench-zod-valibot/.

    5 Oct 2026

On this page

  1. What I tested
  2. Is msw faster than nock?
  3. Why is axios slower under both?
  4. Should you switch from nock to msw?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove