Agent skill

Django Filter Benchmark

by saleor in saleor/saleor

Benchmarks Django ORM filters in Saleor by generating bulk data, extracting the SQL and running EXPLAIN ANALYZE to check index usage.

BSD-3-ClauseAuto-check passedDatabases

Install Django Filter Benchmark

skills CLI
$ npx skills add saleor/saleor --skill filter-benchmark -a claude-code

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

GitHub CLI
$ gh skill install saleor/saleor filter-benchmark --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/saleor/saleor.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/filter-benchmark .claude/skills/filter-benchmark && 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
filter-benchmark
GitHub stars
23k
Token cost
~2.3k tokens
SKILL.md length
854 words
Files
2
Skills in repo
8
Repo updated
First seen
Licence
BSD-3-Clause

At a glance

Benchmarks Django ORM filters in Saleor by generating bulk data, extracting the SQL and running EXPLAIN ANALYZE to check index usage.

  • Works in 6 steps: Identify what to benchmark → Generate bulk data script → Populate the database → …
  • Testing a new or changed filter on a large dataset
  • SKILL.md covers Overview, Step 1: Identify what to…, Step 2: Generate bulk data… and Step 3: Populate the database, plus 3 more sections
  • Runs Python scripts from its folder; calls python and make

What it does

The skill is a six-step workflow for performance-testing filters in the Saleor GraphQL layer: identify the filter with its fields, joins and existing indexes, generate a bulk data script, populate through the Django shell to reach over 100k rows, extract the SQL the ORM produces, run EXPLAIN ANALYZE to spot sequential scans and missing indexes, and report findings with concrete fixes such as new indexes or query rewrites.

The data script uses bulk_create with ignore_conflicts, works in batches of 1000-5000 objects, varies field values so the planner sees a realistic distribution, spreads dates over a wide range, covers all enum values and creates minimal parent objects for required foreign keys. The filters being tested live in saleor/graphql app folders, and a helper script, analyze_query.py, is included.

When your agent uses it

  • Testing a new or changed filter on a large dataset
  • Checking whether a filter makes use of an index
  • Generating bulk test data for performance testing
  • Running EXPLAIN ANALYZE on a queryset filter

Example prompts

  • “Benchmark the new transaction event filter on a few hundred thousand rows.”
  • “Run EXPLAIN ANALYZE on this order filter and tell me whether the index is used.”
  • “Generate 100k rows of varied checkout data so I can test the filter.”

Requirements

  • A working Saleor checkout with a database that can hold generated test data

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Identify what to benchmark
  2. Generate bulk data script
  3. Populate the database
  4. Extract the SQL query
  5. Analyze queries and generate report
  6. Wrap up

What it can do on your machine

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

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • python
    • make

    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 Filter Benchmark loads about 2.3k tokens when it runs. Until then it costs about 132 tokens; SKILL.md has 854 words of instructions outside code blocks.

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

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 passed

The automated check found no risky patterns in SKILL.md.

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 saleor/saleor at commit 782a751, republished under its BSD-3-Clause licence (© saleor). 854 words, ~2,259 tokens.

Download SKILL.mdSave it as .claude/skills/filter-benchmark/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
filter-benchmark
description
Benchmark and performance-test Django ORM filters on large datasets. Use this skill whenever the user wants to test filter performance, check query plans with EXPLAIN ANALYZE, generate bulk test data for filters, verify index usage, or benchmark any queryset filter in the Saleor codebase. Trigger this even when the user says things like "test the filter on a big dataset", "check if the index is used", "generate data for performance testing", "run explain analyze on this filter", or "benchmark this query".

Filter Benchmark

Performance-test Django ORM filters by generating bulk data, extracting the SQL query, and running EXPLAIN ANALYZE to verify index usage and query efficiency.

Overview

When adding or modifying filters in the Saleor GraphQL layer, it's critical to verify they perform well on large datasets — a filter that looks correct on 10 rows can cause full table scans on 100k+. This skill automates the full benchmarking workflow:

  1. Identify — Read the filter code, understand what fields and joins it touches, check existing indexes
  2. Generate data — Write a bulk population script that creates realistic, varied data targeting the exact fields the filter uses
  3. Populate — Run the script in Django shell to reach 100k+ rows
  4. Extract SQL — Get the actual query the filter produces from the Django ORM
  5. EXPLAIN ANALYZE — Run the query plan analysis and check for seq scans, missing indexes, and performance issues
  6. Report — Summarize findings and suggest concrete fixes (new indexes, query rewrites)

Step 1: Identify what to benchmark

Read the filter code to understand:

  • Which model(s) are being filtered
  • Which fields are involved (including related model fields for subquery filters)
  • What indexes exist on those fields (check the model's Meta.indexes)
  • What filter input combinations matter (e.g., date ranges, enum values, subqueries with Exists)

Look at the filter function source — it lives in saleor/graphql/<app>/filters.py. Understand the ORM query it builds (.filter(), Q(), Exists(), OuterRef(), etc.) because the test data must exercise all code paths.

Step 2: Generate bulk data script

Write a Python script that creates test data with enough variety to exercise the filter. The script should:

  • Use bulk_create with ignore_conflicts=True for maximum speed
  • Create data in batches (1000-5000 objects per batch) to avoid memory issues
  • Vary the field values that the filter targets so the query planner sees realistic data distribution
  • For date fields: spread values across a wide range (months/years), not just a narrow window
  • For enum/choice fields: distribute across all possible values
  • For related objects (e.g., events on a transaction): create multiple per parent with varied attributes
  • Handle required foreign keys by creating or reusing minimal parent objects (orders, checkouts, etc.)
  • Use timezone.now() and timedelta for date generation
  • Override auto_now / auto_now_add fields via bulk_update after creation when needed

The script should be a function that creates ~1000 objects per call. The user will call it in a loop to reach 100k+.

Example structure:

python
import random
from datetime import timedelta
from decimal import Decimal

from django.utils import timezone

from saleor.payment.models import TransactionItem, TransactionEvent
from saleor.payment import TransactionEventType


def populate(batch_size=1000):
    """Create batch_size TransactionItems with varied events."""
    now = timezone.now()

    # Create TransactionItems
    transactions = TransactionItem.objects.bulk_create(
        [
            TransactionItem(
                currency="USD",
                charged_value=Decimal("10.00"),
                # Vary dates across 2 years
                created_at=now - timedelta(days=random.randint(0, 730)),
            )
            for _ in range(batch_size)
        ]
    )

    # Override auto_now/auto_now_add fields with varied values via bulk_update
    for t in transactions:
        t.created_at = now - timedelta(days=random.randint(0, 730))
        t.modified_at = now - timedelta(days=random.randint(0, 365))
    TransactionItem.objects.bulk_update(transactions, ["created_at", "modified_at"])

    # Create events for each transaction
    event_types = [e.value for e in TransactionEventType]
    events = []
    for t in transactions:
        num_events = random.randint(1, 4)
        for _ in range(num_events):
            events.append(
                TransactionEvent(
                    transaction=t,
                    type=random.choice(event_types),
                    amount_value=Decimal("10.00"),
                    currency="USD",
                    created_at=now - timedelta(days=random.randint(0, 730)),
                )
            )
    TransactionEvent.objects.bulk_create(events)
    print(
        f"Created {len(transactions)} transactions and {len(events)} events. "
        f"Total: {TransactionItem.objects.count()} transactions, "
        f"{TransactionEvent.objects.count()} events"
    )

Adapt this pattern to whatever model and filter is being tested. The key principle: the data must vary on exactly the fields the filter touches.

Step 3: Populate the database

Run the population script in Django shell. Activate the venv first:

bash
source .venv/bin/activate && python manage.py shell

Then in the shell, run the function in a loop:

python
for i in range(100):
    populate()

This reaches 100k objects. Monitor the output to confirm counts are growing. If the database already has data from a previous run, check counts first and only add what's needed.

Step 4: Extract the SQL query

Get the actual SQL that the filter produces. There are two approaches — use whichever fits best:

Approach A: From the filter function directly

Open a Django shell and call the filter function with representative input values, then print the query:

python
from saleor.payment.models import TransactionItem
from saleor.graphql.payment.filters import filter_where_created_at_range

qs = TransactionItem.objects.all()
filtered = filter_where_created_at_range(qs, None, {"gte": "2025-01-01T00:00:00Z", "lte": "2025-06-01T00:00:00Z"})
print(str(filtered.query))
Show full SKILL.md (333 more words)Show less
Approach B: From a test with breakpoint

Add a breakpoint() right after the filter call in the filter function, run a test that hits it, then in the debugger:

python
print(str(qs.query))

Use this approach when the filter input is complex (e.g., involves GraphQL variable resolution or multiple conditions).

Approach C: Using .explain() directly
python
print(qs.explain(analyze=True, verbose=True, buffers=True))

This runs EXPLAIN ANALYZE directly from Django without needing psql. Useful for a quick check, but the data.sql + make explain approach gives JSON output which is easier to analyze.

Step 5: Analyze queries and generate report

Use the helper script at .claude/skills/filter-benchmark/analyze_query.py. It does everything in one call per queryset:

  • Runs EXPLAIN ANALYZE with default planner settings
  • Runs EXPLAIN ANALYZE with enable_seqscan = OFF to verify index availability
  • Detects red flags (Seq Scans on large tables, row estimate mismatches, sorts, nested loops with inner seq scans)
  • Saves JSON plans to /tmp
  • Uploads plans to explain.dalibo.com for interactive visualization

Run in Django shell:

python
import sys; sys.path.insert(0, ".claude/skills/filter-benchmark")
from analyze_query import analyze, report

# Analyze each queryset — prints quick summary + warnings inline
analyze(filtered_qs, "created_at range")
analyze(another_qs, "events by type")

# Print a full markdown report with Dalibo links
report()

Before analyzing, verify the querysets actually return rows. If EXPLAIN ANALYZE shows 0 rows, the filter input values don't match the generated data — adjust filter parameters (widen date range, use existing event types) and re-run.

The report() output includes a summary table and per-query details. Use it as the basis for the final report to the user, adding:

1. Dataset size — how many objects of each model, how field values are distributed

2. Recommendations — if there are warnings, suggest concrete fixes:

  • Missing index: show the migration to add it (use AddIndexConcurrently)
  • Suboptimal query: suggest ORM changes in the filter function
  • Missing composite index: when filtering on multiple fields together

Step 6: Wrap up

After presenting the report with Dalibo links, ask the user if they want to clean up the test data. If yes, delete the objects in reverse dependency order (child models first, then parents) to avoid foreign key violations. Use .delete() with filtering to target only the bulk-created data — for example, filter by the date range or other markers used during generation. Print counts of deleted objects for confirmation.

© saleor, BSD-3-Clause. 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 .claude/skills/filter-benchmark of saleor/saleor.

  • SKILL.md
  • analyze_query.py

Open the folder on GitHubat commit 782a751

Compare with similar skills

Django Filter Benchmark 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 Filter Benchmark compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Django Filter Benchmark this skillsaleor/saleor23k—~2.3kAutomated safety check: PassBSD-3-Clause
Phy Test Data FactoryLeoYeAI/openclaw-master-skills2.2k—~5.5kAutomated safety check: PassApache-2.0
Dummy Datasetkillvxk/pm-skills-zh167—~595Automated safety check: PassMIT
Kolokoloai/kolo525—~1.2kAutomated safety check: PassNone
Database OptimizerJeffallan/claude-skills12k—~1.6kAutomated safety check: PassMIT
SQL Optimizationgithub/awesome-copilot40k2 repos~2.3kAutomated safety check: PassMIT

Similar skills

  • Phy Test Data Factory

    LeoYeAI/openclaw-master-skills

    Schema-driven test data factory generator. An agent skill from LeoYeAI/openclaw-master-skills.

    2.2k GitHub stars~5.5k tokensUpdated 2 mo ago
    Testing & QAAuto-check passed
  • Dummy Dataset

    killvxk/pm-skills-zh

    生成用于测试的逼真虚拟数据集,支持自定义列、约束条件及输出格式(CSV、JSON、SQL、Python 脚本)。适用于创建测试数据、构建模拟数据集,或为开发和演示生成示例数据。

    167 GitHub stars~595 tokensUpdated 6 mo ago
    DatabasesAuto-check passed
  • Kolo

    koloai/kolo

    Kolo is a text-based Python debugger that captures every executed function, return value, local variable, HTTP request, and SQL query into greppable trace files.

    525 GitHub stars~1.2k tokensUpdated 5 mo ago
    DatabasesAuto-check passed
  • Database Optimizer

    Jeffallan/claude-skills

    Tunes PostgreSQL and MySQL performance by analyzing slow queries and execution plans, designing indexes, rewriting queries and adjusting configuration, one validated change at a time.

    12k GitHub stars~1.6k tokensUpdated 6 days ago
    DatabasesAuto-check passed
  • SQL Optimization

    github/awesome-copilot

    Official

    Universal SQL performance optimization assistant for comprehensive query tuning, indexing strategies, and database performance analysis across all SQL databases (MySQL, PostgreSQL, SQL Server…

    40k GitHub starsUsed in 2 repos~2.3k tokens
    DatabasesAuto-check passed
  • Dsql

    awslabs/agent-plugins

    Official

    Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, diagnose cluster performance, load data, and develop applications with a serverless, distributed…

    916 GitHub stars~7.1k tokensUpdated today
    DatabasesAuto-check passed

More from saleor/saleor

All 8 skills in this repo
  • Commits changes in the Saleor codebase and works through pre-commit hook failures from ruff, mypy, the GraphQL schema check and the migrations check.

    23k GitHub stars~575 tokensUpdated yesterday
    Auto-check passed
  • 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 yesterday
    Auto-check passed
  • Rules for writing Django migrations in Saleor that avoid long table locks and stay compatible with zero-downtime rolling deploys.

    23k GitHub stars~1.6k tokensUpdated yesterday
    Auto-check passed
  • Pytest Runner

    saleor/saleor

    Run pytest tests with automatic virtual environment activation. Use this skill whenever running tests, executing pytest, or when asked to "run tests", "test…

    23k GitHub stars~251 tokensUpdated yesterday
    Auto-check passed
  • Saleor Port Changes

    saleor/saleor

    Forward-ports or backports a single PR or branch onto the currently checked-out Saleor branch, handling GraphQL version markers and migration numbering along the way.

    23k GitHub stars~969 tokensUpdated yesterday
    Auto-check passed
  • Checklist for adding, changing, deprecating or removing Saleor GraphQL fields, mutations, enums and webhook event types so the change passes review first time.

    23k GitHub stars~1.2k tokensUpdated yesterday
    Auto-check passed

Works with

Questions about Django Filter Benchmark

What does Django Filter Benchmark do?

Benchmarks Django ORM filters in Saleor by generating bulk data, extracting the SQL and running EXPLAIN ANALYZE to check index usage. The skill is a six-step workflow for performance-testing filters in the Saleor GraphQL layer: identify the filter with its fields, joins and existing indexes, generate a bulk data script, populate through the Django shell to reach over 100k rows, extract the SQL the ORM produces, run EXPLAIN ANALYZE to spot sequential scans and missing indexes, and report findings with concrete fixes such as new indexes or query rewrites.

When should I use Django Filter Benchmark?

Django Filter Benchmark fits situations like: testing a new or changed filter on a large dataset; checking whether a filter makes use of an index; generating bulk test data for performance testing; running EXPLAIN ANALYZE on a queryset filter.

How do I install Django Filter Benchmark in Claude Code?

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

How do I install Django Filter Benchmark in Codex?

Run `npx skills add saleor/saleor --skill filter-benchmark -a codex`. Or copy the skill folder (.claude/skills/filter-benchmark in saleor/saleor) into .agents/skills/filter-benchmark in your project. Codex loads it when a task matches its description.

Can I use Django Filter Benchmark 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 saleor/saleor --skill filter-benchmark -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/filter-benchmark, .gemini/skills/filter-benchmark, .github/skills/filter-benchmark and .opencode/skills/filter-benchmark in your project.

What does Django Filter Benchmark need to run?

Going by SKILL.md and its folder, Django Filter Benchmark needs Python for the scripts in its folder and the command-line tools its instructions call (python and make). Our summary lists: A working Saleor checkout with a database that can hold generated test data.

Does Django Filter Benchmark 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 Filter Benchmark safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Django Filter Benchmark use?

Django Filter Benchmark is published under the BSD-3-Clause licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Django Filter Benchmark use?

About 2.3k tokens (SKILL.md is roughly 9k 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 Filter Benchmark?

Skills that share tags, products or a category with Django Filter Benchmark: Phy Test Data Factory (LeoYeAI/openclaw-master-skills, 2.2k stars), Dummy Dataset (killvxk/pm-skills-zh, 167 stars), Kolo (koloai/kolo, 525 stars) and Database Optimizer (Jeffallan/claude-skills, 12k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Django Filter Benchmark?

saleor (a GitHub organization) maintains it in saleor/saleor, which has 23,428 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on October 9, 2026.

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