Skip to content

perf: add local render CPU benchmark - #3071

Draft
ascorbic wants to merge 3 commits into
mainfrom
perf/render-cpu-benchmark
Draft

perf: add local render CPU benchmark#3071
ascorbic wants to merge 3 commits into
mainfrom
perf/render-cpu-benchmark

Conversation

@ascorbic

@ascorbic ascorbic commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds a repeatable local CPU benchmark for server-rendered pages in the production-built Cloudflare performance fixture.

pnpm render-cpu keeps three distinct measurements instead of averaging them together: module evaluation from wrangler check startup, repeated first requests in fresh workerd processes, and batches after route warm-up. It captures V8 CPU profiles through the inspector protocol, drains every streamed response, waits briefly for request-owned continuation work, and reports median active CPU, median absolute deviation, garbage collection, response wall time, and the corresponding cold/warm query count. Raw .cpuprofile files and a JSON summary are written outside the repository for flamegraph analysis.

The query-count harness now sends browser-shaped Accept headers. This exercises the HTML layout-prefetch path that real navigations use and updates the D1 query snapshots accordingly. It also keeps Astro's agent-detected dev server attached to the harness lifecycle and fails promptly if the seed server exits before becoming ready.

The resulting D1 snapshot increase (+67 queries across cold and warm routes) is newly measured existing behavior, not runtime work introduced by this PR. The previous */* requests skipped the HTML prefetch branch entirely; browser navigations already take it in production. Making that cost visible gives follow-up optimization work a truthful baseline.

The fixture accepts an alternate Wrangler config path so the same build can be grounded against an isolated deployed Worker without committing account resource IDs.

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added and reviewed the user-facing changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...
  • I have included screenshots below if this PR changes the UI

The localization, changeset, Discussion, and screenshot items are not applicable: this changes repository-only performance tooling and a private fixture, with no published package or UI change.

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: OpenAI Codex (GPT-5)

Screenshots / test output

Not applicable — no UI changes.

Validated on the merged current origin/main head with:

  • pnpm --config.verifyDepsBeforeRun=warn build
  • pnpm --config.verifyDepsBeforeRun=warn typecheck
  • pnpm --config.verifyDepsBeforeRun=warn lint
  • pnpm --config.verifyDepsBeforeRun=warn format:check
  • pnpm --config.verifyDepsBeforeRun=warn query-counts --target sqlite
  • pnpm --config.verifyDepsBeforeRun=warn render-cpu -- --route home --startup-runs 1 --cold-runs 2 --requests 2 --batches 1 --warmups 1 (includes D1 query snapshot verification)
  • pnpm --config.verifyDepsBeforeRun=warn render-cpu -- --skip-prepare (full startup, first-request, and warm baseline across ten routes)

The same fixture was deployed to an isolated benchmark Worker for grounding. Across ten page types, local and deployed median CPU had r = 0.948 correlation and 0.75 ms mean absolute error. Query count explained 82% of local CPU variance and 73% of deployed CPU variance.

The cold-path split is material: on the merged head, Worker module evaluation was 23.5 ms median, first requests were 43–80 ms by route before adding startup, and warm renders were 4.2–12.1 ms. A warm-only profile therefore misses most of the CPU cost paid by a fresh isolate.

@changeset-bot

changeset-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ae7adb0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Query-count snapshot changes

17 routes changed, total Δ +67 queries.

D1

Route Before After Δ
GET / (cold) 17 22 +5
GET / (warm) 6 10 +4
GET /category/development (cold) 23 27 +4
GET /category/development (warm) 11 14 +3
GET /contributors (cold) 17 22 +5
GET /contributors (warm) 6 10 +4
GET /contributors-naive (cold) 24 29 +5
GET /contributors-naive (warm) 13 17 +4
GET /pages/about (cold) 17 22 +5
GET /pages/about (warm) 6 10 +4
GET /posts (cold) 17 22 +5
GET /posts (warm) 6 10 +4
GET /posts/building-for-the-long-term (warm) 17 16 -1
GET /search (cold) 22 27 +5
GET /search (warm) 11 15 +4
GET /tag/webdev (cold) 23 27 +4
GET /tag/webdev (warm) 11 14 +3

Comparing snapshot files between base and head. Updated automatically on each push.

@github-actions github-actions Bot added query-count changed PR diff modifies query-count snapshot files review/needs-review No maintainer or bot review yet labels Sep 11, 2026
@pkg-pr-new

pkg-pr-new Bot commented Sep 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@3071

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@3071

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@3071

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@3071

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@3071

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@3071

emdash

npm i https://pkg.pr.new/emdash@3071

create-emdash

npm i https://pkg.pr.new/create-emdash@3071

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@3071

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@3071

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@3071

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@3071

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@3071

@emdash-cms/registry-moderation

npm i https://pkg.pr.new/@emdash-cms/registry-moderation@3071

@emdash-cms/registry-verification

npm i https://pkg.pr.new/@emdash-cms/registry-verification@3071

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@3071

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@3071

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@3071

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@3071

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@3071

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@3071

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@3071

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@3071

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@3071

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@3071

commit: ae7adb0

@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 674 lines across 6 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
docs 90a4ac0 Sep 11 2026, 04:24 PM

@ascorbic
ascorbic marked this pull request as draft September 11, 2026 16:31
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 11, 2026

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://perf-render-cpu-benchmark.try.emdashcms.com, https://perf-render-cpu-benchmark-emdash-playground.emdash-cms.workers.dev (commit ae7adb0)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://ab7df132.try.emdashcms.com, https://ab7df132-emdash-playground.emdash-cms.workers.dev ae7adb0 2026-09-12T09:10:51.766Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://25ebaad6.try.emdashcms.com, https://25ebaad6-emdash-playground.emdash-cms.workers.dev 90a4ac0 2026-09-11T16:26:38.905Z Visit the dashboard ↗

@github-actions

Copy link
Copy Markdown
Contributor

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

overlap query-count changed PR diff modifies query-count snapshot files size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant