Skip to content

perf: perf improvements#124

Draft
pi0 wants to merge 9 commits intomainfrom
perf-improvements
Draft

perf: perf improvements#124
pi0 wants to merge 9 commits intomainfrom
perf-improvements

Conversation

@pi0
Copy link
Member

@pi0 pi0 commented Mar 25, 2026

  • Default keep-alive agents — shared http.Agent/https.Agent with keepAlive: true, 256 maxSockets for connection reuse in both ProxyServer and proxyFetch. Skipped for HTTP/2 incoming requests.
  • URL parse cacheparseURL() with 256-entry LRU avoids repeated new URL() for the same string targets.
  • Single-pass header mergesetupOutgoing merges req.headers + options.headers in one pass instead of two spreads.
  • proxyFetch optimizations — sync _toBuffer fast path, response headers from rawHeaders pairs instead of Headers object, plain-object header fast path via Object.assign.
  • Benchmark suitebench/index.ts with validation + mitata benchmarks.

Results

Scenario httpxy server proxyFetch fast-proxy @fastify/http-proxy http-proxy-3
GET 51 µs 57 µs 44 µs 52 µs 170 µs
POST 1KB 45 µs 55 µs 48 µs 62 µs 166 µs
POST 100KB 177 µs 202 µs 170 µs 175 µs 304 µs
$ node bench/index.ts

clk: ~5.36 GHz
cpu: AMD Ryzen 9 9950X3D 16-Core Processor
runtime: node 24.13.0 (x64-linux)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
• GET proxy (no body)
------------------------------------------- -------------------------------
httpxy server                 50.29 µs/iter  49.73 µs 111.42 µs █▄▂▂▁▁▁▁▁▁▁
httpxy proxyFetch             54.97 µs/iter  53.35 µs 113.58 µs ▃█▂▁▁▁▁▁▁▁▁
fast-proxy                    43.72 µs/iter  43.46 µs  57.29 µs ▁█▅▂▁▁▁▁▁▁▁
@fastify/http-proxy           48.95 µs/iter  47.22 µs 124.89 µs ▄█▁▁▁▁▁▁▁▁▁
http-proxy-3                 161.62 µs/iter 166.14 µs 257.57 µs ▄█▃▃▂▁▁▁▁▁▁

summary
  fast-proxy
   1.12x faster than @fastify/http-proxy
   1.15x faster than httpxy server
   1.26x faster than httpxy proxyFetch
   3.7x faster than http-proxy-3

• POST proxy (~1KB JSON body)
------------------------------------------- -------------------------------
httpxy server                 43.97 µs/iter  44.00 µs  57.18 µs ▁█▄▂▁▁▁▁▁▁▁
httpxy proxyFetch             53.85 µs/iter  53.58 µs  79.40 µs ▂█▂▂▁▁▁▁▁▁▁
fast-proxy                    46.94 µs/iter  46.68 µs  61.16 µs ▁█▄▂▁▁▁▁▁▁▁
@fastify/http-proxy           57.48 µs/iter  53.76 µs 105.81 µs ▂█▂▁▁▁▁▁▁▁▁
http-proxy-3                 151.28 µs/iter 153.39 µs 208.45 µs ▂█▄▂▂▁▁▁▁▁▁

summary
  httpxy server
   1.07x faster than fast-proxy
   1.22x faster than httpxy proxyFetch
   1.31x faster than @fastify/http-proxy
   3.44x faster than http-proxy-3

• POST proxy (~100KB JSON body)
------------------------------------------- -------------------------------
httpxy server                166.09 µs/iter 139.44 µs 644.48 µs █▁▁▁▁▁▁▁▁▁▁
httpxy proxyFetch            190.45 µs/iter 156.86 µs   1.05 ms █▁▁▁▁▁▁▁▁▁▁
fast-proxy                   175.72 µs/iter 144.02 µs 788.01 µs █▂▁▁▁▁▁▁▁▁▁
@fastify/http-proxy          175.44 µs/iter 145.64 µs 820.95 µs █▂▁▁▁▁▁▁▁▁▁
http-proxy-3                 303.09 µs/iter 271.24 µs 997.53 µs █▂▁▁▁▁▁▁▁▁▁

summary
  httpxy server
   1.06x faster than @fastify/http-proxy
   1.06x faster than fast-proxy
   1.15x faster than httpxy proxyFetch
   1.82x faster than http-proxy-3

Before → After

httpxy server proxyFetch
GET 203 µs → 51 µs (4x) 175 µs → 57 µs (3x)
POST 1KB 149 µs → 45 µs (3.3x) 165 µs → 55 µs (3x)
POST 100KB 307 µs → 177 µs (1.7x) 352 µs → 202 µs (1.7x)

Acknowledgements

Performance optimizations were inspired by analysis of fast-proxy and @fastify/http-proxy.

pi0 and others added 3 commits March 25, 2026 22:48
mitata-based benchmarks for httpxy server, proxyFetch, fast-proxy,
@fastify/http-proxy, and http-proxy-3 with pre-bench validation.
1. Default keep-alive agents (http/https) with 256 maxSockets for
   connection reuse — skipped for HTTP/2 incoming requests.
2. LRU URL parse cache (256 entries) avoids repeated `new URL()` for
   the same string targets in server.ts, fetch.ts, and parseAddr.
3. Single header copy in `setupOutgoing` — merge req.headers and
   options.headers in one pass instead of two spread operations.

httpxy server is now on par with fast-proxy (~50µs/req vs ~43µs GET).
@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4fc6ebc2-82fa-468e-ba4b-e9a389012b29

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf-improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 81.57895% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.87%. Comparing base (1de0a6c) to head (df70dd3).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/fetch.ts 74.46% 9 Missing and 3 partials ⚠️
src/_utils.ts 92.85% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #124      +/-   ##
==========================================
- Coverage   95.74%   94.87%   -0.87%     
==========================================
  Files           8        8              
  Lines         752      800      +48     
  Branches      303      326      +23     
==========================================
+ Hits          720      759      +39     
- Misses         30       38       +8     
- Partials        2        3       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Default keep-alive agents (http/https) for connection reuse in proxyFetch
- Sync _toBuffer fast path avoids async overhead for string/ArrayBuffer bodies
- Response headers built from rawHeaders array pairs instead of Headers object
- Request headers: fast path for plain object (Object.assign) skipping Headers API

proxyFetch: ~170µs -> ~57µs GET, ~165µs -> ~55µs POST 1KB (3x faster)
@pi0 pi0 changed the title perf: connection pooling, URL cache, single header copy perf: perf improvements Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant