Making StatReloader's SLEEP_TIME configurable via a command line param to `runserver`

Hello,

Developing on a Windows (I know, please keep reading :slight_smile: ) laptop, I find that runserver’s auto reload functionality consumes quite a bit of power and thus battery. As well, while this is acutely detrimental to laptop battery life, for grid powered hardware this will result in extra load which ultimately comes from power generation - a process that in too many cases spews carbon into our atmosphere causing climate change.

It’s my understanding that this is truly not a problem with Django, but rather with how Windows handles watching. I as well understand that WatchmanReloader, and projects like GitHub - adamchainz/django-watchfiles: Use watchfiles in Django’s autoreloader., may provide alternatives to StatReloader. However, I’d like to suggest that the responsibility and known solutions don’t immediately address the needs of many of the users that will find themselves using runserver.

I believe that runserver is most useful for novice developers who may lack the knowledge of Python, Django, and their OS, to explore an implement the known alternatives. Given this, I’d like to suggest that making it as simple as possible to reduce resource utilization for novice users is a worthwhile effort. To that end, I’d like to suggest that we add a command line parameter to runserver: --sleeptime that will be passed to the implementation of BaseReloader such that it may be used in place of any hard coded values, and in particular SLEEP_TIME of StatReloader. Interestingly, while this is not a problem for WatchmanReloader as that already looks for an environment variable DJANGO_WATCHMAN_TIMEOUT, it might be helpful for WatchmanReloader to take and use this param if supplied. Of course, it’d be an option to also load SLEEP_TIME from an environment variable, but somehow that doesn’t seem like the djangonic way about this, and also doesn’t seem like the wildly beginner friendly solution that I’m suggesting with this post.

I can only imagine that a proposal to add a new parameter to runserver might not be particularly welcome, but I hope that this suggestion will at least spark a conversation about how we might make runserver a little bit less resource intensive.

Regards,
Ryan

1 Like

pywatchman is broken on Python 3.10+: https://github.com/facebook/watchman/issues/970 . There has been no fix for two years and Django 5.0+ only supports Python 3.10+. It may be time to rip out WatchmanReloader for Django 5.1.

I hope django-watchfiles can be the future, and maybe merged into Django at some point. @orf , the author of watchman support, got django-watchfiles into a workable state. Testing and improving it for all edge cases would be great.


Given that watchfiles provides a low CPU alternative, I would prioritize working on it over StatReloader (or fixing watchman in a fork, if possible!). If we had to tell users either “Use --sleeptime” or “Install [django-]watchfiles / watchman-fork”, I’d rather it be the latter.

Long term, I think we could adopt watchfiles as a direct dependency. It is stable and is maintained by a professional Python developer, with regular releases, a much better dependency than watchman ended up being.

That said, I think there’s space to do some automatic adaptive sleep adjustment in StatReloader, to reduce CPU usage when a server is idle. A gradual exponential backoff, up to say 5s, could cut out a lot of work without compromising reload speed drastically.

Or another idea: check virtual environment files only every so many ticks, since they very rarely change and are the vast majority of files being stat-d.


The timeout is quite different from the sleep time. I don’t think we should unify the two options.

Looks like it’s back ! New release last month