Why does Django not hot-reload on M1 Mac?

I have a Django application. Back when I was using an Intel mac, it's hot-reloading functionality was working. However, a year ago I switched to one of the new Macs and now I can't get it to hot-reload.

Here is my settings.py:


import os

import firebase_admin

BASE_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY_1 = '12312312'
# ... some more secret keys

DISABLE_SERVER_SIDE_CURSORS = True

DEBUG = True

AUTH_USER_MODEL = 'my_project.MyUser'

ALLOWED_HOSTS = ['*']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'my_project',
]

MIDDLEWARE = [
    'django.middleware.gzip.GZipMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'my_project/'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'wsgi.application'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'user',
        'USER': 'user',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    },
    'replica': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'user',
        'USER': 'user',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '5432',
    },
}

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

SECURE_HSTS_SECONDS = 0
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = False
X_FRAME_OPTIONS = 'DENY'
CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
CSRF_COOKIE_NAME = 'csrftoken'

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = os.environ.get('SECURE_SSL_REDIRECT', '') == 'True'

STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'

FIREBASE_APP = firebase_admin.initialize_app()

When I run the server (python3 manage.py runserver):

Watching for file changes with StatReloader
Performing system checks...
April 18, 2025 - 02:29:48
Django version 3.2.13, using settings 'settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Any time I update any .py file, I expect the server to reload but it doesn't.

You can install uvicorn package for reloading and which also has other cool features like -

  1. reload

  2. defining port

  3. defining host

  4. assigning workers (processes)

uvicorn your_app_name.wsgi:application --host 0.0.0.0 --port 8000 --reload --workers 4

for your requirement this command will you enough

uvicorn your_app_name.wsgi:application --reload

Using the watchdog backend on macOS is better, especially with newer filesystems like APFS used on Apple Silicon.

Install the dependency:

pip install watchdog

Then run the server with:

python manage.py runserver --reload

I believe this happens because Apple Silicon handles file watching differently. So try to install watchdog

pip install watchdog

Django will automatically switch to Watchdog's better file watcher.

If it doesn't work, force it in settings.py:

import sys
if sys.platform == 'darwin':
    from django.utils.reloader import watchman
    watchman.USE_WATCHMAN = True

The default watcher misses file changes on ARM Macs. Watchdog uses macOS-native APIs that actually work.

Back to Top