Skip to main content

Django middleware that measures request time breakdown (total/db/app) and query count using execute_wrapper.

Project description

django-xbench

Here's how django-xbench exposes request timing breakdown using the Server-Timing header: Server Timing Preview

Measure Django request time breakdown (total / db / app) and query count with minimal setup.
Adds Server-Timing and X-Bench-Queries headers and optionally logs per-request metrics.

Goal: make performance debugging “visible” (DB vs app/serialization) without heavyweight APM.

Features

  • ✅ Measures total request time and DB time (via connection.execute_wrapper)
  • ✅ Calculates app time (= total - db)
  • ✅ Counts DB queries
  • ✅ Adds response headers:
    • Server-Timing: xbench-total;dur=..., xbench-db;dur=..., xbench-app;dur=...
    • X-Bench-Queries: <int>
  • ✅ Optional logging:
    • [XBENCH] GET /path | xbench_total=...ms xbench_db=...ms xbench_app=...ms q=...
  • ✅ Tested with pytest + pytest-django

Installation

pip install django-xbench

For local development (recommended):

pip install -e ".[dev]"

Quickstart

  1. Add middleware in your settings.py:
MIDDLEWARE = [
    # Recommended: place near the top to approximate end-to-end server time
    # (includes other middleware overhead).
    "django_xbench.middleware.XBenchMiddleware",

    # ... other middleware ...

    # Optional: place near the bottom to focus on view/serializer/template time.
    # (Excludes middleware above XBench; includes anything below it.)
]
  1. Run your server and hit any endpoint:

In your project:

python manage.py runserver
curl -I http://127.0.0.1:8000/<your-endpoint>/

In this repo (demo):

python -m examples.manage runserver
curl -I http://127.0.0.1:8000/db-heavy/

You should see headers similar to:

Server-Timing: xbench-total;dur=12.345, xbench-db;dur=1.234, xbench-app;dur=11.111
X-Bench-Queries: 3

Output

Server-Timing

Example:

Server-Timing: xbench-total;dur=52.300, xbench-db;dur=14.100, xbench-app;dur=38.200
  • xbench-total: whole request duration
  • xbench-db: total DB time measured by wrapper
  • xbench-app: max(0, total - db) (serialization/template/python time etc.)

You can inspect this in Chrome DevTools → Network → Timing
(or any browser that supports the Server-Timing spec).

Query count header

X-Bench-Queries: 5

Configuration

You can configure XBench via settings.py or Environment Variables.

settings.py:

XBENCH_LOG_ENABLED = True
XBENCH_LOG_LEVEL = "debug"  # default: "info"

Example (Windows):

set XBENCH_LOG_ENABLED=1
set XBENCH_LOG_LEVEL=debug

Example (macOS/Linux):

export XBENCH_LOG_ENABLED=1
export XBENCH_LOG_LEVEL=debug

Development

Run tests

pytest

Note: this repo includes a bundled examples/ Django project used by pytest-django. The provided pytest.ini config sets pythonpath = . so examples can be imported reliably.

If you want to see logs while testing:

pytest -s

Demo project (bundled)

This repository includes an examples/ Django project for manual testing.

Run it from the repository root:

python -m examples.manage runserver

Try a few endpoints:

curl -I http://127.0.0.1:8000/db-heavy/
curl -I http://127.0.0.1:8000/app-heavy/
curl -I http://127.0.0.1:8000/admin/login/

Compatibility

  • Python: 3.9+
  • Django: 3.2+ (tested on Django 5.2.x)

Roadmap

  • DRF serialization time breakdown (view/serializer timing)
  • More robust Server-Timing merging (preserve existing metrics)
  • Docs: real-world examples (N+1 detection demo endpoints)
  • CI (GitHub Actions) for tests & release

Contributing

Issues and PRs are welcome.
If you propose new metrics, please include:

  • minimal reproducible example
  • tests
  • documentation update

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_xbench-0.1.1.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_xbench-0.1.1-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file django_xbench-0.1.1.tar.gz.

File metadata

  • Download URL: django_xbench-0.1.1.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for django_xbench-0.1.1.tar.gz
Algorithm Hash digest
SHA256 937da312efba8c7474e37d7eda72504ead14c8a8d91d5ab2a55a1d20e6211726
MD5 676de8446e4af9633881d388cbf14422
BLAKE2b-256 ce3e2182feab101455c61126e6b3ca7cbfad5c0136eb558589ea32898b45290c

See more details on using hashes here.

File details

Details for the file django_xbench-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: django_xbench-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for django_xbench-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3da4ed1b605581fa8df0ae8c3423521de45893251b2d38c4b185cf0312f2df48
MD5 bc31e1a3ec153272b4aaedf3313f2e95
BLAKE2b-256 5d264328086b55fd58b799abcc32b68abdf011f73670eedd7d90fcc4e656cce3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page