I haven't tried Async Django, (But use normal Django on a few work and hobby project) and am hesitant based on my experience in rust, and not finding a fault I think coloring my Python/Django code would be advantageous to do.
Four releases later async will be marketed as "this has been a mistake" and the green threads will be the best thing ever. Thousands of blog posts will be written and everyone has to rewrite their code bases. Repeat for goroutines etc.
Async functions allow me to build massively parallel and concurrent systems with ease - it's beautiful.
In comparison, I'm not as fond of Go's approach to concurrency, which feels less elegant to me.
But there is a big downside, that's true.
python users only have themselves to blame for ignoring it.
> IIRC the history of the async things in TLA in order: Twisted (callbacks), Eventlet (for Second Life by Linden Labs), tornado, gevent; gunicorn, Python 3.5+ asyncio, [uvicorn,]
Async/await > History: https://en.wikipedia.org/wiki/Async/await
However, if we are to be honest, the history of async usage in Django wasn't very impressive. You could argue that for most products, you don’t really need async. It was just an extra layer of complexity without any significant practical benefit.
Over the last couple of years, AI use-cases have changed that perception. Many AI products have calling external APIs over the network as their bottleneck. This makes the complexity from async Python worth considering. FastAPI with its intuitive async usage and simplicity have risen to be the default API/web layer for AI projects.
I wrote about using async Django in a relatively complex AI open source project here: https://jonathanadly.com/is-async-django-ready-for-prime-tim...
tldr: Async django is ready! there is a couple of gotcha's here and there, but there should be no performance loss when using async Django instead of FastAPI for the same tasks. Django's built-in features greatly simplify and enhance the developer experience.
So - go ahead and use async Django in your next project. It should be a lot smoother that it was a year or even six months ago.
Can you expand more on why these AI cases make the complexity tradeoff different?
I'd imagine think waiting on a 3rd party LLM API call would be computationally very inexpensive compared to what's going on at the business end of that API call. Further lowering the cost, Django is usually configured to use multiple threads and/or processes so that this blocking call won't keep a CPU idle, no?
They’re very slow. Like, several seconds to get a response slow. If you’re serving a very large number of very fast requests, you can argue that the simplicity of the sync model makes it worth it to just scale up the number of processes required to serve that many requests, but the LLM calls are slow enough that it means you need to dramatically scale up the number of serving processes available if you’re going to keep the sync model, and that’s mostly to have CPUs sitting around idle waiting for the LLM to come back. The async model can also let you parallelize calls to the LLMs if you’re making multiple independent calls within the same request - this can cut multiple seconds off your response time.
If the alternative to Async is more processes, rather than threads, a clear benefit is reduced memory usage and reduced process startup time.
People who like synchronous Python can use Django.
People who like asynch Python can use Starlette - the async web server also written by the guy who wrote Django.
It’s not clear why Django needs to be async, especially when I get the sense there’s developers who like async and developers who prefer synch. It’s a natural fit for Django to fulfill the sync demand and Starlette to fulfill the async. They’re both good.
Django has a batteries-includes approach, benefits from tighter integration of orm, auth, form handling, etc, and has a huge 3rd party ecosystem.
First-class async support in Django allows Django users to avoid jumping through hoops (celery, channels, ...) for longer-running requests, something especially noticable if you're calling any kind of AI service.
Which is a very Django way to think: lots of tools ready to go, use only what you need.
Django is fine for writing a thin CRUD layer around a database. It makes the easy stuff easy. But doesn't seem to help much for the hard stuff and often actively hinders it.
Really the main reason for Django is its ORM and migrations. It's basically the other Python ORM (next to SQLAlchemy) but, unlike SQLAlchemy, it's not designed to be used standalone. In my experience I find Django (and active record ORMs in general) easier for people to get started with, but massively limiting in long run for complex domains.
Django having async support means you can use the Django ORM, and the Django request/response cycle, and generally not need to write your async and your sync web code using slightly different APIs.