Skip to main content

Make Django’s autoreloader more efficient by watching for changes with watchfiles.

Project description

https://img.shields.io/github/actions/workflow/status/adamchainz/django-watchfiles/main.yml.svg?branch=main&style=for-the-badge https://img.shields.io/badge/Coverage-100%25-success?style=for-the-badge https://img.shields.io/pypi/v/django-watchfiles.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

Make Django’s autoreloader more efficient by watching for changes with watchfiles.


Improve your Django and Git skills with my books.


Requirements

Python 3.9 to 3.14 supported.

Django 4.2 to 6.0 supported.

Installation

  1. Install with pip:

    python -m pip install django-watchfiles
  2. Add django-watchfiles to your INSTALLED_APPS:

    INSTALLED_APPS = [
        ...,
        "django_watchfiles",
        ...,
    ]

That’s it! 😅

Try installing django-browser-reload as well, to make your browser automatically reload the page when changes are detected.

Usage

django-watchfiles will be automatically used by Django’s runserver command. You can tell this because runserver will list WatchfilesReloader as the watcher class:

$ ./manage.py runserver
Watching for file changes with WatchfilesReloader
...

(Rather than the default StatReloader.)

WatchfilesReloader provides the following advantages:

  • Much lower CPU usage

    Django’s default StatReloader works by polling all files for changes, sleeping for one second, and looping. Meanwhile, WatchfilesReloader avoids polling; instead, it asks the operating system to report any changes to the watched files.

    The difference can be stark and save you significant battery when developing on a device that isn’t connected to a power source. A quick benchmark on a medium-sized project (385,000 lines plus 206 installed packages) using an M1 MacBook showed StatReloader using ~10% of a CPU every other second, while WatchfilesReloader uses 0%.

  • Reduced reload time

    StatReloader can take one second or more to detect changes, while WatchfilesReloader can take as little as 50 milliseconds. This means that runserver starts reloading your code more quickly, and you can iterate more rapidly.

  • Batched reloads

    Sometimes multiple file changes can occur in quick succession, such as when one file is saved and then updated by a formatter, or when multiple files are changed when you git switch to another branch. In such cases, StatReloader can trigger multiple reloads, unnecessarily slowing down progress, or it can miss some changes, leading to old code being left running. WatchfilesReloader instead batches changes, using watchfiles’ debounce feature, so that multiple changes will only trigger a single reload.

    WatchfilesReloader uses watchfiles’ defaults here, waiting for changes within a 50 millisecond window, and repeating this wait for up to 1600 milliseconds, as long as changes keep occurring. These values provide a good balance between responsiveness and batching.

On some platforms (Windows Subsystem for Linux, or WSL), watchfiles will fall back to a polling approach. This is still more efficient than StatReloader though, because it’s implemented in Rust.

watchfiles has some configuration options which can be configured through environment variables. See the watchfiles documentation for details.

History

Django’s runserver started with only the logic for StatReloader, because it’s simple and works on all platforms.

In Django 1.7 (2014), Django gained support for using the Linux file-watching API inotify, through the pyinotify package. This provided efficient reloading, but was limited to Linux. This was thanks to Unai Zalakain, Chris Lamb, and Pascal Hartig for that work in Ticket #9722.

In Django 2.2 (2019), Django gained support for Watchman, a cross-platform file-watching service from Facebook, via the pywatchman package. This provides efficient reloading on Linux and macOS, but requires developers to install and run the Watchman service separately. Thanks to Tom Forbes for that work in Ticket #27685.

Unfortunately, the pywatchman package stopped working on Python 3.10, as reported in its Issue #970 (2021). This issue remained unfixed for a long time, until March 2024, after the release of Python 3.12. It appears that Watchman and pywatchman are not a priority for maintenance by Facebook.

In 2022, Samel Colvin released watchfiles, a new cross-platform file-watching library for Python. It is powered by Notify, a popular and established Rust crate. (watchfiles is also the Rust-powered rebuild of Samuel’s earlier watchgod package (2017).)

I created django-watchfiles in 2022 to integrate watchfiles with Django’s autoreloader. The inspiration came from writing about using Watchman in Boost Your Django DX and feeling a bit dismayed that it wasn’t particularly easy, and that it wasn’t (yet) working on Python 3.10.

django-watchfiles had its first stable release in 2024. I may propose integrating it with Django core at some point, when it’s more established.

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_watchfiles-1.4.0.tar.gz (8.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_watchfiles-1.4.0-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file django_watchfiles-1.4.0.tar.gz.

File metadata

  • Download URL: django_watchfiles-1.4.0.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_watchfiles-1.4.0.tar.gz
Algorithm Hash digest
SHA256 88e253e8e8427834eac467923d334c35010279b3e9ceb5bb91014be83975b11b
MD5 cde1611ea31d2813cf4458a7b7097987
BLAKE2b-256 1a8951b82766a1c937dea9fb92f0fb7666919d120379fc26dc84ab504e35f37e

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_watchfiles-1.4.0.tar.gz:

Publisher: main.yml on adamchainz/django-watchfiles

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_watchfiles-1.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_watchfiles-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 40cb3180987c63629b0681ab228b65afd68e0f783388cc72a45620378213bb48
MD5 1648bf521b3825847a56ef8c4b3c224c
BLAKE2b-256 c7853d31f347e1a3eef9be381792df1994ff25e4db4659ab40a5cc3f814e3a1a

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_watchfiles-1.4.0-py3-none-any.whl:

Publisher: main.yml on adamchainz/django-watchfiles

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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