Skip to main content

Performance budgets and measurement

Performance is user-visible latency, responsiveness, stability, resource use, and efficiency under real constraints. “Feels slow on my phone” starts an investigation; it is not a measurement.

Define the journey and metric​

JourneyUser metricSupporting resources
cold launch to usable homeTTID, TTFD, p50/p95/p99CPU, disk, GC, class loading
search typing to resultsinput-to-render latencynetwork, parsing, DB, recomposition
feed scrollslow/frozen frames, frame timingCPU/GPU, allocations, image decode
photo uploadcompletion/time/failurebytes, radio wakeups, disk, battery
30-minute callthermal/battery/memory slopecodecs, network, wake locks

Define device tier, OS, dataset size, network condition, power/thermal state, build variant, compilation mode, and starting state. An average hides the users harmed by the tail; track percentiles and failure/timeout rate.

Budgets before optimization​

search interaction budget: 400 ms p95
debounce: 100 ms
API/network: 180 ms
parse/map: 30 ms
DB transaction: 40 ms
UI render: 50 ms

The numbers are product-specific. A budget forces trade-offs and ownership. If network already consumes the entire target, shaving 2 ms from Kotlin mapping is noise.

Measure release-like behavior​

  • Use non-debuggable/profileable release-like builds with shrinking/optimization where relevant.
  • Use representative physical devices, especially low/mid tiers; emulators are useful for correctness, not end-user numbers.
  • Warm up where the experiment requires it and state compilation/cache conditions.
  • Run enough iterations; report distribution and variance, not the best run.
  • Change one hypothesis at a time and compare traces.
  • Avoid profiler overhead when collecting benchmark numbers; use tracing/benchmark modes designed for measurement.

End-to-end versus component benchmarks​

  • Macrobenchmark: startup, scroll, animation, multi-screen journey.
  • Microbenchmark: a hot pure function/algorithm/serialization operation.
  • Production telemetry/vitals: real devices, distributions, regressions and reach.
  • Profiler/Perfetto: explains why a measured problem occurs.

Passing a microbenchmark cannot prove the app launch is fast. A production alert cannot identify the blocking function without diagnostic evidence.

Regression gates​

Keep stable journey scenarios, device/lab policy, baseline history, allowable variance, and trace artifacts. Gate meaningful regressions with statistical/noise awareness rather than a brittle single-run threshold. Compare APK size/startup/jank/memory/network/battery as relevant to a change.

Do not optimize proxy metrics blindly

Lower CPU can increase latency; caching reduces network but increases memory/disk/staleness; more parallelism may improve one request while causing thermal throttling. Optimize the user journey within resource constraints.

Sources​

Exercise​

Create budgets and a reproducible benchmark protocol for cold launch, search, feed scroll, checkout, and one-hour background sync. Include p95 target, device tier, data/network state, and diagnostic tool.