agentsclimarketplace

Performance audit

Skill RBraga01/a-team/skills/performance-audit

Systematic performance investigation workflow. Use when performance regressions are suspected, before and after optimisation work, or as a pre-release gate for performance-critical features. Produces a baseline, identifies the real bottleneck, and validates improvement with hard numbers.From its SKILL.md

Install
npx -y skills add RBraga01/a-team --skill performance-audit

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.2 KB, as published. Nobody here has run it

Performance Audit

The Law

A PERFORMANCE CLAIM WITHOUT NUMBERS IS AN OPINION.
"I think it's faster" is not a result.
"p95 latency dropped from 480ms to 42ms on a 1000-item dataset" is a result.

When to Use

  • Before any optimisation work (establish baseline first)
  • When a performance regression is reported
  • As a pre-release gate on performance-critical features
  • After an optimisation to validate the improvement

Audit Workflow

Step 1: Define the Performance Goal

Before measuring anything, define what "good" looks like:

CategoryExample target
API latencyp95 < 200ms at 100 concurrent users
Page loadFirst Contentful Paint < 1.5s on 4G
Mobile frame rate60fps during scroll, 0 jank frames
Build timeFull build < 3 minutes
MemoryPeak heap < 512MB under load
Bundle sizeJS bundle < 250KB gzipped

If no target exists, the first audit establishes the baseline that becomes the target.

Step 2: Measure the Baseline

Run the benchmark before any changes. Record:

  • Tool used and exact command
  • Input size and conditions
  • Raw numbers (min, p50, p95, p99, max)
  • System state (CPU, memory, concurrent users)
## Baseline — YYYY-MM-DD

**Feature:** User search endpoint
**Tool:** k6
**Command:** `k6 run --vus 50 --duration 60s scripts/search-load-test.js`
**Input:** 1000-user dataset, query="test"

| Metric | Value |
|--------|-------|
| p50 | 45ms |
| p95 | 380ms |
| p99 | 720ms |
| Error rate | 0.2% |
| Throughput | 210 req/s |

Step 3: Profile — Find the Real Bottleneck

Use the appropriate tool for the stack. Read the output. Don't guess.

Web APIs

# Node.js — CPU profile
node --prof app.js
# Run load test, then:
node --prof-process isolate-*.log > profile.txt

# Python — flame graph
pip install py-spy
py-spy record -o profile.svg --pid $(pgrep -f "python app.py")

# Go — pprof
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# Database — slow query log
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT ...;

Frontend

# Bundle analysis
npx webpack-bundle-analyzer stats.json
npx source-map-explorer dist/main.js

# Runtime: Chrome DevTools → Performance tab
# Record interaction → identify long tasks (>50ms)

# Lighthouse CI
npx lhci autorun

Mobile

  • Android: Android Studio → Profiler → CPU/Memory/Network
  • iOS: Xcode → Instruments → Time Profiler
  • Flutter: flutter run --profile → DevTools → Performance overlay

Step 4: Report the Finding

State the bottleneck with evidence, not assumption:

## Bottleneck Found

**Location:** `UserSearchService.search()` — lines 45-67
**Evidence:** pprof shows 78% of CPU time in this function
**Root cause:** For each of 50 search results, a separate `getUserById()` DB call is made (N+1 query)
**Impact:** 47 sequential DB calls per request × ~8ms each = ~376ms per request

Step 5: Apply One Change

Single change. Document hypothesis and expected impact before applying:

## Change Applied

**Hypothesis:** Replacing per-item DB lookups with a single JOIN will eliminate 46 of the 47 DB calls
**Change:** `UserSearchService.search()` — replace loop + `getUserById()` with `getUsersByIds(ids)` JOIN
**Files modified:** `src/services/UserSearchService.ts`
**Expected impact:** p95 latency from 380ms to < 50ms

Step 6: Re-Measure and Compare

Run the exact same benchmark from Step 2.

## After Optimisation — YYYY-MM-DD

**Change:** N+1 query replaced with single JOIN

| Metric | Before | After | Delta |
|--------|--------|-------|-------|
| p50 | 45ms | 12ms | -73% |
| p95 | 380ms | 38ms | -90% |
| p99 | 720ms | 65ms | -91% |
| Error rate | 0.2% | 0.1% | -50% |
| Throughput | 210 req/s | 890 req/s | +324% |

**Verdict:** IMPROVEMENT CONFIRMED
**Root cause validated:** DB calls per request: 47 → 1
**No regression:** error rate stable, memory unchanged

Step 7: Verdict

VerdictCriteria
IMPROVEMENT CONFIRMEDMeasurable improvement on target metric, no regression elsewhere
INCONCLUSIVENo measurable change — hypothesis was wrong; identify next bottleneck
REGRESSIONChange made things worse — revert immediately, re-diagnose
GOAL METTarget from Step 1 achieved — further optimisation not required

Performance Budget (Pre-Release Gate)

For release-critical features, define performance budgets in docs/performance-budgets.md:

api_latency:
  endpoint: POST /api/search
  p95_ms: 200
  measured_with: k6
  load: 100 concurrent users

bundle_size:
  entry: main.js
  max_gzip_kb: 250
  measured_with: webpack-bundle-analyzer

mobile_fps:
  screen: SearchScreen
  min_fps: 60
  tool: Android Profiler

CI fails if any budget is exceeded. Performance is a feature — it regresses like any other feature.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.