Triaging a Perfherder regression bug

SkillMonitoring & ops

Lets your agent triage Firefox performance regression bugs: confirm alerts, find causes, and work toward a fix.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Triaging a Perfherder regression bug skill

About this capability

Handle a Perfherder performance regression bug end to end: read the alert bug, confirm whether the regression is real, find the cause, and iterate to a fix. Use when the user has a Perfherder/browsertime regression bug (the "N% <test> ... regression on <date>" bugs filed in Testing::Performance), ne

What this skill tells your AI

The instructions your AI receives, as published by mozilla-firefox/firefox in .agents/skills/perf-regression-triage/SKILL.md and read by ahel’s review.

Tooling

Three tools cover the three kinds of evidence in a regression bug. Use them rather than fetching URLs by hand — WebFetch on a Treeherder or profiler URL returns a UI shell with no data in it.

  • The regression bugmcp__moz__get_bugzilla_bug, or the @moz:bugzilla://bug/{id} resource. There is no Bugzilla CLI; this is the supported path.
  • Push and job datatreeherder-cli <rev>. Use --perf for performance and resource data, --repo autoland to inspect the culprit push, and --watch --notify to wait on a running try push instead of polling it.
  • Before/After profilesprofiler-cli, driven through the profiler-analysis skill. If it is not installed: npm install -g @firefox-devtools/profiler-cli@latest.

profiler-analysis owns the profiler-cli protocol (run profiler-cli guide first, stop the daemon when done). Hand profiles to that skill instead of reimplementing it here.

The regression policy gives the patch author 3 business days to acknowledge and start investigating before the patch may be backed out. Establish early whether that clock is running, and tell the user if it is close to expiring.

Step 1: read the bug

Fetch it with @moz:bugzilla://bug/{id}. Every Perfherder alert bug carries the same machine-readable payload. Pull out all of it before doing anything else:

  • Alert summary ID — the perfherder/alerts?id=NNNNN link. Feeds --alert in step 2.
  • Culprit push revision — the pushloghtml?changeset=... link in comment 0.
  • Base / new revisionsbaseRev= and newRev= in the PerfCompare link.
  • Regressed tests — first column of the alert table.
  • Platform and options — e.g. linux2404-64-shippable, fission webrender.
  • Before/After profiles — the profiler.firefox.com links in the last column.

The culprit push usually contains several patches. Inspect it directly rather than reading the pushlog HTML:

treeherder-cli <culprit-rev> --repo autoland --perf

Identify which patch is the user's and which files it touched (git show <rev> / the linked Phabricator revision). If the push has multiple candidate patches and it is not obvious which is responsible, say so — the confirmation push below tests the user's patch specifically, which is what settles it.

Summarize for the user: how big the regression is, which tests, which platform, and what the patch changed. Then move to confirmation.

Step 2: confirm it

Do this before any investigation. A meaningful fraction of alerts do not reproduce.

The whole confirmation is one command, not two manual pushes. --alert runs exactly the tests in the alert summary and compares your working revision against the base revision your patch sits on, pushing both sides for you:

./mach try perf --alert <ALERT_ID> --rebuild 10

Read references/confirm.md before running it — it covers getting the local repo onto the right base revision, how many retriggers are actually needed, the pgo/shippable trap, and how to read the result.

Never push to try without explicit approval from the user. Show the exact command, say roughly what it will cost in CI, and wait.

Then branch on the outcome:

  • Reproduces — continue to step 3.
  • Does not reproduce — do not start optimizing. Go to references/close-out.md; this is likely noise or an unrelated patch in the same push.
  • Ambiguous / overlapping distributions — more retriggers, or narrow to the single most-regressed test. See references/confirm.md.

Step 3: find the cause

Start with the Before/After profiles already linked in the bug — they are free and specific to the regressed test. Hand them to the profiler-analysis skill rather than fetching them yourself; WebFetch on a profiler URL only retrieves the UI shell.

Compare against what the patch actually changed. Most Perfherder regressions on speedometer-class benchmarks come from work added to a hot path, a lost fast path, extra allocation, or added main-thread sync work.

Step 4: iterate to a fix

Read references/iterate.md. The loop is change → narrow try push → check, and the entire point of that file is keeping each round cheap: narrow the test set, drop to one platform, and only re-run the full alert set for the final confirmation.

Step 5: close out

Read references/close-out.md for the possible resolutions, the bug fields to set, and who to talk to when the right answer is "this regression is acceptable."

Cost discipline

This skill exists partly to keep regression work cheap, in CI and in tokens.

  • One push per question. --alert gives base and new together; do not push twice.
  • Confirm broadly once, then iterate narrowly. Full alert-set reruns are for the final check only.
  • Do not read the reference files up front. Read the one for the step you are on.
  • Read profiles through profiler-analysis, not by downloading them into context.

Signals

GitHub stars
13k
Forks
2k
Last commit
Sep 2026

Others that do the same job

Advanced
Catalog kind
skill
Gateway key
perf-regression-triage
Source
github.com/mozilla-firefox/firefox