mitodl/agent-kit/drf-api-performance
Claude Code and agent skill by mitodl/agent-kit
- community
Checking that the SKILL.md file is still in the repository.
Write and review fast Django REST Framework APIs. Use this skill when adding or changing a DRF viewset, serializer, pagination class, or queryset - covers response nesting limits, paginating list endpoints and keeping the count query cheap, select_related vs prefetch_related vs django-prefetch, keeping ORM queries out of serializers, required_prefetches, and catching N+1s with django-zeal, django_assert_num_queries, and drf-lint.
Install
npx vskill@latest install mitodl/agent-kit/drf-api-performanceSKILL.md
Performant DRF APIs
A fast API is two problems: the shape of the response, and the cost of the queries that fill it. These rules apply to every DRF viewset, serializer, and queryset.
The rules
- Keep response nesting to two levels or less; split deeper data into a second endpoint.
- Paginate every list endpoint. Set the default once in a shared module, cap
client-supplied page size with max_limit, and order deterministically.
- Narrow the pagination count query to the primary key. It is a second query
over your whole result set, and it scales with production data, not fixtures.
- Pick the narrowest prefetch tool that works:
select_related()for foreign
keys, prefetch_related() for to-many relationships, prefetch() for data the model has no direct relationship to.
- Use
select_related(), notprefetch_related(), when the queryset **already
filters or orders on that table** - the join is happening either way.
- Three or four to-one joins are fine; treat eight as the review threshold
where you check EXPLAIN and split the query instead of widening it further.
- **Never query inside a serializer or call a function directly or indirectly
that makes one** - the body runs once per object, so a query there is multiplied by the page size. The view's queryset assembles the data.
- Declare
required_prefetcheson every serializer. It fails loudly under
DEBUG and pytest; in production it only logs, so treat it as a development guardrail and not a reason to skip the prefetch.
- Back a prefetch with a same-named `cached_property` so non-API callers get
the same answer without a second implementation.
- Test list APIs with 5-10 records at each level, or the N+1 checks won't fire.
- Pin a constant query count across varying data with
django_assert_num_queries, and never add skip_nplusone_check to a new test.
References
| Read this | For | |
|---|---|---|
| response-shape.md | The two-level nesting rule, worked normalization example, the extra-round-trip trade-off | |
| pagination.md | DefaultPagination in a shared module, DEFAULT_PAGINATION_CLASS, the three legitimate per-view overrides, class comparison, why the count query gets expensive, .only() vs .values() (and when .only() raises), widening count_fields | |
| prefetching.md | Tool comparison, the already-joined exception, writing a prefetch() prefetcher and its footguns, composite keys, the cached_property shadowing pattern and the hasattr antipattern | |
| joins-and-query-plans.md | Width vs multiplication, when table size enters the plan, Postgres planner thresholds, reading EXPLAIN (ANALYZE, BUFFERS), getting the SQL out of Django | |
| serializers.md | The SerializerMethodField N+1, the full "move it to the queryset" table, BaseSerializer and required_prefetches, and why it only raises outside production | |
| testing-and-lint.md | django-zeal setup and scoped exemptions, django_assert_num_queries vs django_assert_max_num_queries, drf-lint's ORM001/ORM002 and its baseline |
Resources
- Write Performant APIs - the handbook page this skill is drawn from
- 2026-03-24 MIT Learn outage post-mortem - what an expensive count query costs in production
- django-prefetch, django-zeal, mitol-drf-lint
- DRF: Pagination, Django: `prefetch_related()`, Django: `Prefetch` objects, Django: `cached_property`
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/python/drf-api-performance/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/mitodl/agent-kit/drf-api-performance)