N+1 database queries and silent query count growth can severely affect Django application performance. Unfortunately, they are often discovered too late—in production server logs or APM dashboards.
To solve this problem, I built django-query-guard—an open-source Pytest plugin that brings database performance checks directly into automated test suites.
💡 The Problem: Silent N+1 Queries
In Django, the ORM makes fetching related models effortless, but it’s terrifyingly easy to write an accidental N+1 loop:
python
# ❌ N+1 Query Accident
# Fetches 100 users (1 query), then executes 100 individual queries for each profile!
# Total: 101 Database Queries! 🐌
users = User.objects.all()
profiles = [user.profile.bio for user in users]
🛡️ The Solution: django-query-guard
Instead of relying on manual code reviews, django-query-guard turns query limits and N+1 prevention into enforceable Pytest assertions:
python
import pytest
@pytest.mark.django_db
@pytest.mark.query_guard(max_queries=2, detect_n_plus_one=True)
def test_user_profiles_api(client):
response = client.get("/api/users/")
assert response.status_code == 200
If your endpoint accidentally executes 101 queries instead of 2, Pytest fails instantly with an exact breakdown of which SQL statement repeated! 💥
🔥 Key Features
🎯 Pytest Marker Integration: @pytest.mark.query_guard(max_queries=N)
🧠 Smart SQL Normalization: Parameter-variation filtering prevents false positives on intentional duplicate queries with identical parameters.
🗄️ Multi-Database Support: Monitors queries across all configured Django database connections (default, replica, etc.).
📊 HTML Query Reports: Dark-themed HTML report generation after test runs (pytest --query-guard-report=report.html).
📈 Trend History Tracking: JSON-based run history with regression detection across test builds (pytest --query-guard-trend=.query_guard_history.json).
🐍 Wide Compatibility: Fully tested on Python 3.10–3.14 and Django 4.0–6.0.
📦 Installation & Setup
Install the stable package from PyPI:
bash
pip install django-query-guard
Or with development tools:
bash
pip install django-query-guard[dev]
📊 Generating Visual HTML Reports
You can generate a dark-themed HTML query report after any test run:
bash
pytest --query-guard-report=report.html
The report includes:
Summary metrics (Total tests, pass/fail counts, total queries, N+1 detections)
Per-test query count breakdown
Detailed SQL query execution duration and parameters for failing tests












