Web API performance: profiling Django REST framework

We’ve seen several cases of developers making these assumptions before they start building their API, and either discounting Django as not being fast enough for their needs, or deciding to not use a Web API framework such as Django REST framework because they ‘need something lightweight’.

I’m going to be making the case that Web API developers who need to build high performance APIs should be focusing on a few core fundamentals of the architecture, rather than concentrating on the raw performance of the Web framework or API framework they’re using.

.. the biggest performance gains for Web APIs can be made not by code tweaking, but by proper caching of database lookups, well designed HTTP caching, and running behind a shared server-side cache if possible.

.. 1. Get your ORM lookups right.

Given that database lookups are the slowest part of the view it’s tremendously important that you get your ORM queries right. Use .select_related() and.prefetch_related() on the .queryset attribute of generic views where necessary. If your model instances are large, you might also consider using defer() or only()to partially populate the model instances.

2. Your database lookups will be the bottleneck.

.. 3. Work on performance improvements selectively.

Remember that premature optimization is the root of all evil. Don’t start trying to improve the performance of your API until you’re in a position to start profiling the usage characteristics that your API clients exhibit. Then work on optimizing your views selectively, targeting the most critical endpoints first.

Optimizing slow Django REST Framework performance

At it’s root, the problem is called the “N+1 selects problem”; the database is queried once for data in a table (say, Customers), and then, one or more times per customer inside a loop to get, say,customer.country.Name. Using the Django ORM, this mistake is easy to make. Using DRF, it is hard not to make.

.. Eager loading is a common performance optimization that has application well beyond the Django REST Framework.

Any time you are querying nested relationships via an ORM, you should think about setting up the proper eager loading. In my experience, it is the most commonplace performance-related problem in modern small- and midsize web development.