Skills· Official

Performance

Make software measurably faster and cheaper to run — measure first, find the one bottleneck, fix it, and prove the gain with before-and-after numbers instead of guessing.

When to use it. When a page, endpoint, query, or job is slow, a hosting or database bill jumps, load times or Core Web Vitals regress, or before launching something that must handle real traffic.

Most slow software has one bottleneck, and it's rarely where you'd guess. Measure, change one thing, measure again — and keep only what the numbers support.

Steps

  1. Define the target. What's slow, for whom, and how fast is fast enough? "The order page loads in under a second at the 95th percentile." "The nightly import finishes in ten minutes." Without a target you won't know when to stop.
  2. Measure the current state. Time the real path with realistic data: server timings or logs for endpoints, EXPLAIN ANALYZE for queries, a profiler for CPU, Lighthouse or WebPageTest for pages (LCP, INP, CLS). Record the numbers — they're your baseline.
  3. Find the bottleneck. Look at where the time actually goes. The usual culprits:
    • N+1 queries — a query inside a loop; fetch everything in one query or a batch
    • Missing indexes — a filter, join, or sort on an unindexed column (a sequential scan of a large table)
    • Unbounded work — loading every row or rendering every item, with no limit or pagination
    • Waterfalls — requests made one after another that could run in parallel
    • Oversized payloads — columns and fields you don't use, large JSON, unoptimized images, heavy JavaScript bundles
    • No caching — recomputing or refetching what rarely changes; rendering public pages per request when they could be static or cached at the edge
  4. Change one thing — the fix for the biggest measured cost. Prefer doing less work (fewer queries, smaller payloads, caching) over doing the same work faster.
  5. Measure again, the same way. Compare with the baseline. If the number didn't move, revert the change — complexity without a gain is a cost.
  6. Repeat until you reach the target, then stop. Don't optimize what doesn't matter.
  7. Keep it from regressing. Add a guard where it's cheap: a test that counts the queries a page makes, a bundle-size budget in CI, the index in a migration, an alert on response time.

Cost is performance too

Work you avoid doesn't only make things faster — it makes them cheaper. Caching public pages, letting idle servers sleep, batching requests, and fetching less are often the biggest savings on a hosting bill.

Done when

  • There's a stated target and a recorded baseline
  • The bottleneck was found by measurement, not assumed
  • Every change you kept has a measured improvement; the rest are reverted
  • Behaviour is unchanged and the tests pass
  • Something guards against the regression coming back

Report back

The target, the baseline, what the bottleneck was and how you found it, what you changed, and the before-and-after numbers. Name any trade-offs — staleness from caching, extra memory — for the person to accept.

Traps

  • Optimizing before measuring.
  • Testing with ten rows when production has ten million.
  • Caching without a plan for invalidation — fast and wrong.
  • Shaving microseconds off code while an N+1 query costs a hundred times more.

More skills