Skill

Review Django Code for Performance Bottlenecks

Django Performance Review finds only validated N+1, unbounded queryset, and index issues - zero findings is an acceptable result.


81
Spark score
out of 100
Updated last month
Version 1.0.0

Add to Favorites

Why it matters

Identify and report critical performance issues in your Django applications, focusing on database-driven bottlenecks like N+1 queries, unbounded querysets, and missing indexes. Ensure findings are validated and actionable.

Outcomes

What it gets done

01

Analyze Django ORM and query patterns for performance regressions.

02

Validate identified issues with data flow tracing and codebase research.

03

Report findings categorized by impact (CRITICAL, HIGH, LOW).

04

Provide specific, provable performance optimizations.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-django-perf-review | bash

Overview

Django Performance Review

Reviews Django code for validated performance issues - N+1 queries, unbounded querysets, missing indexes, write loops - tracing data flow and checking data volume before reporting anything, with zero findings treated as an acceptable outcome. Use for a Django performance pass focused on verified ORM/query bottlenecks on hot paths - not for style preferences, admin views, migrations, or small tables.

What it does

Django Performance Review audits Django code for provable performance issues - N+1 queries, unbounded querysets, missing indexes, and other database-driven bottlenecks - and reports only what can be validated, not speculative optimization advice. Its review approach is: research first (trace data flow, check for existing optimizations, verify data volume), validate before reporting (pattern matching alone is not validation), accept zero findings rather than manufacturing issues, and make severity match actual impact (if a finding reads "minor" but is tagged CRITICAL, downgrade or drop it).

Issues are triaged into five priorities. N+1 queries (CRITICAL) multiply with data - 100 rows means 100 extra queries, 10,000 rows means a timeout - and are validated by tracing view to queryset to template/serializer to loop access; fixes use select_related/prefetch_related, queryset annotation instead of a SerializerMethodField that queries per object, or avoiding model properties that trigger a query when accessed inside a loop. Unbounded querysets (CRITICAL) exhaust memory and cause OOM kills; fixes are pagination on list endpoints, iterator(chunk_size=...) for large batch processing, and never calling list() on an unbounded queryset. Missing indexes (HIGH) cause full table scans on large tables; fixes add db_index=True or Meta.indexes (including composite indexes) for fields used in filter() or order_by(). Write loops (HIGH) turn N writes into N round trips with lock contention; fixes are bulk_create(), queryset.update()/bulk_update(), and queryset.delete() instead of per-object create()/save()/delete() in a loop. Inefficient patterns like count() vs exists() or get() in small loops are LOW priority and rarely worth reporting.

Each priority ships its own validation checklist - for example N+1 requires confirming the related field is accessed inside a loop, no existing select_related/prefetch_related covers it, the table has 1000+ rows, and the code path is actually hot (not admin, not a rare action). Before reporting any issue at all, five steps must all be validated: trace the data flow, search for existing optimizations, verify data volume, confirm it's a hot path, and rule out mitigations like caching or rate limiting - if any step can't be validated, the issue is not reported.

Findings use a structured format ([PERF-001] style with location, issue, validation steps performed, code evidence, and a concrete fix) and a summary count of validated issues by severity; if nothing is found, the skill states plainly what was reviewed and what was checked rather than inventing a finding. It also documents explicit false positives to avoid: lazy queryset variable assignment causes no extra query, a single list() call is one query and not N+1, a single object doing two queries (not inside a loop) is at most a LOW finding, and pure style preferences are never reported as performance issues. Out of scope entirely: test files, admin-only views, management commands, migrations, one-time scripts, disabled-feature-flag code, tables under 1000 rows that won't grow, cold paths, and micro-optimizations without evidence.

When to use - and when NOT to

Use this skill when a Django performance review is needed that focuses on verified ORM and query issues - when code likely has N+1 queries, unbounded querysets, missing indexes, or other database-driven bottlenecks, and only provable findings are wanted rather than speculative advice. Do not treat the output as a substitute for environment-specific validation, testing, or expert review, and stop to ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.

Who it's for

Django and DRF backend engineers doing performance-focused code review who want evidence-backed findings with concrete fixes - not a generic style pass or a list of theoretical inefficiencies.

FAQ

Common questions

Discussion

Questions & comments ยท 0

Sign In Sign in to leave a comment.