0

Django Ninja vs DRF Benchmark: Critical Analysis and New Results


Hello devs đź‘‹,

Recently, I looked into Django Ninja, this new challenger that promises to bring FastAPI speeds to the Django ecosystem.

On paper, the benchmarks are impressive. But looking closer, I felt the comparison was a bit… biased. 🤔

Indeed, official benchmarks often compare DRF-uwsgi (synchronous mode) with Django-Ninja-uvicorn (asynchronous mode). It’s a bit like comparing a race car on a highway with a 4x4 on a dirt road. Both are performant, but they don’t race in the same category.

So I decided to run my own performance tests locally to set the record straight. ⏱️

đź§Ş Test Methodology

To have a fair comparison, I ran several test scenarios isolating variables.

The idea is to compare:

  1. Sync vs Sync: DRF under uWSGI vs Ninja under uWSGI.
  2. Input Validation: DRF Serializers vs Pydantic (used by Ninja).
  3. Async: See how everyone behaves with asynchronous calls.

I used the following repo as a base (modified for testing needs): https://github.com/vitalik/django-ninja-benchmarks/tree/master

Configurations Tested:

  • DRF-uwsgi (Sync): The classic and robust stack.
  • Ninja-uwsgi (Sync): Ninja used synchronously.
  • DRF-uvicorn (Async): DRF running under an ASGI server.
  • Ninja-uvicorn (Async): The “star” configuration highlighted.

📊 The Results

Here is what I found after running the tests on my machine.

1. API Calls with Requests Lib (Synchronous Client)

Comparison: DRF-uwsgi (sync) Vs Ninja-uwsgi (sync)

In this classic scenario (a standard python script client), we compare both frameworks on equal footing (WSGI).

Benchmark Sync Requests

👉 Result: Unsurprisingly, Django Ninja takes the lead thanks to its lightweight nature, but the gap is less abysmal than when changing application servers. DRF remains quite capable, but Ninja’s Pydantic validation gives it a boost.

2. API Calls with Aiohttp Lib (Asynchronous Client)

Comparison: DRF-uwsgi Vs Ninja-uwsgi Vs DRF-uvicorn Vs Ninja-uvicorn

Here, we bombard the server with concurrent requests.

Benchmark Async Aiohttp Benchmark Concurrency

👉 Result: This is where it gets interesting. One might think Async wins every time. However, on simple operations or CPU-bound tasks (like heavy JSON serialization), Django (in Sync uWSGI mode) holds up incredibly well, sometimes even surpassing poorly configured Async versions.

Thread management by uWSGI is extremely mature and performant for standard Python code.

3. JSON Input Validation

Comparison: DRF Serializer vs Pydantic Schema

This is often the API bottleneck: validating what the user sends.

Benchmark Validation

👉 Result: Pydantic (and thus Ninja) crushes DRF. 🚀 There’s no contest here. Pydantic is written partly in Rust (in v2) and optimized to the extreme. DRF Serializers are very flexible and powerful, but much slower in pure execution.

If your API does a lot of complex data validation, Ninja will save you precious time, regardless of the server (uWSGI or Uvicorn).


🏆 The Verdict: Django is the Winner 🎉

My conclusion might be counter-intuitive, but here is my analysis:

It’s not so much “Ninja vs DRF” or “Async vs Sync”. The big winner is the Django ecosystem.

  1. If you need raw validation performance: Ninja (Pydantic) is unbeatable.
  2. If you have an existing app: Switching to Ninja can help, but optimizing your WSGI server (switching to uWSGI with the right thread/process settings) is often the most cost-effective optimization (ROI).
  3. Async is not magic: As I explained in another article, async only becomes indispensable for very specific I/O (WebSockets, SSE, slow outgoing HTTP requests). For classic CRUD, a well-tuned synchronous Django is a beast.

In Summary

Official benchmarks don’t lie, but they tell a specific story (Ninja’s “happy path”). In real-world conditions, on equal ground (Sync vs Sync), Ninja remains faster thanks to Pydantic, but DRF is not as “has-been” as people say.

My advice? Test it yourself with your own use cases!

Have you observed the same results in prod? Let me know on Twitter or LinkedIn!

Comments