Skip to content

feat(ci): measure the per-commit benchmark path against the mocked population - #45455

Open
MajorLift wants to merge 3 commits into
jongsun/ci/benchmark-population-consistencyfrom
jongsun/ci/benchmark-mocked-series
Open

feat(ci): measure the per-commit benchmark path against the mocked population#45455
MajorLift wants to merge 3 commits into
jongsun/ci/benchmark-population-consistencyfrom
jongsun/ci/benchmark-mocked-series

Conversation

@MajorLift

@MajorLift MajorLift commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Changelog

CHANGELOG entry: null

Description

Stacked on #45204. Base that PR, not main — the mockMode stamping and the consumer-side population filter this builds on live there.

#45204 keeps the two populations from being blended. It does not give the gate a population it can actually use: only main and release/* publish, and both run live, so a mocked PR run resolves no baseline at all.

This makes the per-commit path measure mocked on every branch including main, which is what produces a mocked series for PRs to compare against. Live measurement does not disappear — it moves to the scheduled drift job in #45446, which passes live through the same input.

Why the per-commit path should not be live

The live population's timings are substantially a property of CDN cache state rather than of the commit. tokens.api.cx.metamask.io/v3/assets serves cache-control: max-age=10800, and on that endpoint a cache miss costs 292ms against 105ms for a hit — 2.77× at the median, on an identical request seconds apart (#45446). The cache is warmed by everyone else's traffic, so the hit ratio is exogenous: two runs of the same commit minutes apart can land either side of a TTL boundary.

That is tolerable for drift detection, which averages over many runs. It is not tolerable per-commit, where one run has to decide whether a merge proceeds.

What changed

  • resolveBenchmarkMockMode(branch, override?) — an explicit mocked/live override beats the branch heuristic. Anything else, including the empty string an unset workflow input expands to, falls through to the existing branch behaviour.
  • benchmark-mock-mode workflow input, default mocked, threaded into all four jobs — benchmarks, benchmarks-page-load, quality-gate, store-benchmark-stats. Every site that resolves the population reads the same value, so the harness, the gate and the publisher cannot disagree. A disagreement would file a live measurement in the mocked series, which is the failure this is shaped to prevent.
  • Separate files per population. stats/<branch>/performance_data_mocked.json alongside the existing performance_data.json. Keying only by branch would now put both series in one file, leaving the consumer's mockMode filter as the only thing keeping them apart — one unstamped entry and a mocked baseline silently absorbs live latency. live keeps the historical path so the existing series stays continuous.
  • resolve_mock_mode() in benchmark-stats-commit.sh, mirroring the TypeScript resolver including its precedence.

Verification

Both arms of the resolver change:

with the change            PASS   277 passed, 12 suites
benchmarks.ts at base      FAIL   2 failed, 7 passed

The two failures on base are exactly the two override cases. The fallback test — unset, empty, MOCKED, mock, true all falling through to the branch heuristic — passes in both arms, because it pins behaviour this must not change.

The shell resolver must agree with the TypeScript one, since they independently decide the same fact. All 20 branch × override combinations: shell-resolver-check.txt

branch=main               override=<unset> -> live
branch=main               override=mocked  -> mocked
branch=main               override=typo    -> live
branch=45147/merge        override=live    -> live
branch=45147/merge        override=MOCKED  -> mocked

An unrecognised override never picks a population — it falls through to the branch, in both implementations.

bash -n passes on the script; the workflow parses and all four jobs carry BENCHMARK_MOCK_MODE.

What is not proven here: that the mocked series is usable as a baseline. That needs the series to exist and accumulate depth, which is weeks of runs, not a PR. This delivers the publishing half of #45205; re-deriving the ceilings is the other half and stays open.

Gap to close after this lands: until #45446's scheduled job exists, nothing runs live. That is the intended sequencing — per-commit stops measuring the CDN first — but the live series pauses in the interval, and #45446 should follow closely.

Related issues

Progresses: #45205

Manual testing steps

  1. yarn jest shared/constants/benchmarks.test.ts development/metamaskbot-build-announce/
  2. On the next main push, confirm stats/main/performance_data_mocked.json is created and performance_data.json is untouched.
  3. Confirm a PR run's comment resolves a historical baseline from the mocked series.

Pre-merge author checklist


Note

Medium Risk
Touches CI quality-gate baseline selection and stats publishing paths; a harness/publisher/gate disagreement could silently mix live and mocked series or leave PRs without a usable baseline.

Overview
Makes the per-commit benchmark path measure the mocked population on every branch (including main), so PRs can eventually gate against a matching historical series instead of finding no baseline.

resolveBenchmarkMockMode(branch, override?) now lets an explicit mocked/live value beat the branch heuristic; unrecognized or empty overrides still fall through. The same override is threaded via a new benchmark-mock-mode workflow input (default mocked) into the harness, quality gate, and stats publisher so they cannot disagree.

Mocked results are written to performance_data_mocked.json; live keeps the unsuffixed historical path. Readers (getBenchmarkStatsUrl, announce/gate baseline fetch) select the matching file rather than relying only on in-file mockMode filtering.

Reviewed by Cursor Bugbot for commit 64c8933. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamask-ci metamask-ci Bot added team-extension-platform Extension Platform team INVALID-PR-TEMPLATE PR's body doesn't match template labels Aug 12, 2026
@metamask-ci

metamask-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

✨ Files requiring CODEOWNER review ✨

👨‍🔧 @MetaMask/extension-platform (5 files, +67 -8)
  • 📁 development/
    • 📁 metamaskbot-build-announce/
      • 📄 compare-benchmarks.ts +4 -1
      • 📄 historical-comparison.test.ts +24 -0
      • 📄 historical-comparison.ts +2 -4
      • 📄 performance-benchmarks.ts +13 -3
      • 📄 utils.ts +24 -0

👨‍🔧 @HowardBraham (5 files, +67 -8)
  • 📁 development/
    • 📁 metamaskbot-build-announce/
      • 📄 compare-benchmarks.ts +4 -1
      • 📄 historical-comparison.test.ts +24 -0
      • 📄 historical-comparison.ts +2 -4
      • 📄 performance-benchmarks.ts +13 -3
      • 📄 utils.ts +24 -0

👨‍🔧 @itsyoboieltr (5 files, +67 -8)
  • 📁 development/
    • 📁 metamaskbot-build-announce/
      • 📄 compare-benchmarks.ts +4 -1
      • 📄 historical-comparison.test.ts +24 -0
      • 📄 historical-comparison.ts +2 -4
      • 📄 performance-benchmarks.ts +13 -3
      • 📄 utils.ts +24 -0

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 90740f9. Configure here.

Comment thread .github/scripts/benchmark-stats-commit.sh
@metamask-ci

metamask-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Builds ready [90740f9]
⚡ Performance Benchmarks (Total: 🟢 16 pass · 🟡 7 warn · 🔴 1 fail)

Baseline (latest main): unknown | Date: unknown | Pipeline: 31585190838 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]🟡 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.8s
  • 🟡 confirmTx/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 3.3s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 assetClickToPriceChart
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 264ms
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🔴 swap/INP: p75 712ms
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 105 Bytes (0%)
  • ui: 50 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 36 Bytes (0%)

@MajorLift
MajorLift deployed to pr-comment August 12, 2026 10:31 — with GitHub Actions Active
@MajorLift
MajorLift force-pushed the jongsun/ci/benchmark-population-consistency branch from fb38a10 to 338de43 Compare August 12, 2026 10:35
…anch

`resolveBenchmarkMockMode` takes an explicit override that beats the branch
heuristic, threaded from a `benchmark-mock-mode` workflow input defaulting to
`mocked`. Every job that resolves the population reads it, so the harness, the
gate and the publisher cannot disagree.

The two series get separate files — `performance_data_mocked.json` alongside
the existing `performance_data.json` — so a mocked run can never overwrite the
live series, and the consumer's mockMode filter stops being the only thing
keeping them apart.

Live measurement moves to the scheduled drift job in #45446, which passes
`live` through the same input.
@sonarqubecloud

Copy link
Copy Markdown

@MajorLift
MajorLift deployed to pr-comment August 12, 2026 11:03 — with GitHub Actions Active
@metamask-ci

metamask-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Builds ready [f020eb5]
⚡ Performance Benchmarks (Total: 🟢 13 pass · 🟡 10 warn · 🔴 1 fail)

Baseline (latest main): unknown | Date: unknown | Pipeline: 31588153782 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]🟢 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]
🟡 load_new_account
🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.9s
  • 🟡 bridgeUserActions/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 208ms
  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🔴 sendTransactions/INP: p75 744ms
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 2.0s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 105 Bytes (0%)
  • ui: 50 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 63 Bytes (0%)

@MajorLift
MajorLift deployed to pr-comment August 12, 2026 11:13 — with GitHub Actions Active
@metamask-ci

metamask-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Builds ready [f020eb5]
⚡ Performance Benchmarks (Total: 🟢 13 pass · 🟡 10 warn · 🔴 1 fail)

Baseline (latest main): unknown | Date: unknown | Pipeline: 31588153782 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]🟢 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]
🟡 load_new_account
🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.9s
  • 🟡 bridgeUserActions/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 208ms
  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🔴 sendTransactions/INP: p75 744ms
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 2.0s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 105 Bytes (0%)
  • ui: 50 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 63 Bytes (0%)

Splitting the write path left the read path pointing at the live file
unconditionally, so a mocked consumer filtered an unsuffixed series that
holds no mocked entries and reported no baseline forever — the mocked
series would have been published and never read.

`getBenchmarkStatsUrl` selects the file; the PR comment's "Baseline logs"
link follows the same selection so it cannot contradict the numbers beside it.
@metamask-ci

metamask-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Builds ready [64c8933] [reused from f020eb5]
⚡ Performance Benchmarks (Total: 🟢 13 pass · 🟡 10 warn · 🔴 1 fail)

Baseline (latest main): unknown | Date: unknown | Pipeline: 31594839665 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]🟢 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]
🟡 load_new_account
🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.9s
  • 🟡 bridgeUserActions/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 208ms
  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🔴 sendTransactions/INP: p75 744ms
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 2.0s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 105 Bytes (0%)
  • ui: 50 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 63 Bytes (0%)

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

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template size-M team-extension-platform Extension Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant