Performance Budget Reporting and Scorecards

A budget gate that fails a pull request tells one engineer that one build broke one threshold. That is enough to protect a release, but it is nowhere near enough to keep performance work funded, staffed, and visible over quarters. This guide, part of the Dashboarding & Team Adoption reference, is about the layer above the gate: how to turn thousands of raw pass/fail records into a scorecard an executive can read in ten seconds, a weekly digest an engineering lead actually opens, and a compliance-over-time metric that survives a budget-cutting meeting.

Reporting is where performance engineering stops being a private CI concern and becomes an organisational commitment. The audiences upstairs never see a Lighthouse trace or a bundle-analyzer treemap; they see whatever you choose to summarise for them. Get that summary wrong — too noisy, too technical, or too rosy — and the first austerity review quietly defunds the work. Get it right and you build a durable case that ties field metrics to revenue, retention, and headcount. The sections below walk through the audiences and what each one needs, how to design the scorecard itself, how to automate a weekly digest, how to define a defensible compliance metric, how to connect all of it back to adoption and funding, and finally which data sources feed the whole pipeline.

Who Reads a Performance Budget Report

The single most common reporting mistake is writing one document for everybody. An executive, a product manager, and an engineering lead want fundamentally different things from the same underlying data, and a report that tries to serve all three at once serves none of them. Before you design a scorecard, decide who the primary reader is and what decision they are trying to make.

Executives — a VP of Engineering, a CTO, a general manager — care about direction and risk, not values. They want to know whether performance is improving or degrading, whether it is a liability that could hurt conversion or SEO, and whether the current investment is paying off. Give them a single headline pass rate, a trend arrow, and at most one sentence of context. If an executive has to scroll, you have already lost them. The correct altitude here is "our checkout journey met its LCP budget of 2500 ms at P75 on mid-range mobile over Slow 4G in 94% of deploys this quarter, up from 81%."

Product managers sit one level down and care about their surface area. A PM who owns checkout wants to know whether checkout specifically is healthy, which routes in their area are worst, and whether a regression is blocking their roadmap. They translate the engineering signal into user impact and prioritisation, so give them per-journey breakdowns and the two or three worst routes rather than a global average that hides their problem inside someone else's success.

Engineering leads and the performance engineers themselves need the most granular view: which route regressed, by how many milliseconds, on which device profile, in which pull request, and whether the change is real or CI noise. This audience already lives in the Grafana budget-trend dashboards and the Lighthouse CI server, so your report for them is less a summary and more a triage queue that points at the exact commit to investigate.

Reporting audiences and their needs Three side-by-side columns describing what executives, product managers, and engineering leads each want from a performance budget report. One dataset, three reports Executives wants: direction + risk One headline pass rate A trend arrow One line of context Tie to revenue/SEO read time: 10s Product managers wants: their surface Per-journey health Worst 2 to 3 routes Roadmap blockers User-impact framing read time: 2m Engineering leads wants: triage queue Route + delta in ms Device profile Offending commit Noise vs real read time: hours
The same gate data must be summarised at three different altitudes; a report that serves only one audience is normal and correct.

The practical consequence is that you build one data pipeline and three views on top of it. The pipeline computes every metric once — pass rates, per-route percentiles, deltas against baseline — and each audience view queries the slice it needs. Never hand-maintain three parallel spreadsheets; they drift within a week and destroy your credibility the first time the executive number disagrees with the engineering number.

Designing the Scorecard

A scorecard is the executive-facing artifact, and it lives or dies on ruthless subtraction. The goal is that a reader who knows nothing about web performance can look at it and correctly answer three questions: are we healthy, are we getting better or worse, and where is the biggest problem. Three numbers, in other words. Everything else is supporting detail that belongs in a linked appendix, not on the card. The full construction is covered in Building an Executive Performance Scorecard; here is the anatomy.

The first number is the pass rate: the share of budget checks that passed over the reporting window. Define it precisely and publish the definition. A defensible version is "the percentage of production deploys in the last 30 days whose checkout LCP met its 2500 ms budget at P75, measured on emulated mid-range mobile over Slow 4G." State the window, the journey, the metric, the threshold, the percentile, and the device-plus-connection context every time. A pass rate with no percentile and no device context is a vanity number that means nothing and will not survive scrutiny.

The second element is the trend arrow: is the pass rate higher or lower than the previous equivalent window? An arrow plus a delta ("94%, up 13 points quarter over quarter") does more persuasive work than any chart, because it answers the direction question instantly. Compute the trend against a comparable window — this quarter versus last quarter, not this week versus a holiday week — so a seasonal traffic dip does not masquerade as a regression.

The third element is the worst routes: a short ranked list of the two or three journeys currently furthest over budget, each with its overage. "Search results INP is 340 ms at P75 on mid-range mobile over Slow 4G against a 200 ms budget" tells a PM exactly where to spend. This is the one place on the scorecard where you show a problem, and it is what converts a passive status report into an action driver.

Executive scorecard anatomy A scorecard showing a headline pass rate, a quarter-over-quarter trend arrow, and a ranked list of the worst routes by budget overage. Q3 Performance Budget Scorecard Pass rate (30d) 94% checkout LCP P75 Trend vs Q2 +13 pts Routes over budget 3 of 41 tracked Worst routes by overage (P75, mid-range mobile / Slow 4G) /search INP +140 ms /product LCP +620 ms /cart CLS +0.04 Everything else within budget. Full route table linked in the appendix.
Three answers — healthy, improving, biggest problem — on one card; every threshold carries its percentile and device-plus-connection context.

Colour is a signal, not decoration. Use one green, one amber, and one red, mapped to explicit thresholds, and never more. A scorecard with six colours forces the reader to build a legend in their head. Amber should mean "within tolerance but trending toward the ceiling" and red should mean "over budget now," and those bands should be documented so nobody argues about what a colour means during a review.

Automating a Weekly Digest

A scorecard someone has to remember to open is a scorecard nobody opens. The delivery mechanism that actually sustains attention is a pushed weekly digest — an email or a chat message that lands in the same inbox as everything else the reader triages. Automating it is a small pipeline: a scheduled job reads the aggregated data, renders a compact summary, and posts it. The full build lives in Weekly Performance Budget Email Digests; this section covers the shape.

The job runs on a cron schedule — early Monday is conventional, so the week opens with the number in front of everyone. It queries the Lighthouse CI server's API for the week's assertion results and the RUM store for field percentiles, computes the same three headline values as the scorecard, and renders them into a short templated message. Keep the digest to one screen: the headline pass rate, the trend versus last week, the worst two routes, and a link to the full dashboard for anyone who wants to drill in.

Here is a compact aggregation-and-render job in Node that pulls Lighthouse CI build data and emits a digest payload:

import { fetch } from "undici";

const LHCI_BASE = process.env.LHCI_SERVER_URL;
const PROJECT_ID = process.env.LHCI_PROJECT_ID;
const BUDGET_MS = 2500; // checkout LCP budget, P75, mid-range mobile / Slow 4G

async function getBuilds(sinceDays) {
  const since = Date.now() - sinceDays * 24 * 60 * 60 * 1000;
  const res = await fetch(
    `${LHCI_BASE}/v1/projects/${PROJECT_ID}/builds?limit=500`,
    { headers: { "Content-Type": "application/json" } }
  );
  const builds = await res.json();
  return builds.filter((b) => new Date(b.runAt).getTime() >= since);
}

function passRate(builds, metric, budget) {
  const evaluated = builds.filter((b) => b.metrics && metric in b.metrics);
  if (evaluated.length === 0) return null;
  const passed = evaluated.filter((b) => b.metrics[metric] <= budget);
  return Math.round((passed.length / evaluated.length) * 100);
}

async function buildDigest() {
  const thisWeek = await getBuilds(7);
  const lastWeek = (await getBuilds(14)).filter(
    (b) => new Date(b.runAt).getTime() < Date.now() - 7 * 24 * 60 * 60 * 1000
  );
  const now = passRate(thisWeek, "lcpP75", BUDGET_MS);
  const prior = passRate(lastWeek, "lcpP75", BUDGET_MS);
  const delta = now !== null && prior !== null ? now - prior : 0;
  return {
    headline: `Checkout LCP budget: ${now}% of deploys passed this week`,
    trend: delta >= 0 ? `up ${delta} pts` : `down ${Math.abs(delta)} pts`,
    context: "P75, emulated mid-range mobile over Slow 4G, 2500 ms budget",
    dashboardUrl: `${LHCI_BASE}/app/projects/${PROJECT_ID}`
  };
}

buildDigest().then((d) => console.log(JSON.stringify(d, null, 2)));

Schedule it with a GitHub Actions workflow so the runner, secrets, and logs live where the rest of your CI lives:

name: weekly-performance-digest
on:
  schedule:
    - cron: "0 13 * * 1"
  workflow_dispatch: {}
jobs:
  digest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci
      - name: Build and post digest
        env:
          LHCI_SERVER_URL: ${{ secrets.LHCI_SERVER_URL }}
          LHCI_PROJECT_ID: ${{ secrets.LHCI_PROJECT_ID }}
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
        run: node scripts/weekly-digest.mjs
Weekly digest pipeline A scheduled job reads the Lighthouse CI server and the RUM store, aggregates the week, renders a digest, and posts it to email and chat. Monday 06:00 digest pipeline LHCI server assertion results RUM store field percentiles Scheduled job aggregate + render Email digest execs + PMs Chat post eng channel One job, two sources, two channels — computed once, delivered where people already read.
The digest is a thin scheduled job over the same aggregated data; it pushes the number to where each audience already works.

Two rules keep a digest alive. First, never send an empty or unchanged digest silently dropped — if the week was quiet, say so in one line, because a predictable rhythm is what trains people to read it. Second, make every number in the digest reproducible from the linked dashboard; the moment a reader clicks through and the numbers disagree, the digest becomes noise. The digest and the dashboard must read from the same aggregation, which is exactly why you compute metrics once.

Defining a Compliance Over Time Metric

Pass rate for a single week is volatile. One noisy CI day or one holiday traffic pattern can swing it enough to trigger a false alarm or hide a real slide. What executives and budget owners actually want is a compliance-over-time metric: a smoothed, longitudinal measure of how consistently you stay within budget. This is the number that anchors a quarterly review, and it is worth defining carefully. The mechanics are expanded in Tracking Budget Compliance Over Time.

Define compliance as the fraction of a rolling window in which the tracked journeys met their budgets, weighted by traffic. A workable definition: over a trailing 8-week window, the share of production deploys whose checkout LCP stayed at or under 2500 ms at P75 on mid-range mobile over Slow 4G, weighted by the sessions each deploy served. Traffic weighting matters because a regression on a route that serves 2% of sessions is not equivalent to one on a route that serves 40%, and an unweighted average lets a low-traffic route dominate the headline.

Plot compliance as a line against your target, and the story tells itself. A line climbing toward a 90% target line, with the occasional dip that recovers, is the picture of a maturing practice. A line drifting away from the target is the picture that gets performance work funded — or, if you ignore it, the picture that gets cited when someone asks why conversion fell.

Compliance over an eight-week window A line chart showing weekly traffic-weighted budget compliance climbing from 71 percent to 93 percent and crossing above a 90 percent target line. Traffic-weighted compliance, trailing 8 weeks 60% 80% 100% 90% target W1 W2 W3 W4 W5 W6 W7 W8 Checkout LCP at 2500 ms, P75, mid-range mobile over Slow 4G; W5 dip recovered by W6.
Compliance smooths week-to-week noise into a defensible trend; the dashed target line turns "are we improving" into a yes-or-no.

Publish the definition alongside the number, and freeze it. The fastest way to lose trust is to change the compliance formula between reviews so the trend looks better — someone will notice, and every future number becomes suspect. If you must revise the metric, restate history under both the old and new definitions so the change is transparent. Pair the compliance line with a short note on what drove any dip: a specific regression, a CI-runner change that widened variance, or a genuine field shift picked up in RUM.

Connecting Reporting to Adoption and Funding

Reporting is not an end in itself; it is the instrument that keeps performance work adopted and funded. A scorecard that only engineers see changes nothing. A scorecard that lands in front of the people who set priorities and hold the budget is how a performance practice earns its continued existence. This is the direct bridge to Driving Team Performance Budget Adoption: adoption is what generates clean data, and reporting is what converts that data into organisational will.

The loop works like this. Good gating and instrumentation produce trustworthy data. Reporting turns that data into a visible commitment with a name and an owner. Visibility creates accountability — a route that shows up red in the weekly digest for a month becomes a conversation nobody can avoid. Accountability drives the fixes, the fixes improve the compliance line, and an improving compliance line is the single most effective artifact you can bring to a funding conversation. When someone asks whether the performance investment is worth it, "compliance rose from 71% to 93% over the quarter while checkout conversion held" is an answer with a number attached.

To make reporting fund the work rather than merely describe it, tie at least one metric to a business outcome the executive already cares about. If your RUM data lets you segment conversion or bounce by LCP bucket, report that correlation: sessions where checkout LCP stayed under 2500 ms at P75 on mid-range mobile over Slow 4G converted at a materially higher rate than sessions above it. That single linkage moves performance from a cost centre to a revenue lever in the reader's mind, and it is the sentence that protects the headcount when budgets tighten. Keep the causal claim honest — correlation framed as correlation — but do not bury the relationship in caveats until it disappears.

Data Sources That Feed the Reports

Every number on the scorecard traces back to one of two kinds of source: synthetic lab data from your CI, and field data from real users. Both matter, and a good report is explicit about which one it is showing, because they answer different questions and diverge in predictable ways.

The Lighthouse CI server is the system of record for gate outcomes. Running your own instance — see Self-Hosting the Lighthouse CI Server — gives you a queryable API of every build, its assertion results, and its lab metrics, which is exactly what the digest job reads. Lab data is stable and controllable, so it is ideal for gate pass rates and for attributing a regression to a specific commit, but it does not represent what your actual users experience on their actual devices and networks.

Field data comes from RUM. Real-user percentiles are the truth about experience, and they are what you should anchor executive-facing compliance and any business-outcome correlation to. RUM is noisier and lags a deploy by the time it takes sessions to accumulate, so it is poor for per-commit attribution but essential for the "are our users actually fast" question. The report should draw the pass rate from lab gates and the compliance-and-impact story from field data, and it should label each so no reader conflates them.

Source Answers Latency Best for Weak for
Lighthouse CI server (lab) Did this build pass its budget? Immediate, per build Gate pass rate, per-commit attribution, worst-route triage Real-user experience across device and network diversity
RUM store (field) Are real users within budget at P75/P90? Hours to days, needs session volume Compliance-over-time, business-outcome correlation, executive headline Attributing a change to one specific commit
Combined view Both, side by side Mixed Explaining a lab/field gap to leadership Nothing — this is the target state

The reconciling move is to show lab and field on the same card and explain the gap when it appears. A budget that passes in the lab but misses in the field usually means your CI device-and-network emulation is gentler than your real user base — for example gate runs on emulated mid-range mobile over Slow 4G while a meaningful share of traffic is slower still — and that gap is itself a reportable finding that argues for recalibrating thresholds. A report that surfaces and explains the lab-versus-field divergence reads as far more credible than one that quietly picks whichever number looks better this week.

Frequently Asked Questions

How often should we send a performance budget report?

A weekly digest for engineering leads and product managers, and a monthly or quarterly rollup for executives. Weekly keeps regressions visible while they are still cheap to fix; quarterly matches the cadence of funding and planning conversations. Send the weekly digest on a fixed day so the rhythm trains people to read it, and say so explicitly when the week was quiet rather than sending nothing.

What single metric belongs at the top of an executive scorecard?

A traffic-weighted pass rate for one flagship journey, stated with its full context — for example the share of deploys whose checkout LCP met 2500 ms at P75 on mid-range mobile over Slow 4G. Pair it with a trend arrow against the prior comparable window. Executives read direction and risk, so one honest headline number plus its trend outperforms any dense chart.

Should scorecards use lab data or field data?

Both, labelled clearly. Draw gate pass rates and per-commit attribution from the Lighthouse CI lab data, and draw compliance-over-time and any business-outcome correlation from RUM field percentiles. When the two diverge, show both and explain the gap, since a lab-field mismatch is usually a signal that your CI emulation is gentler than your real user base.

How do we define budget compliance so it survives scrutiny?

Use a rolling window, weight by traffic, and freeze the formula. A defensible definition is the traffic-weighted share of deploys over a trailing 8 weeks whose tracked journeys met their budgets at P75 on a stated device and connection. Publish the definition next to the number and never change it silently between reviews; if you must revise it, restate history under both definitions.

How does reporting actually help keep performance work funded?

Reporting turns gate data into a visible, owned commitment, and an improving compliance line paired with a business-outcome correlation is the strongest artifact you can bring to a budget review. Tie at least one metric to something the executive already values — such as conversion segmented by LCP bucket — so performance reads as a revenue lever rather than a cost, which is what protects the headcount when budgets tighten.