Usually it's recommended to use a dedicated webserver like nginx or a CDN to serve static / user uploaded files when using Django. But after it's now (august 2020) possible to use async / await syntax in Django views, I thought it might be time to revisit this recommendation. It now should be possible to write views that are not blocking a complete worker process for the entire response serving time.
The code for returning async file responses is available via this django_fileresponse package. The process of building this package was also documented on my twitch stream (youtube playlist).
Options for returning file responses directly from the application server concurrently without async views:
- Just start a lot of worker processes and live with the memory overhead of c.a. 30MB per additional worker
- Start a lot of threads which is probably fine for most use cases
- Use gevent workers which will automatically turn your synchronous file responses in async ones using eventlets (and mokeypatching the standard library)
- Authentication and Authorization is working out of the box, no fiddling around with X-Accel like django-downloadview has to do it or with signed URLs / Cookies
- Being able to dynamically modify the streamed files (insert advertisement etc..)
- For biggish files CDNs are not optimal because they are relatively expensive (billed by traffic) while there's no improvement in user experience, because the difference in latency doesn't matter as much for bigger files