plain-optimize
Automates performance trace analysis to identify slow database queries and N+1 issues.
Install
mkdir -p .claude/skills/plain-optimize && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6072" && unzip -o skill.zip -d .claude/skills/plain-optimize && rm skill.zipInstalls to .claude/skills/plain-optimize
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Captures and analyzes performance traces to identify slow queries and N+1 problems. Use when a page is slow, there are too many queries, or the user asks about performance.Key capabilities
- →Capture performance traces
- →Analyze query counts
- →Identify N+1 problems
- →Verify index effectiveness
How it works
It captures OpenTelemetry spans and analyzes them for duplicate queries and slow database operations.
Inputs & outputs
When to use plain-optimize
- →Identify N+1 query issues
- →Debug slow API responses
- →Verify database index effectiveness
About this skill
Performance Optimization Workflow
1. Capture and Analyze
Make a request and get structured JSON — response metadata plus a full trace analysis:
uv run plain request /path --json
uv run plain request /path --json --user 1
uv run plain request /path --json --method POST --data '{"key": "value"}'
The --user flag accepts a user ID or email.
traces is normally a list — one entry per request, so a followed redirect chain returns one per hop in hop order. Analyze each on its own; the last entry is the page that actually rendered. Never sum counts across hops: a query the framework runs once per request would look like a repeat that no change can fix.
Check trace_note before indexing. traces is null when the OpenTelemetry SDK isn't installed and [] when nothing was captured; in both cases a trace_note sibling key says why. Report that instead of indexing into nothing.
A failed request returns a different shape. If the view raised, the command exits 1 and emits {"error": "...", "traces": [...]} — no response key. The trace is still there, and analysis.exceptions carries the stacktrace, so this is the payload to read when debugging a 500. Branch on "response" in payload before reaching for it.
Each entry has name (e.g. GET /admin/p/user, including any query string) and request_id — which matches response.request_id for the hop that rendered — plus analysis (derived) and spans (raw):
analysis.query_count— statements executed in this requestanalysis.transaction_count— transaction-control statements, counted apart from queries. Withplain.postgresthis is savepoint bookkeeping;BEGIN/COMMITare issued outside the instrumented cursor and never appearanalysis.duration_ms— that request's durationanalysis.exceptions— exceptions recorded on any span, withspan,error_type,message,stacktraceanalysis.queries— each distinct statement withcount,total_duration_ms, andsources, slowest firstsources— the call sites that issued the statement, aspath:line in functionstrings. The path says whose code it is: project paths vs installed-package (site-packages) pathsspans— raw OpenTelemetry spans, a flat list (parent_span_idgives the structure)
count means one thing: how many times that statement ran in that request. Nothing is pre-diagnosed.
2. Identify Bottlenecks
You do the diagnosing. The trace reports what ran; deciding what is wrong with it is the job. Read analysis.queries and look for:
- Repeats —
count > 1is the N+1 shape. Go read the code at the recorded call sites before concluding: three executions from three branches is not the same as three from a loop, and only the source tells you which. A source is where the query executed, which for lazy querysets can be framework code (a paginator, a template render) even though project code built the queryset — a repeat with onlysite-packagessources still usually traces back to a queryset the project constructed. - Slow statements — high
total_duration_ms. A single slow query outranks a dozen fast repeats. - Cost the counts don't show —
duration_msfar exceeding the sum of query time means the time went somewhere else; readspansfor it. - Missing indexes, unnecessary work in hot paths.
Never sum counts across hops — a query the framework runs once per request would look like a repeat that no change can fix.
3. Apply Fixes
- Add
select_related()/prefetch_related()for N+1 - Add database indexes for slow queries
- Cache expensive computations
4. Verify Improvement
Re-run uv run plain request /path --json and compare analysis.query_count, the count on the statement you changed, and analysis.duration_ms for the same trace — match traces by name, not position, since a fix can change the redirect chain.
When not to use it
- →When database access is not the bottleneck
Prerequisites
Limitations
- →Requires Plain framework
- →Analysis depends on trace quality
How it compares
It provides structured analysis of query counts and durations rather than raw logs.
Compared to similar skills
plain-optimize side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| plain-optimize (this skill) | 1 | 2mo | No flags | Intermediate |
| supabase-advanced-troubleshooting | 1 | 27d | Caution | Advanced |
| sql-optimization-patterns | 64 | 2mo | No flags | Advanced |
| supabase-postgres-best-practices | 4 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by dropseed
View all by dropseed →You might also like
supabase-advanced-troubleshooting
jeremylongshore
Execute apply Supabase advanced debugging techniques for hard-to-diagnose issues. Use when standard troubleshooting fails, investigating complex race conditions, or preparing evidence bundles for Supabase support escalation. Trigger with phrases like "supabase hard bug", "supabase mystery error", "supabase impossible to debug", "difficult supabase issue", "supabase deep debug".
sql-optimization-patterns
wshobson
Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries. Use when debugging slow queries, designing database schemas, or optimizing application performance.
supabase-postgres-best-practices
davila7
Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.
supabase-performance-tuning
jeremylongshore
Optimize Supabase API performance with caching, batching, and connection pooling. Use when experiencing slow API responses, implementing caching strategies, or optimizing request throughput for Supabase integrations. Trigger with phrases like "supabase performance", "optimize supabase", "supabase latency", "supabase caching", "supabase slow", "supabase batch".
analyzing-query-performance
jeremylongshore
Execute use when you need to work with query optimization. This skill provides query performance analysis with comprehensive guidance and automation. Trigger with phrases like "optimize queries", "analyze performance", or "improve query speed".
find-hypertable-candidates
timescale
Use this skill to analyze an existing PostgreSQL database and identify which tables should be converted to Timescale/TimescaleDB hypertables. **Trigger when user asks to:** - Analyze database tables for hypertable conversion potential - Identify time-series or event tables in an existing schema - Evaluate if a table would benefit from Timescale/TimescaleDB - Audit PostgreSQL tables for migration to Timescale/TimescaleDB/TigerData - Score or rank tables for hypertable candidacy **Keywords:** hypertable candidate, table analysis, migration assessment, Timescale, TimescaleDB, time-series detection, insert-heavy tables, event logs, audit tables Provides SQL queries to analyze table statistics, index patterns, and query patterns. Includes scoring criteria (8+ points = good candidate) and pattern recognition for IoT, events, transactions, and sequential data.