Description
When SQL queries contain large IN clauses with thousands of parameters (e.g., UUIDs), the SQL panel either:
- Freezes for 10-18+ seconds (sqlparse < 0.5.5)
- Crashes with SQLParseError (sqlparse >= 0.5.5)
This is a common pattern when fetching IDs from one query and filtering by them in another:
job_ids = list(Campaign.objects.filter(...).values_list('job_id', flat=True))
# job_ids contains 5000+ UUIDs
applications = JobApplication.objects.filter(job_id__in=job_ids)
# Database query is fast, but debug toolbar freezes/crashes
Behavior Matrix
| debug-toolbar |
sqlparse |
When |
Behavior |
| <= 5.x |
< 0.5.5 |
Page load |
Freezes 10-18+ seconds |
| <= 5.x |
>= 0.5.5 |
Page load |
SQLParseError crash |
| >= 6.x |
< 0.5.5 |
SQL panel click |
Freezes 10-18+ seconds |
| >= 6.x |
>= 0.5.5 |
SQL panel click |
SQLParseError crash |
Benchmark Results (sqlparse 0.5.3)
| IN clause size |
Format time |
| 100 UUIDs |
0.01s |
| 500 UUIDs |
0.08s |
| 1,000 UUIDs |
0.26s |
| 3,000 UUIDs |
1.81s |
| 5,000 UUIDs |
4.87s |
| 10,000 UUIDs |
18.02s |
Root Cause
The bottleneck is in debug_toolbar/panels/sql/utils.py:
@lru_cache(maxsize=128)
def parse_sql(sql, *, simplify=False):
stack = get_filter_stack(simplify=simplify)
return "".join(stack.run(sql)) # sqlparse tokenizes entire SQL string
For a query with 5000 UUIDs:
- SQL string length: ~170,000 characters
- Token count: ~15,000+ tokens
- Each token processed by filters (indent, bold keywords, HTML escape)
The LRU cache doesn't help because each query with different parameters is a cache miss.
Steps to Reproduce
A minimal reproduction project is available:
https://github.com/kkm-horikawa/debug-toolbar-perf-issue
git clone https://github.com/kkm-horikawa/debug-toolbar-perf-issue.git
cd debug-toolbar-perf-issue
uv sync
uv run python manage.py migrate
uv run python manage.py runserver
# Visit http://127.0.0.1:8000/ and click on test links
Current Workaround
DEBUG_TOOLBAR_CONFIG = {
'PRETTIFY_SQL': False, # Disables ALL SQL formatting
}
This is suboptimal because it disables formatting for all queries, not just problematic ones.
Proposed Solution
I have submitted PR #2291 that:
- Adds
SQL_PRETTIFY_MAX_LENGTH setting (default 50000) to skip formatting for long queries
- Catches SQLParseError from sqlparse >= 0.5.5 gracefully
- Shows informative message with SQL preview when formatting is skipped
This provides:
- Normal formatting for typical queries
- Graceful degradation for extreme cases
- Configurable threshold
Related Issues
Environment
- Python 3.11+
- Django 5.0+
- django-debug-toolbar 5.2.0 / 6.1.0
- sqlparse 0.5.3 / 0.5.5+
Description
When SQL queries contain large
INclauses with thousands of parameters (e.g., UUIDs), the SQL panel either:This is a common pattern when fetching IDs from one query and filtering by them in another:
Behavior Matrix
Benchmark Results (sqlparse 0.5.3)
Root Cause
The bottleneck is in
debug_toolbar/panels/sql/utils.py:For a query with 5000 UUIDs:
The LRU cache doesn't help because each query with different parameters is a cache miss.
Steps to Reproduce
A minimal reproduction project is available:
https://github.com/kkm-horikawa/debug-toolbar-perf-issue
Current Workaround
This is suboptimal because it disables formatting for all queries, not just problematic ones.
Proposed Solution
I have submitted PR #2291 that:
SQL_PRETTIFY_MAX_LENGTHsetting (default 50000) to skip formatting for long queriesThis provides:
Related Issues
Environment