Django Query Stats per request

Snippet

# stats.py
import time

from django.db import connection
from loguru import logger


class StatsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """Capture stats about each request
        """
        start_time = time.time()

        # Needed in upper environments to get the SQL queries stats
        # Otherwise only works when DEBUG="true"
        connection.force_debug_cursor = True

        queries_before = len(connection.queries)
        response = self.get_response(request)
        queries_after = len(connection.queries)

        duration = time.time() - start_time

        num_queries = queries_after - queries_before

        try:
            total_query_time = sum(float(query["time"]) for query in connection.queries)
            logger.info(
                f"Time taken: {duration * 1_000:.2f} ms, "
                f"SQL queries executed: {num_queries}, "
                f"Total query time: {total_query_time * 1_000:.2f} ms",
                num_queries=num_queries,
                duration=duration,
                total_query_time_ms=int(total_query_time * 1_000),
                request_body=request.body.decode("utf-8"),
                request_method=request.method,
                request_path=request.path,
            )

            # Add some stats to the header so that we can see them in the clients
            response["X-Response-Time-ms"] = int(duration * 1_000)
            response["X-Total-Queries-Time-ms"] = int(total_query_time * 1_000)
            response["X-Total-Queries"] = num_queries

        except Exception:
            # Never expect this to have an exception
            # but better to catch and log, rather then breaking the response
            logger.exception("Error logging request stats")

        return response

Description

Be sure to add it to your settings.py middleware

MIDDLEWARE = [
    # ...
    "my_app.stats.StatsMiddleware",
]
By xtream1101 Updated 2025-05-11 00:04