backend-db-performance
Skill9 starsChanged 42 days agoMITView on GitHub
Optimize slow queries, indexes, and N+1s. Use when "slow query", "database performance", "add an index", or "N+1". Schema consistency → audit-db-schema. RLS access control → plan-rls-audit.
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- kensaurus/skillsedited, first seen Oct 1, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- kensaurus/skills★ 950% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository165 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .cursor/rules/approved-plan-execution.mdcCursor rule
- .cursor/rules/skill-workflows.mdcCursor rule
- .cursor/rules/verification-before-completion.mdcCursor rule
- llms.txtllms.txt
- audit-accessibilitySkill
- audit-agent-speedSkill
- audit-analyticsSkill
- audit-auth-flowsSkill
- audit-backend-architectureSkill
- audit-bundle-sizeSkill
- audit-cicdSkill
- audit-codemod-safetySkill
- audit-code-qualitySkill
- audit-code-reviewSkill
- audit-db-schemaSkill
- audit-doctrineSkill
- audit-env-paritySkill
- audit-fe-apiSkill
- audit-gate-logicSkill
- audit-i18nSkill
- audit-infra-costSkill
- audit-langfuse-llmSkill
- audit-llm-securitySkill
- audit-monetization-iapSkill
- audit-payment-systemSkill
- audit-performanceSkill
- audit-realworldSkill
- audit-registry-listingSkill
- audit-resilienceSkill
- audit-responsiveSkill
- audit-securitySkill
- audit-skill-conflictsSkill
- audit-ui-statesSkill
- audit-uiux-design-systemSkill
- audit-ux-journeysSkill
- audit-uxSkill
- backend-error-handlingSkill
- backend-observabilitySkill
- backend-patternsSkill
- backend-realtimeSkill
- burndown-fullSkill
- complete-everythingSkill
- data-pipelineSkill
- data-visualizationSkill
- debug-errorSkill
- debug-fe-be-integrationSkill
- debug-sentry-monitorSkill
- deploy-npmSkill
- deploy-verifySkill
- design-apiSkill
- design-canvasSkill
- design-emailSkill
- design-frontendSkill
- design-generative-artSkill
- design-mobile-firstSkill
- design-motionSkill
- design-prdSkill
- design-systemSkill
- design-themeSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 68
Use get_advisors MCP tool for performance/security
- Distinctive: line 69
Don't re-fix already addressed issues
- Distinctive: line 134
All six index forms and the Prisma model: references/schema-and-indexes.md §Index types, §Prisma index syntax.
- Distinctive: line 165
Read performance is critical
- Very specific: line 194
Look for: Seq Scan (bad on large tables), Index Scan (good), Nested Loop (check for N+1), high actual time.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Database Optimization Skill
Degree of freedom: MIXED. Which query/index/N+1 to fix [HIGH freedom];
existing-index probes and EXPLAIN ANALYZE [LOW freedom — run exactly].
How to reason
- Observe — EXPLAIN ANALYZE /
pg_stat_statements/ existingpg_indexes - Interpret — seq scan vs N+1 vs over-fetch vs missing pagination
- Classify — add-index / eager-load / narrow-select / paginate / leave-alone
- Severity — write-path timeout outranks a 200ms list page
Worked example
Observe:
/feedp95 2.4s; Prisma logs 81 queries;pg_indexeshas noidx_posts_user_created. Interpret:findManyposts then per-rowuser.findUnique— N+1;ORDER BY created_atis a seq scan. Classify: eager-loadinclude: { author }+ composite index(user_id, created_at DESC). Verify: EXPLAIN ANALYZE → Index Scan; query count 2; p95 < 200ms. Did not add a duplicate index.
Self-critique before reporting
- Existing first — listed
pg_indexes/ migrations beforeCREATE INDEX - EXPLAIN — the claimed winner has ANALYZE output, not intuition
- No duplicate index — the proposed name was queried and absent
- Right owner — schema consistency →
audit-db-schema; RLS access →plan-rls-audit
Systematic approach to identifying and fixing database performance issues.
When to Use
- Slow page loads (database bottleneck)
- Query timeout errors
- N+1 queries
- Schema design review
- Index optimization
- Migration planning
Check existing first [LOW freedom — run exactly]
Before ANY optimization, verify current state:
- Check existing indexes:
SELECT indexname, indexdef FROM pg_indexes
WHERE schemaname = 'public' AND tablename = 'your_table';- Check existing migrations:
ls -la supabase/migrations/ | grep -i "index\|optim\|perf"- Check if index already exists:
SELECT 1 FROM pg_indexes WHERE indexname = 'your_proposed_index';- Check Supabase advisors for current issues:
- Use
get_advisorsMCP tool for performance/security - Don't re-fix already addressed issues
Why: Duplicate indexes waste storage and slow writes. Always verify before adding.
Performance Investigation [HIGH freedom]
1. Identify Slow Queries
- Prisma:
new PrismaClient({ log: [{ emit: 'event', level: 'query' }] })anddb.$on('query', ...); log anything over 100 ms with its duration. - Postgres/Supabase:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements, then order bytotal_time DESC, readingtotal_time / callsandrows / calls.
Logging snippet and the pg_stat_statements query: references/queries.md §Identify slow queries.
2. Common Performance Issues
| Issue | Symptom | Solution |
| N+1 Queries | Many small queries | Use include / eager load |
| Missing Index | Slow WHERE/JOIN | Add index on filtered columns |
| Full Table Scan | Slow on large tables | Add index, limit results |
| Over-fetching | Slow response | Select only needed fields |
| No Pagination | Memory issues | Add cursor/offset pagination |
N+1 Query Fix [HIGH freedom]
- Problem:
findManythen a per-rowfindUniquein a loop — 1 + N queries. - Fix: eager-load the relation; narrow it with a nested
selectso you do not over-fetch the join. - Supabase: one
.select('*, author:users(id, name, avatar)')call does the join.
// Good - 2 queries total
const posts = await db.post.findMany({
include: { author: { select: { id: true, name: true, avatar: true } } },
})Bad/good Prisma and the Supabase equivalent: references/queries.md §N+1 query fix.
Index Optimization [HIGH freedom]
When to Add Indexes
Add index when column is used in:
WHEREclauses (filtering)JOINconditionsORDER BYclauses- Unique constraints
Don't add index when:
- Table is small (< 1000 rows)
- Column has low cardinality (few unique values)
- Column is rarely queried
- Table has heavy writes
Index Types
- Single-column for one filter; composite when
WHERE a = ? ORDER BY b(column order matters: equality first, then sort). - Unique index for constraints; partial index (
WHERE published = true) for a hot subset; GIN for JSONB, arrays andto_tsvectorsearch. - Prisma:
@@index([userId, createdAt(sort: Desc)]),@@unique([...])mirror the SQL.
CREATE INDEX idx_posts_user_created ON posts(user_id, created_at DESC); -- composite, order matters
CREATE INDEX idx_posts_published ON posts(created_at) WHERE published = true; -- partialAll six index forms and the Prisma model: references/schema-and-indexes.md §Index types, §Prisma index syntax.
Query Optimization Patterns [HIGH freedom]
- Select only needed fields —
select: { id, name, email }instead of the whole row. - Pagination — offset (
skip/take) is fine for small pages; cursor (cursor: { id },skip: 1) for large or infinite lists; returnnextCursorfrom the last row. - Batch —
createMany({ skipDuplicates })instead of a create loop;$transaction([...])for related writes. - Count —
db.post.count({ where }); pair it with the page query inside one$transaction.
const posts = await db.post.findMany({
take: limit,
skip: cursor ? 1 : 0, // skip the cursor row itself
cursor: cursor ? { id: cursor } : undefined,
orderBy: { createdAt: 'desc' },
})
const nextCursor = posts.length === limit ? posts[posts.length - 1].id : nullSelect, both pagination styles, batching and count: references/queries.md §Select only needed fields through §Count optimization.
Schema Design Best Practices [HIGH freedom]
Normalization vs Denormalization
Normalize when:
- Data changes frequently
- Data integrity is critical
- Storage is a concern
Denormalize when:
- Read performance is critical
- Data rarely changes
- Complex joins are slow
- Normalized: a
post_stats(post_id PK → posts, view_count, like_count)table; denormalized: counters as columns onposts. - Data types —
UUIDids,VARCHAR(n)for bounded strings,DECIMAL(10,2)for money,TIMESTAMPTZalways,ENUMfor fixed sets. - Soft deletes — nullable
deletedAtwith@@index([deletedAt]); every read filtersdeletedAt: null.
SQL for both shapes, the data-type list and the soft-delete model: references/schema-and-indexes.md §Normalization, §Efficient data types, §Soft deletes.
Supabase-Specific Optimizations [HIGH freedom]
- RLS — a function call or sub-select per row (
get_user_team()) is slow; preferuser_id = auth.uid(), or anEXISTSjoin against the membership table when the rule needs it. - Edge Functions — move multi-query aggregations into one
supabase.rpc('get_dashboard_stats')call behindDeno.serveinstead of several client round trips.
CREATE POLICY "fast_policy" ON posts FOR SELECT USING (user_id = auth.uid());Slow/fast/join policies and the Edge Function: references/schema-and-indexes.md §RLS performance, §Edge Functions.
Query Analysis [LOW freedom — run exactly]
EXPLAIN ANALYZE
EXPLAIN ANALYZE SELECT * FROM posts WHERE user_id = 'abc123' ORDER BY created_at DESC LIMIT 20;Look for: Seq Scan (bad on large tables), Index Scan (good), Nested Loop (check for N+1), high actual time. Annotated version: references/queries.md §EXPLAIN ANALYZE.
Key Metrics
| Metric | Target | Action if Exceeded |
| Query time | < 100ms | Add index, optimize |
| Rows scanned | < 10x returned | Add index |
| Memory usage | < 256MB | Add LIMIT, pagination |
| Connection count | < pool size | Use connection pooling |
Optimization Checklist [LOW freedom — do not skip]
- Queries logged and monitored
- Indexes on filtered/joined columns
- No N+1 queries (eager loading)
- Pagination on all list endpoints
- Select only needed fields
- Batch operations where possible
- Connection pooling configured
- RLS policies optimized
- EXPLAIN ANALYZE on slow queries
- Appropriate data types used
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
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.

