Skip to content

perf(server): skip empty middleware work - #30

Merged
Upd4ting merged 1 commit into
mainfrom
perf/http-middleware-fast-paths
Aug 19, 2026
Merged

perf(server): skip empty middleware work#30
Upd4ting merged 1 commit into
mainfrom
perf/http-middleware-fast-paths

Conversation

@Upd4ting

@Upd4ting Upd4ting commented Aug 19, 2026

Copy link
Copy Markdown
Member

Summary

  • skip prefix/postfix route lookups and promise continuations when their registry is empty
  • skip monitor lookup, response snapshot, and promise continuation when no monitor can run
  • avoid sorting zero or one matching callback
  • keep fast-path state synchronized across registration, removal, duplicate IDs, and hot reload lifecycle calls

This PR intentionally does not change controller resolution or HTTPResult construction/serialization.

Rebase on #29

Rebased commit: e8d87505a5912cd06dec1a9839224d71f35050ac on 0c212790f29a241aeb750026caea7c09de553f4a (perf(api): compile controller resolution plans (#29)).

The rebase was conflict-free. The incremental diff still contains only:

  • src/server.ts
  • src/test/server-fast-paths.test.ts

git merge-base --is-ancestor 0c212790 HEAD succeeds, so #29 is preserved in full. The benchmark below measures new main including #29 against new main + #30; it does not reattribute #29's controller-resolution gains to this PR.

Incremental benchmark after rebase

Method

  • baseline: 0c212790; candidate: e8d8750; same orb
  • Node.js 22.19.0; autocannon 8.0.0; loopback HTTP
  • server pinned to CPU 2; load generator pinned to CPUs 4 and 6
  • 3-second warm-up followed by 10 seconds measured, 5 repetitions
  • before/after order alternated per repetition; fresh server process for every sample
  • all fixtures register 1,000 static routes; no fixture-specific production fast path
  • response: { "hello": "world" }; dynamic route: /users/:id; POST uses a small JSON body
  • dispersion is population coefficient of variation; p99 is the worst observed p99 across repetitions

These direct-server scenarios isolate the middleware/monitor change. #29 is present in both artifacts but its controller plans are intentionally outside this incremental measurement.

Scenario Main + #29 req/s + #30 req/s Mean change CV before → after Range before → after p99 max Errors
GET, c=10 34,453 36,582 +6.2% 4.9% → 7.0% 31,791–36,287 → 32,655–39,780 1 ms → 1 ms 0
GET, c=100 34,945 37,223 +6.5% 3.7% → 3.2% 32,957–36,767 → 36,120–39,341 5 ms → 5 ms 0
Dynamic GET, c=10 31,182 34,563 +10.8% 5.8% → 4.9% 29,426–34,418 → 32,667–37,699 1 ms → 0 ms 0
POST, c=10 30,109 31,231 +3.7% 1.2% → 3.0% 29,606–30,693 → 30,273–32,593 0 ms → 0 ms 0
Last of 1,000, c=10 34,970 37,791 +8.1% 2.1% → 5.5% 34,441–36,449 → 35,731–41,660 0 ms → 0 ms 0

The five paired deltas are not uniformly positive: GET c=10 includes one -9.4% run, POST one -1.4% run, and route 1,000 one -0.1% run. Their paired median changes are respectively +9.6%, +2.7%, and +7.3%. The aggregate direction is positive, but GET c=10 and route 1,000 remain noisy.

Populated pipeline

The pipeline fixture uses two prefixes, two postfixes, and one monitor.

  • means: 34,266 → 35,470 req/s (+3.5%)
  • medians: 35,128 → 35,720 req/s (+1.7%)
  • CV: 4.2% → 1.1%
  • paired deltas: +10.7%, +9.1%, +0.3%, +0.6%, -2.0%
  • p99: 0 ms; errors/timeouts/non-2xx: 0

Because three runs are near zero and one regresses, the populated-pipeline result remains directional/inconclusive. This PR claims the robust fast path only for empty or non-matching work.

Correctness

The integration test exercises an initially empty pipeline, dynamic prefix/postfix/monitor registration, priority order, monitor execution, removal, and the restored empty fast path. The existing contract suite covers HEAD, OPTIONS, errors, monitor isolation/errors/priorities, WebSocket success/error monitoring, and route lifecycle behavior. #29's controller-plan tests are also included after the rebase.

Commands run after rebase:

  • pnpm install --frozen-lockfile
  • pnpm build
  • pnpm --package=@antelopejs/core@1.4.7 dlx ajs module test . — 126 passing
  • pnpm lint

GitHub CI and GitGuardian pass on the rebased commit. No review or inline comment is currently open.

Limits and risk

Avoid route lookups, promise continuations, monitor snapshots, and sorting when the corresponding request pipeline stage has no work. Keep handler counts in sync with registration lifecycle changes.

Amp-Thread-ID: https://ampcode.com/threads/T-01a01745-cfcc-7179-a3a1-e5aa33780a0c
Co-authored-by: Upd4ting <upd4ting@gmail.com>
@Upd4ting
Upd4ting force-pushed the perf/http-middleware-fast-paths branch from 750602f to e8d8750 Compare August 19, 2026 16:50
@Upd4ting
Upd4ting merged commit f972258 into main Aug 19, 2026
2 checks passed
@Upd4ting
Upd4ting deleted the perf/http-middleware-fast-paths branch August 19, 2026 17:53
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.

2 participants