Skip to content

perf(producer): worker sizing measures screenshot capture, one browser launch fewer - #6630

Merged
miguel-heygen merged 1 commit into
mainfrom
perf/calibrate-screenshot
Oct 28, 2026
Merged

miguel-heygen merged 1 commit into
mainfrom
perf/calibrate-screenshot

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

What

Auto worker sizing now measures capture in screenshot mode, the mode the parallel workers it sizes actually use. Its calibration browser no longer starts in drawElement mode first.

Why

Calibration runs before every auto-sized multi-worker render. It launched its browser with drawElement on, but a multi-worker render then turns default-on drawElement off (shouldClampDefaultDrawElement, "parallel capture has no runtime self-verification") and captures by screenshot. Two costs:

  • The sample frames timed the wrong capture mode (drawElement is the cheaper one), so the cost estimate understated what the workers would pay.
  • A comp that drawElement refuses (mix-blend-mode, filters, ...) was found refused only inside calibration, which then relaunched and re-initialised a second browser. That is one extra browser launch and page init on every such render.

Why under 100 lines

One lever: calibration samples frames in the capture mode the render will actually use. It is one helper at the existing call site plus its test; nothing else in sizing changes.

Related work

Refs #5945 (renders the fast capture refuses keep their parallel workers).

How

calibrationCaptureConfig(cfg) in renderOrchestrator.ts asks the existing clamp predicate whether a parallel render would keep drawElement. If not, calibration gets useDrawElement: false; an explicit opt-in (PRODUCER_EXPERIMENTAL_FAST_CAPTURE=true or HF_DE_PARALLEL_STREAM=true) still calibrates in drawElement mode. The cloud planner's frame-cost probe (planFrameCost.ts) is untouched.

Worker count only moves if the screenshot sample's p95 crosses the 600 ms calibration target where the drawElement sample did not, which can only lower the count. Frames are the same at any worker count.

Test plan

  • Unit tests added: calibrationCaptureConfig measures screenshot by default and keeps drawElement for both opt-ins.
  • Fails without the fix: renderOrchestrator.test.ts > calibrationCaptureConfig > measures screenshot capture, the mode parallel workers use (returning the config unchanged fails exactly this test, 1 failed / 290 passed).
  • tsc --noEmit (producer) exit 0; renderOrchestrator.test.ts 291 passed; oxfmt and oxlint clean on both files.
  • Manual testing performed: before/after on the real CLI (below).
  • Documentation updated (not applicable)
  • Comments follow CONTRIBUTING.md "Comments"

Before / after

Published hyperframes@0.8.210 vs the same bundle with only this change (the one-line equivalent in the built chunk), Apple M4 Pro (14 cores, 24 GB, hardware GL), hyperframes render on repo fixtures, one render at a time, interleaved, 5 runs each, medians. wall - compile drops compile, which is network-bound for these fixtures (a remote video) and swings by several seconds.

fixture path wall before wall after wall - compile before after setup stage before after output
style-11-prod, 1080x1920, 14 s screenshot, 4 workers 13.76 s 12.72 s 9.96 s 9.17 s (-8%) 1.8 s 1.0 s byte-identical (same sha256, all 10 runs)
overlay-montage-prod + one mix-blend layer, 1080x1920, 42 s screenshot, 4 workers 32.92 s 32.57 s 23.30 s 22.96 s (-1.5%) 3.0 s 2.4 s within this fixture's own run-to-run variation (~52 dB PSNR between two runs of main)

@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 120 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE · 0 blocker · 0 important · 0 nits · head 04384219

Scope

Calibration now uses the same capture mode that clamped parallel workers will use (DE off, same forceScreenshot). The predicate mirrors the call site's shouldClampDefaultDrawElement. deParallelStreamForced is only set when deParallelRouterEligible, and calibration is skipped then, so ignoring that flag here is safe. The calibration session is closed in finally, and probeSession passes through unchanged. The fails-without-fix test is named. All workflows are green on this head. The regression run hit a Docker layer-fetch error on shard-4, and the re-run passed.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit 2b6d176 Oct 28, 2026
126 of 137 checks passed
@miguel-heygen
miguel-heygen deleted the perf/calibrate-screenshot branch October 28, 2026 07:55
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