agentleFS
CODE-SAURABHCODE-SAURABH/OpenSkills/performance-optimizer/SKILL.md

performance-optimizer

Skill2 starsChanged 4 months agoMITView on GitHub

Expert performance analysis and optimization guidance. Use when the user asks about frontend optimization, API latency, database optimization, memory leaks, CPU bottlenecks, or profiling.

17 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use observability-engineer, security-auditor and 4 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • xfstudioSkill

    observability-engineer

    Build production-ready monitoring, logging, and tracing systems.

    Also in 3 projects that use this

  • nahisahoSkill

    security-auditor

    security-auditor skill

    Also in 5 projects that use this

  • lodetomasiSkill

    database-optimizer

    Database performance optimization: N+1 detection, query analysis, indexing, and ORM tuning

    Also in 3 projects that use this

  • AutumnsGroveSkill

    api-designer

    Design and document RESTful and GraphQL APIs with OpenAPI/Swagger specifications, authentication patterns, versioning strategies, and best practices. Use for: (1) Creating API specifications, (2) Designing REST endpoints, (3) GraphQL schema design, (4) API authentication and authorization, (5) API versioning strategies, (6) Documentation generation

    Also in 3 projects that use this

  • xenitV1Skill

    clean-code

    Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

    Also in 3 projects that use this

  • OpenAISkill

    test-driven-development

    Use when implementing any feature or bugfix, before writing implementation code

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. 0 are common, 11 are distinctive, and 8 are very specific to this project.

  • 0

    Common

    Most of the 13 edited versions we read keep these.

  • 11

    Distinctive

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before touching any code:

    line 14
  2. Very specific:

    Use next/image or equivalent — automatic WebP, lazy loading, correct sizing

    line 53
  3. Distinctive:

    Use CSS sprites or SVG for icons — not dozens of small PNG requests

    line 55
  4. Distinctive:

    Avoid long tasks on the main thread (> 50ms) — they block user interaction

    line 59
  5. Distinctive:

    Avoid layout thrashing — batch DOM reads and writes.

    line 62
  6. Distinctive:

    Use a CDN for static assets — serve from the edge, not the origin

    line 69
  7. Distinctive:

    Look for: sequential calls that could be parallel, N+1 patterns, slow DB queries, unnecessary external calls

    line 78
  8. Distinctive:

    Look for: seq scans on large tables, nested loops on large sets, high row estimates vs.

    line 111
  9. Very specific:

    Add the appropriate index — verify with EXPLAIN ANALYZE that it is used

    line 112
  10. Very specific:

    Run ANALYZE if estimates are far off — statistics may be stale

    line 113
  11. Distinctive:

    Use covering indexes for hot read paths — include all columns the query needs to avoid heap fetches

    line 132
  12. Distinctive:

    Use partial indexes for sparse conditions — index only the subset of rows the query filters on

    line 133
  13. Distinctive:

    Never open a new DB connection per request — pool connections at the application layer (PgBouncer, SQLAlchemy pool, HikariCP)

    line 138
  14. Very specific:

    Avoid SELECT * — fetch only needed columns.

    line 143
  15. Very specific:

    Avoid OFFSET pagination at scale — use cursor-based pagination

    line 144
  16. Very specific:

    Avoid LIKE '%term%' on large tables — use full-text search indexes

    line 145
  17. Very specific:

    Use EXISTS instead of COUNT when checking existence — stops scanning after the first match

    line 146
  18. Very specific:

    Remove event listeners on cleanup — every addEventListener needs a corresponding removeEventListener on teardown

    line 169
  19. Distinctive:

    Read measurement-plan.md before collecting a baseline or interpreting a before/after performance result.

    line 197

“Common” is measured: kept by at least 6 in 10 of the 13 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Performance Optimization

Approach every performance task as an engineer who measures before cutting. Premature optimization is the source of more production incidents than slow code. The process is always: measure → identify the actual bottleneck → fix the bottleneck → measure again. Intuition about where the slowness is has a poor track record. Data does not.


Step 0: Measure First, Optimize Second

Before touching any code:

  1. Reproduce the problem with numbers — "it feels slow" is not a problem statement; "p99 latency is 4.2s under 100 concurrent users" is
  2. Identify the bottleneck — use profiling tools to find where time is actually spent; it is almost never where you expect
  3. Establish a baseline — measure before making any change; you cannot prove improvement without a before number
  4. Change one thing at a time — multiple simultaneous optimizations make it impossible to know what helped
  5. Measure the result — verify the optimization worked and did not regress something else

Optimization priority order:

  1. Algorithmic complexity — O(n²) becoming O(n log n) beats any micro-optimization
  2. I/O reduction — fewer DB queries, fewer HTTP calls, smaller payloads
  3. Caching — avoid recomputing or re-fetching what has not changed
  4. Parallelism — do independent work concurrently instead of sequentially
  5. Micro-optimization — only after the above have been exhausted

Frontend Performance

Measure with real tools:

  • Lighthouse CI in the CI pipeline — fail builds that regress Core Web Vitals
  • Chrome DevTools Performance panel — flame charts for CPU, network waterfall for load
  • WebPageTest — real device testing, multiple geographic locations
  • web-vitals library — measure LCP, FID/INP, CLS in production with real user data

Core Web Vitals targets:

  • LCP (Largest Contentful Paint) < 2.5s
  • INP (Interaction to Next Paint) < 200ms
  • CLS (Cumulative Layout Shift) < 0.1

Bundle size:

  • Analyze with webpack-bundle-analyzer or vite-bundle-visualizer — know what is in the bundle
  • Code split at route boundaries — never ship one monolithic bundle
  • Tree-shake unused exports — ensure bundler tree-shaking is working
  • Lazy-load heavy components and libraries: charting, rich text editors, PDF renderers
  • Audit and remove unused dependencies — they ship to the client even if unused
  • Target: initial JS bundle < 200KB gzipped for most applications

Images:

  • Use next/image or equivalent — automatic WebP, lazy loading, correct sizing
  • Specify width and height on every image — prevents layout shift
  • Use CSS sprites or SVG for icons — not dozens of small PNG requests
  • Compress images before serving — never serve raw camera images

JavaScript execution:

  • Avoid long tasks on the main thread (> 50ms) — they block user interaction
  • Move heavy computation to Web Workers
  • Debounce / throttle scroll, resize, and input event handlers
  • Avoid layout thrashing — batch DOM reads and writes; do not interleave them
  • React.memo, useMemo, useCallback only when profiling shows a measurable benefit — they add complexity and are commonly overused

Network:

  • HTTP/2 or HTTP/3 — multiplexing eliminates per-request connection overhead
  • Preconnect to critical third-party origins: <link rel="preconnect">
  • Preload critical assets: fonts, hero images, above-the-fold CSS
  • Use a CDN for static assets — serve from the edge, not the origin
  • Cache static assets aggressively with content-hashed filenames — main.abc123.js can be cached forever

API Latency

Find the bottleneck — use distributed tracing:

  • OpenTelemetry spans on every significant operation — DB query, external HTTP call, cache lookup, business logic
  • Look for: sequential calls that could be parallel, N+1 patterns, slow DB queries, unnecessary external calls

Common API latency culprits and fixes:

ProblemDiagnosisFix
N+1 queriesORM generates one query per item in a listEager load with joins or IN query
Missing indexEXPLAIN ANALYZE shows seq scanAdd targeted index
Synchronous external callsTrace shows sequential HTTP callsFan out with Promise.all / asyncio.gather
Oversized responseResponse payload is largePaginate; return only requested fields
No cachingSame data fetched on every requestCache at service or HTTP layer
Connection overheadNew DB connection per requestConnection pooling
Serialization overheadLarge object serialized repeatedlyCache serialized form

Response size matters:

  • Return only the fields the client needs — avoid SELECT * and avoid serializing entire domain objects to API responses
  • Compress responses with gzip or brotli — most frameworks enable this with one config line
  • Paginate — a response with 10,000 items is slow to serialize, transmit, and parse

Caching strategy:

  • Cache at the layer closest to the consumer
  • HTTP cache headers for public, stable content — Cache-Control: public, max-age=3600
  • Application cache (Redis) for: computed results, external API responses, expensive DB queries
  • Define invalidation before caching — stale data is a correctness bug, not just a performance issue
  • Cache hit rate is a metric — monitor it; a low hit rate means the cache is not helping

Database Performance

Slow query workflow:

  1. Enable slow query log — capture all queries above a threshold (e.g., > 100ms)
  2. EXPLAIN ANALYZE on the slow query — read the actual plan, not the estimated one
  3. Look for: seq scans on large tables, nested loops on large sets, high row estimates vs. actuals
  4. Add the appropriate index — verify with EXPLAIN ANALYZE that it is used
  5. Run ANALYZE if estimates are far off — statistics may be stale

N+1 query pattern:

# ❌ N+1 — one query for the list, one per item
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user_id)
for order in orders:
    items = db.query("SELECT * FROM order_items WHERE order_id = ?", order.id)

# ✅ Single query with join or IN clause
orders = db.query("""
    SELECT o.*, oi.*
    FROM orders o
    JOIN order_items oi ON oi.order_id = o.id
    WHERE o.user_id = ?
""", user_id)

Index effectiveness:

  • Use covering indexes for hot read paths — include all columns the query needs to avoid heap fetches
  • Use partial indexes for sparse conditions — index only the subset of rows the query filters on
  • Monitor index usage — drop indexes that are never used; they slow every write
  • Index bloat accumulates over time — REINDEX CONCURRENTLY periodically on heavily updated tables

Connection pooling:

  • Never open a new DB connection per request — pool connections at the application layer (PgBouncer, SQLAlchemy pool, HikariCP)
  • Monitor connection pool utilisation — exhausted pools queue requests and spike latency
  • Set pool size based on DB server capacity, not application concurrency

Query patterns:

  • Avoid SELECT * — fetch only needed columns; reduces data transfer and enables covering indexes
  • Avoid OFFSET pagination at scale — use cursor-based pagination
  • Avoid LIKE '%term%' on large tables — use full-text search indexes
  • Use EXISTS instead of COUNT when checking existence — stops scanning after the first match

Memory Leak Detection

Node.js:

  • Heap snapshots in Chrome DevTools — take two snapshots separated by a period of activity; compare retained objects
  • --inspect flag to attach Chrome DevTools to a Node process
  • Common sources: event listeners not removed, global state that accumulates, closures holding large objects, unbounded caches

Python:

  • tracemalloc — trace memory allocations to their source
  • memory_profiler — line-by-line memory usage
  • Common sources: growing lists/dicts never cleared, circular references (though Python GC handles most), large objects cached without eviction

General signals:

  • Steady memory growth that does not plateau — the hallmark of a leak
  • Memory growth correlated with request count — something is accumulating per request
  • Out-of-memory crashes on long-running processes

Prevention:

  • Bounded caches — LRU cache with a max size; unbounded caches are memory leaks
  • Remove event listeners on cleanup — every addEventListener needs a corresponding removeEventListener on teardown
  • Weak references for caches where eviction on GC is acceptable

CPU Bottlenecks

Profiling tools:

  • Node.js: --prof flag + node --prof-process; Chrome DevTools flame chart
  • Python: cProfile + snakeviz for visualisation; py-spy for sampling a live process without restart
  • Go: pprof

Common CPU bottlenecks:

  • Synchronous JSON serialization of large objects — consider streaming serialization or pre-serialization
  • Regular expression on large inputs — catastrophic backtracking on poorly written regex; test with ReDoS tools
  • Cryptographic operations on the request path — move to background workers if not latency-critical
  • Sorting large collections — O(n log n) on every request; cache sorted results
  • Unnecessary re-renders in React — profile with the React DevTools Profiler

Parallelism:

  • CPU-bound work in Node.js blocks the event loop — offload to worker threads or a separate process
  • Python GIL limits CPU parallelism in threads — use multiprocessing for CPU-bound work; async/threads for I/O-bound work
  • Horizontal scaling is not a substitute for fixing an O(n²) algorithm — fix the algorithm first

Bundled Reference

Read measurement-plan.md before collecting a baseline or interpreting a before/after performance result.

Definition of Done — Performance Work

  • Baseline measured before optimization with specific numbers
  • Bottleneck identified with profiling tools — not intuition
  • One change made at a time
  • Improvement verified against baseline with the same measurement method
  • No regressions in correctness, memory usage, or latency on other paths
  • Performance budget or SLO defined and monitored going forward
  • CI check added to prevent regression (Lighthouse CI, latency threshold test, or equivalent)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.