Repository files navigation
I've only tested this on Ubuntu.
You might need to adopt some of the commands for Windows (I'm using Windows and I just run this in WSL).
A lot of the code (especially frontend) was AI-generated (with heavy guidance). If you give the @ai-notes/ folder to programs like Cursor, make sure @ai-notes/overview.md is read, it will help.
At the time of writing, the concurrency graph (not the waterfall, the concurrency graph) may not necessarily be correct in gunicorn or other multiprocessing scenarios since the counter is not actually shared among workers. This is a known bug/issue.
Lastly: Not all of the demo is or was used for the conference talk given. I explored a number of different avenues, and there are some half trodden/incomplete paths in this codebase. For example, I'm not actually using MODE as much as I was planning to. I do derive some information from it, but was going to use it to give better titles to the graphs and charts. I didn't get to that, but there's a reason most stuff is there, it's just probably not documented.
git clone https://github.com/MicahLyle/ft
cd ft
Install uv if you haven't already.
uv sync
MODE=rns-sync-ft-t-314 PYTHON_GIL=0 uv run -p python3.14t nanodjango manage app.py runserver 0:8001
Visit localhost:8001 and you're off to the races.
Some of these may be out of date with the talk that was given. Some of these were things I was comparing.
runserver, synchronous, GIL
runserver-sync-gil-t-314: MODE=rns-sync-gil-t-314 uv run -p python3.14 nanodjango manage app.py runserver 0:8000
runserver, synchronous, Free Threaded
runserver-sync-ft-t-314: MODE=rns-sync-ft-t-314 PYTHON_GIL=0 uv run -p python3.14t nanodjango manage app.py runserver 0:8000
gunicorn, synchronous, GIL
gunicorn-sync-gil-p-314: MODE=gun-sync-gil-p-314 uv run -p python3.14 gunicorn app:wsgi --bind 0.0.0.0:8001 --workers 8 --name ft
gunicorn (ASGI, Uvicorn worker)
gunicorn-async-gil-p-314: MODE=gun-async-gil-p-314 uv run -p python3.14 gunicorn -k uvicorn.workers.UvicornWorker app:asgi --bind 0.0.0.0:8001 --workers 8 --name ft
gunicorn-async-ft-p-314t: MODE=gun-async-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t gunicorn -k uvicorn.workers.UvicornWorker app:asgi --bind 0.0.0.0:8001 --workers 2 --name ft
Runserver (sync only, worker t)
runserver-sync-gil-t-313: MODE=rns-sync-gil-t-313 uv run nanodjango manage app.py runserver 0:8000
runserver-sync-ft-t-313t: MODE=rns-sync-ft-t-313t PYTHON_GIL=0 uv run -p python3.13t nanodjango manage app.py runserver 0:8000
runserver-sync-gil-t-314: MODE=rns-sync-gil-t-314 uv run -p python3.14 nanodjango manage app.py runserver 0:8000
runserver-sync-ft-t-314t: MODE=rns-sync-ft-t-314t PYTHON_GIL=0 uv run -p python3.14t nanodjango manage app.py runserver 0:8000
Gunicorn (wsgi only, worker p)
gunicorn-sync-gil-p-313: MODE=gun-sync-gil-p-313 uv run gunicorn app:wsgi
gunicorn-sync-ft-p-313t: MODE=gun-sync-ft-p-313t PYTHON_GIL=0 uv run -p python3.13t gunicorn -k gthread app:wsgi
gunicorn-sync-gil-p-314: MODE=gun-sync-gil-p-314 uv run -p python3.14 gunicorn app:wsgi
gunicorn-sync-ft-p-314t: MODE=gun-sync-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t gunicorn -k gthread app:wsgi
Gunicorn (wsgi only, worker p, optimized)
gunicorn-sync-gil-p-313: MODE=gun-sync-gil-p-313 uv run -p python3.13 gunicorn app:wsgi -w 8
gunicorn-sync-ft-p-313t: MODE=gun-sync-ft-p-313t PYTHON_GIL=0 uv run -p python3.13t gunicorn -k gthread app:wsgi -w 2 --threads 16
gunicorn-sync-gil-p-314: MODE=gun-sync-gil-p-314 uv run -p python3.14 gunicorn app:wsgi -w 8
gunicorn-sync-ft-p-314t: MODE=gun-sync-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t gunicorn -k gthread app:wsgi -w 2 --threads 16
Granian (sync/async, worker t or p)
granian-sync-gil-t-313: MODE=gra-sync-gil-t-313 uv run -p python3.13 granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-sync-gil-p-313: MODE=gra-sync-gil-p-313 uv run -p python3.13 granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-async-gil-t-313: MODE=gra-async-gil-t-313 uv run -p python3.13 granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-async-gil-p-313: MODE=gra-async-gil-p-313 uv run -p python3.13 granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-sync-ft-t-313t: MODE=gra-sync-ft-t-313t PYTHON_GIL=0 uv run -p python3.13t granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-sync-ft-p-313t: MODE=gra-sync-ft-p-313t PYTHON_GIL=0 uv run -p python3.13t granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-async-ft-t-313t: MODE=gra-async-ft-t-313t PYTHON_GIL=0 uv run -p python3.13t granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-async-ft-p-313t: MODE=gra-async-ft-p-313t PYTHON_GIL=0 uv run -p python3.13t granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-sync-gil-t-314: MODE=gra-sync-gil-t-314 uv run -p python3.14 granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-sync-gil-p-314: MODE=gra-sync-gil-p-314 uv run -p python3.14 granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-async-gil-t-314: MODE=gra-async-gil-t-314 uv run -p python3.14 granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-async-gil-p-314: MODE=gra-async-gil-p-314 uv run -p python3.14 granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-sync-ft-t-314t: MODE=gra-sync-ft-t-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-sync-ft-p-314t: MODE=gra-sync-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface wsgi --host 0.0.0.0 --port 8000 app:wsgi
granian-async-ft-t-314t: MODE=gra-async-ft-t-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
granian-async-ft-p-314t: MODE=gra-async-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface asgi --host 0.0.0.0 --port 8000 app:asgi
Granian (3.14t optimized presets)
gra-sync-ft-p-314t (WSGI, workers=2, runtime-threads=16, backpressure=256):
MODE=gra-sync-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface wsgi --host 0.0.0.0 --port 8000 --workers 2 --runtime-threads 16 --backpressure 256 app:wsgi
gra-sync-ft-mt-314t (WSGI, mt runtime, workers=2, runtime-threads=16, backpressure=256):
MODE=gra-sync-ft-mt-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface wsgi --host 0.0.0.0 --port 8000 --workers 2 --runtime-threads 16 --backpressure 256 --runtime mt app:wsgi
gra-async-ft-p-314t (ASGI, workers=2, runtime-threads=8, backpressure=512):
MODE=gra-async-ft-p-314t PYTHON_GIL=0 uv run -p python3.14t granian --interface asgi --host 0.0.0.0 --port 8000 --workers 2 --runtime-threads 8 --backpressure 512 app:asgi
You can’t perform that action at this time.