TL;DR
Django-Bolt is a young API framework that bolts a Rust HTTP server (Actix Web) onto a normal Django project. You keep the ORM, the admin, migrations, and every Django package you already use, but requests are parsed, routed, and authenticated in Rust before your Python handler ever runs. The reported throughput is genuinely wild: around 188,000 requests per second on a plain endpoint, roughly 8-9x what FastAPI does on the same box. The catch is that the moment you touch the database, that number falls to about 14,800 RPS, because Python and the ORM become the bottleneck again. It’s beta (v0.9.0 as of early July 2026), the docs are thin, and I would not put it under a payment API yet. But the idea is the most interesting thing to happen to Django’s API story in years.
Why I bothered looking at this
I wrote a FastAPI vs Litestar vs Django Ninja comparison a couple of days ago, and the whole time I kept circling the same tension: FastAPI and Litestar are fast and pleasant, but you give up the ORM, the admin, and every Django package to get there. Django Ninja hands all of that back but inherits Django’s request path, which was never built for raw throughput. There’s no free lunch; you pick your side.
Django-Bolt showed up in my feed claiming it deletes that tradeoff, so I spent an evening reading the source instead of the marketing. I didn’t run the benchmarks myself — I’ll be upfront about that, and every number below is the author’s, measured on a local dev machine. What I did do is trace how a request actually flows through the thing, because that’s where you find out whether a “Rust-powered” label means something or is just a wrapper around the same slow path. In Django-Bolt’s case, it means something. The HTTP layer, the router, and even JWT verification run in compiled Rust with the Python GIL released, and your Django code only wakes up when there’s real work to do. That’s a real architectural choice, and it shows once you read the request path.
One detail sold me on the author’s seriousness: there’s a runbolt management command that replaces gunicorn and uvicorn entirely. You don’t put an ASGI server in front of it. The Rust binary is the server. It’s a very different posture from “here’s an ASGI app, bring your own worker.”
What Django-Bolt actually is
Under the hood, Django-Bolt (GitHub, MIT licensed) is a stack of four Rust pieces glued to Python:
- Actix Web handles all incoming HTTP — connections, keep-alive, routing, middleware. Actix is one of the fastest web servers in any language, and it’s doing the heavy lifting here.
- PyO3 is the bridge. It lets the Rust runtime call your Python
async defhandlers and hand the results back, marshalling data across the boundary. - msgspec does serialization instead of the standard library’s
json. The project cites 5-10x faster encode/decode, and your request/response schemas aremsgspec.Structclasses rather than Pydantic models. - matchit is a zero-copy path router, so
/users/{user_id}gets matched without allocating strings on every request.
The mental model that helped me: think of it as Actix Web with a Python scripting layer for your business logic, where the scripting layer happens to have Django’s ORM sitting right there. Requests hit Rust, get routed in Rust, get authenticated in Rust, and only cross into Python when your handler needs to run a query or apply business rules. Compare that to Django Ninja, where every request travels the full Django middleware stack in Python before it reaches your view.
Roughly 83% of the repository is Python and 12.5% is Rust. That ratio is the tell: the Rust is concentrated exactly where the hot path lives, and everything you’d actually write day-to-day stays Python.
The benchmark numbers (and why the headline lies a little)
Here are the throughput figures the project reports. I’m quoting them verbatim and labelling them as reported, because I didn’t reproduce them and neither the author’s harness nor the community one follows strict benchmarking hygiene.
| Endpoint | Reported RPS |
|---|---|
| Root (“hello world”) | ~188,100 |
| Path + query params | ~163,200 |
| HTML response | ~164,100 |
| Form data | ~143,900 |
| JSON validation (10 KB body) | ~128,400 |
| ORM read (10 SQLite rows) | ~14,800 |
Put the top row and the bottom row side by side. The two of them tell you almost everything.
The 188K number is a Rust round-trip that barely touches Python. Impressive engineering, but almost no real endpoint looks like that. The instant you do a database read, which is what every API does constantly, you drop by more than 12x, because now you’re paying for Python object creation, the ORM’s query construction, and the database round-trip. Rust can’t speed those up, and it was never going to.
That 14,800 RPS isn’t bad, though. It’s still roughly double what FastAPI reportedly manages on the same ORM-bound workload, and Django Ninja trails further back. What Django-Bolt really buys you is removing the HTTP layer as your bottleneck. Whether that helps you depends entirely on whether the HTTP layer was ever your bottleneck. For most CRUD apps hammering a Postgres box, it wasn’t. For high-fanout gateways, proxies, SSE hubs, and read-heavy JSON APIs with caching, it absolutely is, and that’s the workload Django-Bolt was built for.
The community benchmark (tanrax/python-api-frameworks-benchmark) uses Bombardier with 100 concurrent connections, 10 seconds per endpoint, 1000 warmup requests, and 3 runs. Its author is refreshingly blunt: “This is an informal benchmark run on a local development machine without proper isolation… Results may vary significantly in production environments.” Believe that disclaimer. Treat every number here as a rough direction rather than a hard measurement. If throughput is load-bearing for a decision you’re making, run the harness on your own hardware with your own queries. I’d trust my own wrk run over anyone’s screenshot, and so should you.
Writing an endpoint
This is where it wins me over on ergonomics, because it reads like FastAPI but the schema layer is msgspec instead of Pydantic, the same fast-serialization library the wider modern Python tooling stack has been moving toward. Here’s the minimal case straight from the docs:
# myproject/api.py
from django_bolt import BoltAPI
from django.contrib.auth import get_user_model
import msgspec
User = get_user_model()
api = BoltAPI()
class UserSchema(msgspec.Struct):
id: int
username: str
@api.get("/users/{user_id}")
async def get_user(user_id: int) -> UserSchema:
user = await User.objects.aget(id=user_id)
return {"id": user.id, "username": user.username}
Two things worth calling out. First, User.objects.aget() is Django’s async ORM, and Django-Bolt leans on it hard. If you’re still writing synchronous ORM calls everywhere, you won’t see the benefit, and you may hit SynchronousOnlyOperation surprises. Second, the return type annotation does real work: msgspec uses UserSchema to validate and serialize the response, the same way FastAPI uses Pydantic return types.
Wiring it in is three lines of config:
# myproject/settings.py
INSTALLED_APPS = [
# ...
"django_bolt",
]
And you run it with the bundled server rather than an ASGI worker:
python manage.py runbolt --dev
No uvicorn, no gunicorn process manager, no --workers 4. The Rust binary owns the socket. In production you drop --dev. That’s fewer moving parts than the FastAPI deployment story, where you’re always assembling an ASGI server plus a process supervisor. If you’ve been living in the uv-based Python workflow like me, uv add django-bolt and you’re running.
Auth and guards run in Rust
The part I found most clever is authentication. In a normal Django or FastAPI app, a bad token still costs you a full trip into Python before it gets rejected. Django-Bolt validates JWTs and API keys in Rust, before your handler is scheduled, with the GIL released:
from django_bolt.auth import JWTAuthentication, IsAuthenticated
@api.get("/profile", auth=[JWTAuthentication()], guards=[IsAuthenticated()])
async def profile(request):
return {"user": request.user.username}
Think about what that buys you under a credential-stuffing flood: thousands of junk requests get bounced by compiled code without ever waking the Python interpreter. Your worker pool stays free for legitimate traffic. It’s a real DoS-resilience property, and the kind of thing you only get when the auth layer lives below Python. It reminds me of the argument I made in the Rust vs Go writeup: the real payoff is that the expensive language never runs for the cheap requests.
Beyond auth, the framework ships CORS, rate limiting, compression, and integration with existing Django middleware, plus auto-generated OpenAPI docs and ViewSet/ModelViewSet patterns for people who like DRF’s shape. Streaming responses, Server-Sent Events, file downloads, and WebSockets are all listed as supported. The reported SSE numbers are strong. A streaming test held 10,000 concurrent clients at 100% connection success, pushing about 9,489 messages per second, which tracks with Actix being good at long-lived connections.
Where I’d hesitate
Let me be the person who says the annoying part out loud, because a review that only lists features is a brochure.
It’s v0.9.0 and labelled beta. There have been 57 releases, which tells you the API surface is still moving. The docs, hosted at bolt.farhana.li, are a work in progress, and I hit several pages that were stubs pointing at “coming soon” sections. When something breaks at 2am, thin docs plus a small community means you’re reading Rust source, not Stack Overflow.
The async ORM requirement is load-bearing. Django-Bolt’s whole value proposition assumes your handlers are async and your database access is async. A huge amount of existing Django code is synchronous, and porting it isn’t a find-and-replace. Third-party Django packages that aren’t async-aware will fight you.
There’s a debugging tax to the Rust layer. When the HTTP server is a compiled binary, a stack trace that dies in Actix is not going to be pleasant for a Python develper, and you can’t just drop a pdb breakpoint into the request path. Most of the time you live in Python and never notice. Occasionally you’ll wish the whole thing were Python so you could see what it’s doing.
And the headline number invites cargo-cult adoption. People will read “188K RPS” and rewrite a healthy Django app that serves 40 requests a second, then spend a weekend fighting async bugs for a speedup they’ll never observe. A speedup you can’t measure in production isn’t buying you anything.
Django-Bolt vs FastAPI vs Django Ninja
Here’s how I’d place it against the two frameworks people will actually compare it to. FastAPI numbers are reported figures for the same style of workload; treat the whole table as directional.
| Django-Bolt | FastAPI | Django Ninja | |
|---|---|---|---|
| HTTP layer | Rust (Actix) | Python (Starlette) | Python (Django) |
| Django ORM / Admin | Native | None | Native |
| Serialization | msgspec | Pydantic | Pydantic |
| Reported raw RPS | ~188K | ~20K | Lower than FastAPI |
| Auth executed in | Rust (no GIL) | Python | Python |
| Deploy model | Bundled Rust server | ASGI + worker | ASGI/WSGI + worker |
| Maturity | Beta (v0.9) | Stable, largest community | Stable |
If you already have a Django app and you’re API-bound at the HTTP layer, Django-Bolt is the only option in this table that doesn’t make you throw away the ORM and admin. If you’re greenfield and want the safest, best-documented path, FastAPI is still the boring correct answer. If you want Django’s batteries and don’t need extreme throughput, Django Ninja is more mature and will never surprise you at 2am.
Who should try it, who should skip it
Try it if: you run a read-heavy or streaming API on top of Django, you’re comfortable reading a bit of Rust when things go sideways, your handlers are already async, and you can tolerate a beta dependency for a real throughput win. Internal services, gateways, and SSE/WebSocket hubs are the sweet spot.
Skip it if: you’re shipping something with compliance or uptime guarantees this quarter, your team isn’t fluent in async Django, or your bottleneck is the database (which, be honest, it usually is). In all three cases the risk of a beta framework outweighs a throughput number you won’t hit anyway.
FAQ
Is Django-Bolt faster than FastAPI?
On reported benchmarks, yes, substantially on plain endpoints (~188K vs ~20K RPS) and roughly 2x on ORM-bound reads. But those are the author’s numbers on an un-isolated local machine, and the gap shrinks the more real work your handler does. For a database-heavy CRUD API, the practical difference is far smaller than the headline suggests.
Is Django-Bolt production ready?
Not for anything critical yet. It’s v0.9.0, self-described as beta, with 57 releases behind it and documentation still being written. It’s a great fit for internal tools and side projects where you can absorb breakage. I wouldn’t put it under a payment flow or a system with an SLA today.
Does Django-Bolt work with the Django ORM and admin?
Yes, and that’s the entire point. It runs inside a normal Django project, so the ORM, admin, migrations, signals, and third-party Django packages all keep working. It leans on Django’s async ORM (aget, afilter, etc.), so async-first code gets the most out of it.
What is Django-Bolt built on?
Actix Web for the HTTP server, PyO3 to bridge Rust and Python, msgspec for serialization, and matchit for zero-copy path routing. Your handlers are still plain Python async def functions; the performance-critical layers underneath them are compiled Rust.
How do I install and run Django-Bolt?
pip install django-bolt (or uv add django-bolt), add "django_bolt" to INSTALLED_APPS, define endpoints with @api.get(...) decorators, and start the server with python manage.py runbolt --dev. There’s no separate uvicorn or gunicorn; the bundled Rust server owns the socket.
Sources
- Django-Bolt — GitHub repository — source, architecture, reported benchmark table, MIT license
- Django-Bolt documentation — getting started, auth/guards, middleware, streaming
- django-bolt on PyPI — release history (v0.9.0, July 5 2026) and install
- tanrax/python-api-frameworks-benchmark — independent Bombardier benchmark across FastAPI, Litestar, Django Ninja, Django-Bolt, and DRF, with methodology and caveats
Bottom line
Django-Bolt is the first thing I’ve seen that credibly offers Actix-class throughput without leaving Django behind, and it’s upfront about how it gets there: push HTTP, routing, and auth into Rust, keep your logic in Python, and let the database be the database. The 188K RPS headline is a hello-world number that evaporates under a real query, and the project is too young to trust with anything that pages you at night. But I’ll be watching the release notes closely. If the docs catch up and the API settles, this is how a lot of Django APIs will want to be served. For now, run the benchmark yourself, keep it off the critical path, and enjoy the fact that someone finally tried.