django-bolt decides where your code runs by reading it
django-bolt serves Django from a Rust server, with one Python worker thread per process. In an independent benchmark it ran 1.6 to 1.7x django-ninja on real database endpoints. The catch: a slow sync handler must move to a thread pool, or every request in that process waits. Bolt decides at startup by scanning each handler’s source for ORM calls like .objects.get.
The scan reads only the handler. return Order.objects.get(id=id) goes to the pool. return services.get_order(id) runs the same query inline on the worker thread, and the whole process stalls until it returns. A codebase with a service layer hits this on nearly every route. The way out is async handlers: async def puts the waiting in the signature, so it can’t hide one call down.
A scan of one function sees what’s written there, not what it calls. A fact that has to cross calls belongs in the signature, which is Ron Minsky’s argument for types.