perf-budget — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited perf-budget (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Performance work starts with a number and a measurement, not a hunch. Set a budget, profile the real workload, fix the dominant cost, measure again, and add a guard so regression can't sneak back. Optimizing the wrong layer — micro-tuning a cold path while N+1 queries dominate — wastes effort and adds complexity.
A perf budget is an explicit target: p95 latency, bundle kilobytes, query time, memory ceiling. Without one, "faster" is unmeasurable and every optimization is premature.
Run the performance checklist alongside this process for common traps — only after you've confirmed the path is hot. Pair with [[observability]] for production numbers, [[data-modeling]] for query/index work, [[caching-strategy]] only after read cost is measured, [[react-patterns]] for React/Next.js specifics, and [[browser-checks]] for perceived slowness in the UI.
Skip micro-optimization on cold paths, one-time setup, or code with no user-facing latency impact. Don't demand perf work on every PR — apply when the path is hot or the budget is at risk.
Not a substitute for [[caching-strategy]] — measure first; cache only when read cost justifies it.
Work in order. No code changes until you have a baseline number.
Write the target before profiling:
| Surface | Example budgets |
|---|---|
| API | p95 < 200ms, p99 < 500ms for POST /orders |
| Page | LCP < 2.5s, TTI < 3s on 4G ([[browser-checks]]) |
| Query | < 50ms p95 at 10M rows; examines < 1% of table |
| Job | Process 10k msgs/min; p95 handle < 2s |
| Bundle | Main chunk < 200KB gzip; route chunk < 80KB |
| Memory | Worker steady < 512MB under peak load |
Include:
Align with SLOs in [[observability]] — perf budgets feed alerts and error budgets.
Bad: "Checkout should be fast"
Good: "POST /orders p95 < 500ms at 100 RPS, prod-like cart (20 items)"Prefer production or prod-like measurements ([[observability]]):
EXPLAIN ANALYZE on realistic volume ([[data-modeling]])Profile the dominant path:
| Layer | Tools / signals |
|---|---|
| Backend | Trace waterfall, CPU profiler, flame graph |
| Database | Query plan, rows examined vs returned, lock wait |
| Frontend | Network waterfall, React profiler, bundle analyzer |
| Batch | Per-stage timing, queue lag |
Record baseline numbers in the ticket/PR — you'll need them for after.
Intuition is wrong — the slow function you remember is often 2% of request time; one unindexed query or serial await chain is the real killer.
Ask: what single change would move the budget most?
Rank costs from profile/trace:
POST /orders p95 840ms breakdown (example):
payment API 520ms ← dominant
DB insert 45ms
tax calculation 12ms
JSON serialize 3msFix payment first — not JSON. Shaving 1ms off serialize when payment is 520ms is waste.
Hot path check — does this code run per request at scale? One-off admin export ≠ checkout API.
If multiple similar costs, fix the easiest high-impact first — sometimes parallelizing two 200ms calls beats optimizing one 50ms call.
Priority order (stop when budget met):
| Priority | Win | Skills |
|---|---|---|
| 1 | Remove N+1; batch/join queries | [[data-modeling]] |
| 2 | Add/fix indexes for real query patterns | [[data-modeling]] |
| 3 | Parallelize independent I/O; kill waterfalls | [[react-patterns]] |
| 4 | Paginate/limit unbounded work | [[data-modeling]] |
| 5 | Algorithm fix — O(n²) → O(n), better structure | [[simplify]] |
| 6 | Cache expensive measured reads | [[caching-strategy]] |
| 7 | Lazy load / split bundle | [[react-patterns]] |
| 8 | Micro-tune hot loop | Only with profiler proof |
Caching last among structural options — confirm read cost on hot path first ([[caching-strategy]]). A better query often removes the need entirely.
One change at a time when validating — or isolate in benchmark — so you know what moved the number ([[fault-recovery]] discipline).
After each meaningful change:
Before: p95 840ms | After: p95 310ms | Budget: 500ms ✓If the number didn't move — revert the change unless it bought clarity or mandatory fix. Don't keep "optimizations" that profiler can't justify.
Document before/after in PR — reviewers and future-you need proof.
Every perf win can cost something — name it:
| Optimization | Trade-off |
|---|---|
| Cache | Staleness, invalidation bugs ([[caching-strategy]]) |
| Parallelism | Connection pool pressure, harder debugging |
| Denormalization | Write complexity, consistency ([[data-modeling]]) |
| Aggressive bundling | Cacheability, deploy granularity |
| Lower sampling | Less observability detail |
Spend complexity only where measurement shows user-visible gain. A 5ms win on a 2s page isn't worth opaque code.
Lock the win:
| Guard | When |
|---|---|
| Benchmark in CI | Critical pure logic; threshold assert |
| Bundle size budget | Frontend CI fails if chunk grows > X KB |
| Load test gate | Release pipeline p95 check ([[pipeline-ops]]) |
| SLO alert | Production p95 regression ([[observability]]) |
| Query plan check | EXPLAIN in test on representative query |
Guards should match the same metric you optimized — not a different proxy that drifts.
Re-baseline when workload changes — budgets aren't forever.
Slow API endpoint
Trace → rank spans → N+1 / missing index / external call → fix dominant → re-trace → SLO alert.
Slow SQL
EXPLAIN ANALYZE on prod stats → rows examined → index or rewrite → measure at volume ([[data-modeling]]).
Slow page load
Network waterfall → LCP element → bundle size + critical path → lazy load / server fetch parallel ([[react-patterns]], [[browser-checks]]).
Slow React interaction
Profiler → unnecessary re-renders vs expensive render → fix render or defer work → 60fps input check.
Background job behind
Queue depth + per-message timing → slow handler step → batch DB writes → throughput metric.
"Feels slow" user report
Reproduce with trace → compare p95 vs p50 (tail issue?) → [[browser-checks]] on real device/network.
Pre-launch perf pass ([[launch-readiness]])
Define budget → load test staging → fix blockers → dashboard + alert before 100% ramp.
Ship the feature; measure in prod; optimize what prod proves is slow ([[observability]]).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.