Performance Testing on Throttled Mobile Profiles

Every lab performance test is a simulation of some reader. Lighthouse's default mobile profile simulates one specific reader — a mid-range phone on a slowish 4G connection — and most teams never check whether that reader resembles their own. For a developer documentation site whose readers are mostly on laptops with fibre, the default is pessimistic, and a team chasing a 90 Lighthouse score may be optimizing for someone who never visits. For a consumer site whose readers use budget Android phones on congested networks, the default is optimistic, and a green score hides a slow site.

This guide explains what throttling profiles actually do, calibrates lab settings against field data for two static sites with very different audiences, adds testing on a real mid-range phone, and sets up CI runs with both a standard and a calibrated profile. It is part of Performance Budgets and Lighthouse CI.

Prerequisites

  • Field data: CrUX for pages with enough traffic, or your own RUM with the web-vitals library.
  • Lighthouse 12 (CLI or Lighthouse CI), and WebPageTest for real-network tests.
  • Optionally, a physical mid-range Android phone and a USB cable for remote debugging.

What Throttling Does

Lighthouse's default mobile preset applies:

SettingValue
Round-trip time150 ms
Download throughput1.6 Mbps
Upload throughput750 kbps
CPU slowdown4×
Viewport412 × 823, DPR 1.75
Methodsimulated (Lantern)

"Simulated" means Lighthouse loads the page without throttling and then estimates what the timings would have been under these conditions, using a model of the network and CPU. It is fast and stable, but the model can misjudge sites with unusual loading patterns — many small requests, heavy use of HTTP/3, or service workers. "Devtools" throttling (--throttling-method=devtools) actually slows the connection and CPU in real time; it is slower and noisier but closer to reality for such sites. WebPageTest throttles at the packet level on real devices or VMs, the most realistic of the three.

Comparison of simulated, DevTools and packet-level throttling A matrix comparing throttling methods. Simulated throttling in Lighthouse is fastest and most stable but models rather than measures, and can misjudge unusual loading patterns. DevTools throttling applies real delays in the browser, is slower and noisier, and handles most patterns. Packet-level throttling in WebPageTest is the most realistic, slowest to run, and suited to periodic calibration rather than every pull request. Three ways to throttle Method Speed and stability Realism Use for Simulated (Lighthouse) fast, low variance modelled every pull request DevTools (Lighthouse) slower, noisier real delays unusual loading patterns Packet-level (WebPageTest) slowest most realistic weekly calibration
The CI suite uses simulated for speed and stability, with weekly packet-level runs to keep it honest.

Two Sites, Two Audiences

The two sites in this guide have opposite audiences:

  • Developer docs: 1,300 pages, Eleventy, readers 71% desktop, mostly in North America and Europe.
  • Consumer recipe blog: 2,100 pages, Astro, readers 83% mobile, a large share in South and Southeast Asia on mid-range Android phones.

For each, the p75 LCP from CrUX on the home page and two popular templates was compared with lab LCP under several profiles, five Lighthouse runs each:

ProfileDocs lab LCPDocs field p75Recipe lab LCPRecipe field p75
Lighthouse default mobile2.1 s1.2 s (mobile)2.4 s3.1 s
Desktop preset0.7 s0.8 s (desktop)0.9 s—
Custom "fast 4G" (RTT 40 ms, 9 Mbps, CPU 2×)1.1 s1.2 s (mobile)1.4 s3.1 s
Custom "budget Android" (RTT 200 ms, 1.2 Mbps, CPU 6×)2.9 s—3.2 s3.1 s

For the docs site, the default mobile profile overstated mobile LCP by 75%; "fast 4G" matched the field within 0.1 s. For the recipe blog, the default understated field LCP by 0.7 s, and "budget Android" matched.

Default lab LCP compared with field LCP for two audiences Paired bars. For the developer docs site, lab LCP under Lighthouse default mobile throttling was 2.1 seconds while field p75 mobile LCP was 1.2 seconds, so the lab overstated it. For the recipe blog, lab LCP was 2.4 seconds while field p75 was 3.1 seconds, so the lab understated it. Lab under default throttling versus field p75 Lab (default mobile) Field p75 Developer docs 2.1 s 1.2 s Recipe blog 2.4 s 3.1 s
Lighthouse 12 medians of five runs; field values from CrUX for the same URLs over 28 days.

Step 1: Define a Calibrated Profile

Lighthouse CI accepts custom throttling in settings. The recipe blog added a "budget Android" collection alongside the default:

{
  "ci": {
    "collect": {
      "url": ["http://localhost:4321/", "http://localhost:4321/recipes/dal-tadka/", "http://localhost:4321/collections/weeknight/"],
      "numberOfRuns": 5,
      "settings": {
        "preset": "perf",
        "formFactor": "mobile",
        "throttlingMethod": "simulate",
        "throttling": { "rttMs": 200, "throughputKbps": 1200, "cpuSlowdownMultiplier": 6 },
        "screenEmulation": { "mobile": true, "width": 360, "height": 780, "deviceScaleFactor": 2 }
      }
    }
  }
}

A separate config file keeps the default mobile profile, so results can still be compared with published benchmarks and with Search Console's lab data. Both run in CI; budgets apply to the calibrated one, as described in Writing a Performance Budget That Fails Builds.

Step 2: Check the CPU Multiplier Against the Runner

A 4× or 6× CPU slowdown is relative to the machine running the test. A CI runner that is much faster or slower than a typical developer laptop changes what "6×" means. Lighthouse reports a benchmarkIndex for the host; on GitHub's standard runners it was around 1,250, on a developer M2 laptop around 2,900. For the calibrated profile, the recipe team computed the slowdown per environment so that the effective CPU speed matched the target device — 6× on CI runners, 13× on laptops — and recorded the benchmark index with each result. Without that, laptop runs looked 40% faster than CI runs of the same build.

Step 3: Test on a Real Phone

Simulation cannot capture everything. Once a month, the recipe team runs the three key pages on a real Samsung Galaxy A14 (a common budget phone among its readers) over a real 4G connection, using Chrome remote debugging and the Performance panel, and a WebPageTest run on a Moto G-class device from the Mumbai location. The real-device results caught two things the simulation missed: a CSS backdrop-filter on the sticky header that cost 30–40 ms per frame on the phone's GPU during scrolling, and thermal throttling after two minutes that made long recipe pages with many images noticeably slower to scroll.

Cadence of lab tests at different realism levels Every pull request runs Lighthouse CI with simulated throttling in both the default and calibrated profiles against the preview build. Every week, WebPageTest runs packet-level throttled tests on real devices from the main reader regions. Every month, a person tests key pages on a real budget phone. Field data from RUM is compared with all three every month to recalibrate. Which test runs when Every PR Lighthouse CI, 2 profiles Weekly WebPageTest, real devices Monthly budget phone by hand Monthly review lab vs field
The fast, stable tests gate merges; the slow, realistic ones keep the fast ones calibrated.

Step 4: Recalibrate When Things Change

Calibration drifts. The docs site's audience shifted after a product launch in India, raising its mobile share from 29% to 41% and moving field LCP up; the "fast 4G" profile then understated it. A monthly comparison of lab and field — the approach in Comparing Lab and Field Data with CrUX — flagged the gap, and the docs site added a second calibrated profile for the new audience segment.

Explaining Profiles to the Rest of the Team

Throttling settings look like arbitrary numbers to anyone outside the performance work, and a Lighthouse score that changes because the profile changed invites suspicion. Both teams added a short note at the top of each CI report stating the profile in plain words — "budget Android on congested 4G, our median recipe reader" — and kept a one-page explanation in the repository of how the profile was derived from field data and when it was last calibrated. When a product manager asked why the recipe site's Lighthouse score had "dropped" from 94 to 81 overnight, the answer was in that document: nothing had changed on the site, the report now used the profile that matched real readers, and the lower number was the more honest one.

Measured Impact

MeasureDefault profile onlyDefault + calibrated profiles
Docs: lab-to-field LCP gap (mobile)+0.9 s (lab pessimistic)+0.1 s
Recipes: lab-to-field LCP gap−0.7 s (lab optimistic)+0.1 s
Recipes: regressions caught in CI that the default missed (6 months)—5
Docs: optimization work avoided on non-issues (estimated)—~3 weeks
CI time per pull request (both profiles)2.1 min3.4 min

The docs team's biggest gain was negative: they stopped a planned project to shave 400 ms off mobile LCP that their actual readers would never have noticed.

Pitfalls & Rollback

  • One profile for every site. The default is a convention, not a description of your readers.
  • Comparing runs across machines without checking CPU speed. Record benchmarkIndex.
  • Treating simulated throttling as ground truth. Validate with packet-level and real-device tests.
  • Calibrating once. Audiences change; recheck monthly.
  • Rollback: calibrated profiles are separate config files; removing them returns CI to the default profile without affecting anything else.

Conclusion

A lab test is only as useful as its resemblance to your readers. Keep Lighthouse's default mobile profile for comparability, add a profile calibrated to your field data, adjust CPU slowdown for the machine running the tests, and check the simulation against real devices regularly. On these two sites that turned lab numbers from misleading — in opposite directions — into predictions within 0.1 s of the field.

FAQ

What does Lighthouse's default mobile throttling simulate?

A mid-tier phone on a slow 4G connection, with about 150 milliseconds round-trip time, 1.6 Mbps download and a 4x CPU slowdown relative to the test machine. By default it uses simulated throttling, which estimates timings from an unthrottled load rather than slowing the network in real time.

Should I change the default throttling?

Keep the default for comparability with other sites and tools, but add a second profile calibrated to your own field data. If your readers are mostly on fast desktop connections or mostly on low-end Android devices, the default will overstate or understate their experience.

How do I calibrate throttling against field data?

Pick a few pages with enough field traffic, compare their CrUX or RUM p75 LCP with lab LCP under different throttling settings, and choose the setting whose lab results land closest to the field. Repeat when the audience or the site changes significantly.

Is CPU throttling on a fast machine realistic?

Roughly. A 4x slowdown on a modern laptop approximates a mid-range phone, but CPU throttling does not simulate thermal limits, memory pressure or slower GPUs. Testing on a real mid-range Android phone now and then keeps the lab honest.

Filed underHow-tosLighthouse