Official agent skill

Django Perf Review

by getsentry in getsentry/skills

Django performance code review. An agent skill from getsentry/skills.

OfficialApache-2.0Auto-check: notesBackend & APIs

Install Django Perf Review

skills CLI
$ npx skills add getsentry/skills --skill django-perf-review -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install getsentry/skills django-perf-review --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/getsentry/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/django-perf-review .claude/skills/django-perf-review && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
django-perf-review
GitHub stars
1k
Used in
3 other repos
Token cost
~2.9k tokens
SKILL.md length
687 words
Files
2
Skills in repo
27
Repo updated
First seen
Licence
Apache-2.0

At a glance

Django performance code review. An agent skill from getsentry/skills.

  • Works in 4 steps: Research first - Trace data flow, check… → Validate before reporting - Pattern… → Zero findings is acceptable - Don't… → …
  • Asked to review Django performance
  • SKILL.md covers Review Approach, Impact Categories, Priority 1: N+1 Queries… and Priority 2: Unbounded…, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Django Perf Review is an agent skill from getsentry/skills, published by the product's own GitHub organization. Django performance code review. Use when asked to "review Django performance", "find N+1 queries", "optimize Django", "check queryset performance", "database performance", "Django ORM issues", or audit Django code for performance problems.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file.

It sits in Backend & APIs, covering Backend development. It works with Django. The repository describes itself as: Agent Skills used by the Sentry team for development. The licence is Apache-2.0.

When your agent uses it

  • Asked to review Django performance
  • Find N+1 queries
  • Optimize Django
  • Check queryset performance

Example prompts

  • “review Django performance”
  • “find N+1 queries”
  • “optimize Django”
  • “/django-perf-review”

Requirements

  • Python 3
  • Pre-approved tools (allowed-tools): Read, Grep, Glob, Bash, Task

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Research first - Trace data flow, check for existing optimizations, verify data volume
  2. Validate before reporting - Pattern matching is not validation
  3. Zero findings is acceptable - Don't manufacture issues to appear thorough
  4. Severity must match impact - If you catch yourself writing "minor" in a CRITICAL finding, it's not critical. Downgrade or skip it.

What it can do on your machine

Read from SKILL.md and the folder at commit d18b7aa. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Grep
    • Glob
    • Bash
    • Task

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python and markdown).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Django Perf Review loads about 2.9k tokens when it runs. Until then it costs about 65 tokens; SKILL.md has 687 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~65
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Read, Grep, Glob, Bash, Task

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from getsentry/skills at commit d18b7aa, republished under its Apache-2.0 licence (© getsentry). 687 words, ~2,852 tokens.

Download SKILL.mdSave it as .claude/skills/django-perf-review/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
django-perf-review
description
Django performance code review. Use when asked to "review Django performance", "find N+1 queries", "optimize Django", "check queryset performance", "database performance", "Django ORM issues", or audit Django code for performance problems.
allowed-tools
Read, Grep, Glob, Bash, Task
license
LICENSE

Django Performance Review

Review Django code for validated performance issues. Research the codebase to confirm issues before reporting. Report only what you can prove.

Review Approach

  1. Research first - Trace data flow, check for existing optimizations, verify data volume
  2. Validate before reporting - Pattern matching is not validation
  3. Zero findings is acceptable - Don't manufacture issues to appear thorough
  4. Severity must match impact - If you catch yourself writing "minor" in a CRITICAL finding, it's not critical. Downgrade or skip it.

Impact Categories

Issues are organized by impact. Focus on CRITICAL and HIGH - these cause real problems at scale.

PriorityCategoryImpact
1N+1 QueriesCRITICAL - Multiplies with data, causes timeouts
2Unbounded QuerysetsCRITICAL - Memory exhaustion, OOM kills
3Missing IndexesHIGH - Full table scans on large tables
4Write LoopsHIGH - Lock contention, slow requests
5Inefficient PatternsLOW - Rarely worth reporting

Priority 1: N+1 Queries (CRITICAL)

Impact: Each N+1 adds O(n) database round trips. 100 rows = 100 extra queries. 10,000 rows = timeout.

Validate by tracing: View → Queryset → Template/Serializer → Loop access

python
# PROBLEM: N+1 - each iteration queries profile
def user_list(request):
    users = User.objects.all()
    return render(request, 'users.html', {'users': users})

# Template:
# {% for user in users %}
#     {{ user.profile.bio }}  ← triggers query per user
# {% endfor %}

# SOLUTION: Prefetch in view
def user_list(request):
    users = User.objects.select_related('profile')
    return render(request, 'users.html', {'users': users})
Rule: Prefetch in serializers, not just views

DRF serializers accessing related fields cause N+1 if queryset isn't optimized.

python
# PROBLEM: SerializerMethodField queries per object
class UserSerializer(serializers.ModelSerializer):
    order_count = serializers.SerializerMethodField()

    def get_order_count(self, obj):
        return obj.orders.count()  # ← query per user

# SOLUTION: Annotate in viewset, access in serializer
class UserViewSet(viewsets.ModelViewSet):
    def get_queryset(self):
        return User.objects.annotate(order_count=Count('orders'))

class UserSerializer(serializers.ModelSerializer):
    order_count = serializers.IntegerField(read_only=True)
Rule: Model properties that query are dangerous in loops
python
# PROBLEM: Property triggers query when accessed
class User(models.Model):
    @property
    def recent_orders(self):
        return self.orders.filter(created__gte=last_week)[:5]

# Used in template loop = N+1

# SOLUTION: Use Prefetch with custom queryset, or annotate
Validation Checklist for N+1
  • Traced data flow from view to template/serializer
  • Confirmed related field is accessed inside a loop
  • Searched codebase for existing select_related/prefetch_related
  • Verified table has significant row count (1000+)
  • Confirmed this is a hot path (not admin, not rare action)

Priority 2: Unbounded Querysets (CRITICAL)

Impact: Loading entire tables exhausts memory. Large tables cause OOM kills and worker restarts.

Rule: Always paginate list endpoints
python
# PROBLEM: No pagination - loads all rows
class UserListView(ListView):
    model = User
    template_name = 'users.html'

# SOLUTION: Add pagination
class UserListView(ListView):
    model = User
    template_name = 'users.html'
    paginate_by = 25
Rule: Use iterator() for large batch processing
python
# PROBLEM: Loads all objects into memory at once
for user in User.objects.all():
    process(user)

# SOLUTION: Stream with iterator()
for user in User.objects.iterator(chunk_size=1000):
    process(user)
Rule: Never call list() on unbounded querysets
python
# PROBLEM: Forces full evaluation into memory
all_users = list(User.objects.all())

# SOLUTION: Keep as queryset, slice if needed
users = User.objects.all()[:100]
Validation Checklist for Unbounded Querysets
  • Table is large (10k+ rows) or will grow unbounded
  • No pagination class, paginate_by, or slicing
  • This runs on user-facing request (not background job with chunking)

Priority 3: Missing Indexes (HIGH)

Impact: Full table scans. Negligible on small tables, catastrophic on large ones.

Rule: Index fields used in WHERE clauses on large tables
python
# PROBLEM: Filtering on unindexed field
# User.objects.filter(email=email)  # full scan if no index

class User(models.Model):
    email = models.EmailField()  # ← no db_index

# SOLUTION: Add index
class User(models.Model):
    email = models.EmailField(db_index=True)
Rule: Index fields used in ORDER BY on large tables
python
# PROBLEM: Sorting requires full scan without index
Order.objects.order_by('-created')

# SOLUTION: Index the sort field
class Order(models.Model):
    created = models.DateTimeField(db_index=True)
Rule: Use composite indexes for common query patterns
python
class Order(models.Model):
    user = models.ForeignKey(User)
    status = models.CharField(max_length=20)
    created = models.DateTimeField()

    class Meta:
        indexes = [
            models.Index(fields=['user', 'status']),  # for filter(user=x, status=y)
            models.Index(fields=['status', '-created']),  # for filter(status=x).order_by('-created')
        ]
Validation Checklist for Missing Indexes
  • Table has 10k+ rows
  • Field is used in filter() or order_by() on hot path
  • Checked model - no db_index=True or Meta.indexes entry
  • Not a foreign key (already indexed automatically)

Priority 4: Write Loops (HIGH)

Impact: N database writes instead of 1. Lock contention. Slow requests.

Show full SKILL.md (276 more words)Show less
Rule: Use bulk_create instead of create() in loops
python
# PROBLEM: N inserts, N round trips
for item in items:
    Model.objects.create(name=item['name'])

# SOLUTION: Single bulk insert
Model.objects.bulk_create([
    Model(name=item['name']) for item in items
])
Rule: Use update() or bulk_update instead of save() in loops
python
# PROBLEM: N updates
for obj in queryset:
    obj.status = 'done'
    obj.save()

# SOLUTION A: Single UPDATE statement (same value for all)
queryset.update(status='done')

# SOLUTION B: bulk_update (different values)
for obj in objects:
    obj.status = compute_status(obj)
Model.objects.bulk_update(objects, ['status'], batch_size=500)
Rule: Use delete() on queryset, not in loops
python
# PROBLEM: N deletes
for obj in queryset:
    obj.delete()

# SOLUTION: Single DELETE
queryset.delete()
Validation Checklist for Write Loops
  • Loop iterates over 100+ items (or unbounded)
  • Each iteration calls create(), save(), or delete()
  • This runs on user-facing request (not one-time migration script)

Priority 5: Inefficient Patterns (LOW)

Rarely worth reporting. Include only as minor notes if you're already reporting real issues.

Pattern: count() vs exists()
python
# Slightly suboptimal
if queryset.count() > 0:
    do_thing()

# Marginally better
if queryset.exists():
    do_thing()

Usually skip - difference is <1ms in most cases.

Pattern: len(queryset) vs count()
python
# Fetches all rows to count
if len(queryset) > 0:  # bad if queryset not yet evaluated

# Single COUNT query
if queryset.count() > 0:

Only flag if queryset is large and not already evaluated.

Pattern: get() in small loops
python
# N queries, but if N is small (< 20), often fine
for id in ids:
    obj = Model.objects.get(id=id)

Only flag if loop is large or this is in a very hot path.


Validation Requirements

Before reporting ANY issue:

  1. Trace the data flow - Follow queryset from creation to consumption
  2. Search for existing optimizations - Grep for select_related, prefetch_related, pagination
  3. Verify data volume - Check if table is actually large
  4. Confirm hot path - Trace call sites, verify this runs frequently
  5. Rule out mitigations - Check for caching, rate limiting

If you cannot validate all steps, do not report.


Output Format

markdown
## Django Performance Review: [File/Component Name]

### Summary
Validated issues: X (Y Critical, Z High)

### Findings

#### [PERF-001] N+1 Query in UserListView (CRITICAL)
**Location:** `views.py:45`

**Issue:** Related field `profile` accessed in template loop without prefetch.

**Validation:**
- Traced: UserListView → users queryset → user_list.html → `{{ user.profile.bio }}` in loop
- Searched codebase: no select_related('profile') found
- User table: 50k+ rows (verified in admin)
- Hot path: linked from homepage navigation

**Evidence:**
```python
def get_queryset(self):
    return User.objects.filter(active=True)  # no select_related

Fix:

python
def get_queryset(self):
    return User.objects.filter(active=True).select_related('profile')

If no issues found: "No performance issues identified after reviewing [files] and validating [what you checked]."

**Before submitting, sanity check each finding:**
- Does the severity match the actual impact? ("Minor inefficiency" ≠ CRITICAL)
- Is this a real performance issue or just a style preference?
- Would fixing this measurably improve performance?

If the answer to any is "no" - remove the finding.

---

## What NOT to Report

- Test files
- Admin-only views
- Management commands
- Migration files
- One-time scripts
- Code behind disabled feature flags
- Tables with <1000 rows that won't grow
- Patterns in cold paths (rarely executed code)
- Micro-optimizations (exists vs count, only/defer without evidence)

### False Positives to Avoid

**Queryset variable assignment is not an issue:**
```python
# This is FINE - no performance difference
projects_qs = Project.objects.filter(org=org)
projects = list(projects_qs)

# vs this - identical performance
projects = list(Project.objects.filter(org=org))

Querysets are lazy. Assigning to a variable doesn't execute anything.

Single query patterns are not N+1:

python
# This is ONE query, not N+1
projects = list(Project.objects.filter(org=org))

N+1 requires a loop that triggers additional queries. A single list() call is fine.

Missing select_related on single object fetch is not N+1:

python
# This is 2 queries, not N+1 - report as LOW at most
state = AutofixState.objects.filter(pr_id=pr_id).first()
project_id = state.request.project_id  # second query

N+1 requires a loop. A single object doing 2 queries instead of 1 can be reported as LOW if relevant, but never as CRITICAL/HIGH.

Style preferences are not performance issues: If your only suggestion is "combine these two lines" or "rename this variable" - that's style, not performance. Don't report it.

© getsentry, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in skills/django-perf-review of getsentry/skills.

  • SKILL.md
  • LICENSE

Open the folder on GitHubat commit d18b7aa

Used in 3 other repositories

We found 12 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 3 other GitHub owners. This page covers the copy in getsentry/skills, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Django Perf Review next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Django Perf Review compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Django Perf Review this skillgetsentry/skills1k3 repos~2.9kAutomated safety check: NotesApache-2.0
Saleor Django Schema Migrationsaleor/saleor23k—~1kAutomated safety check: PassBSD-3-Clause
Silk Profilerbaserow/baserow6.1k—~2.9kAutomated safety check: PassCustom licence
Arch Wikiahmedemad3/arch-wiki250—~5.1kAutomated safety check: PassNone
Run Testsnetboxlabs/netbox-branching155—~1.2kAutomated safety check: PassCustom licence
Add Management Commandaropan/clist439—~848Automated safety check: PassApache-2.0

Similar skills

  • Generates and splits Django schema migrations for Saleor with manage.py makemigrations, enforcing one new model or one field change per migration file.

    23k GitHub stars~1k tokensUpdated today
    Backend & APIsAuto-check passed
  • Silk Profiler

    baserow/baserow

    Investigate backend performance using Django Silk profiling data.

    6.1k GitHub stars~2.9k tokensUpdated today
    Backend & APIsAuto-check passed
  • Arch Wiki

    ahmedemad3/arch-wiki

    Scans any project codebase for new/changed modules, endpoints, middleware, infrastructure, Docker topologies, SQL queries, or permissions and updates docs/architecture/architecture.json.

    250 GitHub stars~5.1k tokensUpdated 21 days ago
    Backend & APIsAuto-check passed
  • Run Tests

    netboxlabs/netbox-branching

    Run the netboxbranching plugin's Django test suite against a local NetBox checkout.

    155 GitHub stars~1.2k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Add or change a CLIST Django management command, including arguments, resource selection, EventLog monitoring, or cron and Healthchecks wiring.

    439 GitHub stars~848 tokensUpdated 5 days ago
    Backend & APIsAuto-check passed
  • Django Run Locally

    fossasia/eventyay

    Steps for initiating the Django development server without Docker

    1.7k GitHub stars~411 tokensUpdated today
    Backend & APIsAuto-check passed

More from getsentry/skills

All 27 skills in this repo
  • Skill Scanner

    getsentry/skills

    Official

    Scan agent skills for security issues. An agent skill from getsentry/skills.

    1k GitHub starsUsed in 4 repos~2.5k tokens
    Auto-check: warnings
  • Gh Review Requests

    getsentry/skills

    Official

    Fetch unread GitHub notifications for open PRs where review is requested from a specified team or opened by a team member.

    1k GitHub starsUsed in 3 repos~621 tokens
    Auto-check: notes
  • Security Review

    getsentry/skills

    Official

    Security code review for vulnerabilities. An agent skill from getsentry/skills.

    1k GitHub starsUsed in 4 repos~2.9k tokens
    Auto-check: notes
  • Skill Writer

    getsentry/skills

    Official

    Create, synthesize, and iteratively improve agent skills following the Agent Skills specification.

    1k GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Django Access Review

    getsentry/skills

    Official

    Django access control and IDOR security review. An agent skill from getsentry/skills.

    1k GitHub starsUsed in 3 repos~2.6k tokens
    Auto-check: notes
  • Gha Security Review

    getsentry/skills

    Official

    GitHub Actions security review for workflow exploitation vulnerabilities.

    1k GitHub starsUsed in 3 repos~2.2k tokens
    Auto-check: notes

Works with

Categories

Questions about Django Perf Review

What does Django Perf Review do?

Django performance code review. An agent skill from getsentry/skills. Django Perf Review is an agent skill from getsentry/skills, published by the product's own GitHub organization. Django performance code review.

When should I use Django Perf Review?

Django Perf Review fits situations like: asked to review Django performance; find N+1 queries; optimize Django; check queryset performance.

How do I install Django Perf Review in Claude Code?

Run `npx skills add getsentry/skills --skill django-perf-review -a claude-code`. Or copy the skill folder (skills/django-perf-review in getsentry/skills) into .claude/skills/django-perf-review in your project. Claude Code loads it when a task matches its description.

How do I install Django Perf Review in Codex?

Run `npx skills add getsentry/skills --skill django-perf-review -a codex`. Or copy the skill folder (skills/django-perf-review in getsentry/skills) into .agents/skills/django-perf-review in your project. Codex loads it when a task matches its description.

Can I use Django Perf Review in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add getsentry/skills --skill django-perf-review -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/django-perf-review, .gemini/skills/django-perf-review, .github/skills/django-perf-review and .opencode/skills/django-perf-review in your project.

What does Django Perf Review need to run?

SKILL.md names no scripts, command-line tools or credentials: Django Perf Review is instructions for the agent only. Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Grep, Glob, Bash, Task.

Does Django Perf Review access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Django Perf Review safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Django Perf Review use?

Django Perf Review is published under the Apache-2.0 licence (from the LICENSE file in the skill folder). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Django Perf Review use?

About 2.9k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Django Perf Review?

Skills that share tags, products or a category with Django Perf Review: Saleor Django Schema Migration (saleor/saleor, 23k stars), Silk Profiler (baserow/baserow, 6.1k stars), Arch Wiki (ahmedemad3/arch-wiki, 250 stars) and Run Tests (netboxlabs/netbox-branching, 155 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Django Perf Review?

getsentry (a GitHub organization, an official publisher) maintains it in getsentry/skills, which has 1,045 GitHub stars. The repository holds 27 skills in this directory. The repository was last updated on October 9, 2026.

Source: getsentry/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.