Two middleware entries, and every view, query, template and Celery task in your Django project reports its duration to statsd.
That recording is real. So is every transcript below: they are produced by running the code and checked by the test suite, so a claim on this page cannot outlive the behaviour it describes.
Quick Start
pip install django-statsd
INSTALLED_APPS = [
'django_statsd',
]
MIDDLEWARE = [
'django_statsd.middleware.StatsdMiddleware',
'django_statsd.middleware.StatsdMiddlewareTimer',
]
STATSD_HOST = '127.0.0.1'
STATSD_PORT = 8125
STATSD_PREFIX = 'myproject'
STATSD_TRACK_MIDDLEWARE = True
The tracker goes at the top of MIDDLEWARE and the timer at the
bottom. Your own middlewares go between them, and the pair times
everything in between.
What you get
One GET /dashboard/ puts this on the wire:
myproject.view.get.myproject.views.dashboard.hit
myproject.view.get.myproject.views.dashboard.process_request
myproject.view.get.myproject.views.dashboard.process_response
myproject.view.get.myproject.views.dashboard.process_view
myproject.view.get.myproject.views.dashboard.total
myproject.view.http_codes.2xx
myproject.view.http_codes.hit
myproject.view.site.hit
total is the request, the three process_* names are the phases
inside it, and hit is a counter so you get a rate per view without
dividing anything. The last two are project-wide.
Features
- Views timed by method and dotted view path, with status classes counted separately
- Queries timed through Django's
execute_wrapper, nested under the view that ran them, so you get query time per view - Celery tasks timed per task, plus a counter for every signal Celery exports
- Templates,
jsonandredispatched on import and timed without a line of configuration - Your own code, timed through
request.statsdor the module-level helpers, nested under the view that was running - Async safe. The scope lives on
asgiref.local.Local, so ASGI and async views report correctly
Requirements
- Python 3.10 through 3.14
- Django 5.2, 6.0 or 6.1
Celery and redis are optional. django-statsd patches them if they import and does nothing if they don't.
Where your milliseconds go
Recorded from a real request. The phases don't sum to
total, and the gap is the part of the request outside the section
the middleware pair wraps.
Usage Examples
Time a block inside a view through request.statsd:
def some_view(request):
with request.statsd.timings('build_queryset'):
...
def some_other_view(request):
request.statsd.timings.start('build_queryset')
...
request.statsd.timings.stop('build_queryset')
Or reach the same scope from anywhere during a tracked request, and from inside a Celery task:
import django_statsd
with django_statsd.with_('payment.authorise'):
...
django_statsd.incr('payment.attempt')
@django_statsd.decorator('payment')
def authorise():
...
Both land nested inside the view that was running, so the same helper called from two views gives you two series.
In a dashboard
statsd, Graphite and Grafana, fed by django-statsd over UDP. The
compose file and the provisioning that produced this are in
docs/generate/dashboard/.
Settings
| Setting | Default | What it does |
|---|---|---|
STATSD_HOST |
127.0.0.1 |
Where to send |
STATSD_PORT |
8125 |
Which port |
STATSD_PREFIX |
none | Nests every metric under one name |
STATSD_TRACK_MIDDLEWARE |
False |
The view metrics |
STATSD_TRACK_DATABASE |
False |
Query timings |
STATSD_SAMPLE_RATE |
1.0 |
Odds a metric is really sent |
STATSD_VIEWS_TO_SKIP |
admin | Regexes of views to ignore |
STATSD_DISABLED |
False |
Loaded and silent |
STATSD_DEBUG |
DEBUG |
Warn about unstopped timers |
Full list with docstrings: settings reference.
Documentation
Contributing
See CONTRIBUTING.md. Every code sample on this page is executed by the test suite, so a change to the API that breaks an example fails the build.
Links
License
Metadata
Release files for django-statsd 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_statsd-3.0.0.tar.gz | 13.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_statsd-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.8 kB
Release files / django_statsd-3.0.0.tar.gz
| Download URL | django_statsd-3.0.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45c3aa80245e4612ef762130f83a415033756521631a81a1ef93c02bda80df60
|
|
BLAKE2b-256 checksum How to use checksums |
9a3efd3c99894fa5ffd44efc67467e54b5b4c9deeff85ea42f5e697e884e86a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logRelease files / django_statsd-3.0.0-py3-none-any.whl
| Download URL | django_statsd-3.0.0-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f3244471722f27e8ad83d9a0a95091586af76fe6e70085f32d1dd26a31f5434b
|
|
BLAKE2b-256 checksum How to use checksums |
8061b2c58efa177b92522ea3b72e3d181542e58d33aa948e2f10004e2ca3d642
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency log