Use when building high-performance APIs with django-bolt - routing, JWT auth, msgspec serializers, WebSockets, SSE streaming, file uploads, ORM patterns, runbolt deployment, or migrating from DRF
Pro scans all 7 files and shows the line behind each finding
Scanned 10/2/2026
npx -y skills add CodeAtCode/oss-ai-skills --skill django-bolt --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Django Bolt?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/codeatcode-django-bolt)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: django-bolt
description: Use when building high-performance APIs with django-bolt - routing, JWT auth, msgspec serializers, WebSockets, SSE streaming, file uploads, ORM patterns, runbolt deployment, or migrating from DRF
metadata:
author: MT
version: 3.0.0
tags: python, django, bolt, api, rust, performance, async
---
# Django Bolt
Django Bolt is a high-performance Django framework that bypasses the Python GIL using Rust, delivering **300k+ RPS** for simple endpoints.
## Overview
Django Bolt combines Django's ORM and ecosystem with Rust's performance. Built on top of:
- **Hyper** (Rust HTTP server)
- **Tokio** (async runtime)
- **msgspec** (5-10x faster than Pydantic)
Key features:
- **Async ORM** - Native async/await support for Django ORM
- **Built-in WebSocket** - Real-time communication without channels
- **SSE Streaming** - Server-Sent Events for live updates
- **JWT Authentication** - Built-in auth with refresh token rotation
- **msgspec Serializers** - Fast schema validation and serialization
- **OpenAPI Docs** - Auto-generated at `/docs`
---
## Installation
```bash
pip install django-bolt
```
Add to `INSTALLED_APPS`:
```python
INSTALLED_APPS = [
...
"django_bolt",
]
```
---
## Quick Start
```python
# myapp/api.py
from django_bolt import BoltAPI
api = BoltAPI()
@api.get("/")
async def hello():
return {"message": "Hello, World!"}
@api.get("/users")
async def list_users():
users = await User.objects.all()
return [{"id": u.id, "username": u.username} for u in users]
```
Mount in `urls.py`:
```python
# myproject/urls.py
from django.urls import path
from myapp.api import api
urlpatterns = [
path("api/", api.urls),
]
```
Run:
```bash
python manage.py runbolt --dev
```
---
## Routing
### Basic Routes
```python
@api.get("/users")
@api.post("/users")
@api.put("/users/{pk}")
@api.delete("/users/{pk}")
@api.patch("/users/{pk}")
```
### Path Parameters
```python
@api.get("/users/{user_id}")
async def get_user(user_id: int):
user = await User.objects.aget(id=user_id)
return {"id": user.id, "username": user.username}
```
### Query Parameters
```python
@api.get("/users")
async def list_users(page: int = 1, limit: int = 10):
users = await User.objects.all()[limit*(page-1):limit*page]
return [{"id": u.id} for u in users]
```
### Request Body
```python
import msgspec
class UserCreate(msgspec.Struct):
username: str
email: str
@api.post("/users")
async def create_user(data: UserCreate):
user = await User.objects.acreate(username=data.username, email=data.email)
return {"id": user.id}, 201
```
### Middleware
```python
from django_bolt.middleware import CompressionMiddleware
api.add_middleware(CompressionMiddleware())
```
---
## Class-Based Views
### ViewSet
```python
from django_bolt.views import ViewSet, route
class UserViewSet(ViewSet):
@route.get("/users")
async def list(self, request):
users = await User.objects.alist()
return {"users": [{"id": u.id, "username": u.username} for u in users]}
@route.get("/users/{pk}")
async def retrieve(self, request, pk: int):
user = await User.objects.aget(id=pk)
return {"id": user.id, "username": user.username}
@route.post("/users")
async def create(self, request):
data = await request.json()
user = await User.objects.acreate(**data)
return {"id": user.id}
@route.put("/users/{pk}")
async def update(self, request, pk: int):
data = await request.json()
user = await User.objects.aget(id=pk)
for k, v in data.items():
setattr(user, k, v)
await user.asave()
return {"id": user.id}
@route.delete("/users/{pk}")
async def destroy(self, request, pk: int):
user = await User.objects.aget(id=pk)
await user.adelete()
return {"deleted": True}
api.register_viewset(UserViewSet, prefix="/api")
```
### ModelViewSet
```python
from django_bolt.views import ModelViewSet
from django.contrib.auth import get_user_model
from django_bolt.serializers import ModelSerializer
User = get_user_model()
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = ["id", "username", "email"]
class UserModelViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
api.register_viewset(UserModelViewSet, prefix="/api")
```
---
## OpenAPI / API Documentation
Django Bolt auto-generates OpenAPI 3.1 documentation.
### Access Docs
- **Swagger**: `/docs`
- **ReDoc**: `/redoc`
- **Scalar**: `/scalar`
- **RapidDoc**: `/rapiddoc`
### Configure OpenAPI
```python
from django_bolt import BoltAPI
from django_bolt.openapi import OpenAPIInfo
api = BoltAPI(
info=OpenAPIInfo(
title="My API",
version="1.0.0",
description="API description",
)
)
```
### Include/Exclude from Schema (v0.10.2+/0.11.0+)
```python
@api.get("/internal", include_in_schema=False)
async def internal_handler():
return {"secret": True}
```
---
## Testing
### Test Client
```python
from django_bolt.test import AsyncAPITestClient
class UserAPITest(AsyncAPITestClient):
async def test_create_user(self):
response = await self.post(
"/api/users",
json={"username": "testuser", "email": "test@example.com"}
)
self.assertEqual(response.status_code, 201)
data = await response.json()
self.assertEqual(data["username"], "testuser")
async def test_get_user(self):
user = await User.objects.acreate(username="testuser", email="test@example.com")
response = await self.get(f"/api/users/{user.id}")
self.assertEqual(response.status_code, 200)
```
**Note:** TestClient shares DB connection with handler threads for accurate concurrency testing.
---
## Performance Benchmarks
### Reference Setup
- **Hardware:** AMD Ryzen 5 5600G (6 cores / 12 threads), 16 GB RAM, Linux
- **Server:** `python manage.py runbolt --processes 8` (8 processes × 1 Actix worker)
- **Load generator:** [bombardier](https://github.com/codesenberg/bombardier), C=100, N=100000, loopback on same machine
- **Baseline comparisons:** Plain Django views, DRF, FastAPI, Litestar, JavaScript runtimes (see sources)
- **Run-to-run variance:** ±5% (gaps under ~10% are ties)
**Important:** The load generator shares the 12 cores with the 8 server processes, so numbers are a **floor**, not a ceiling. Absolute numbers are hardware-specific—always publish the conditions with the number.
### Key Results
| Endpoint Type | Req/s | What it measures |
|--------------|-------|------------------|
| JSON hello-world (`GET /`) | **311,270** | Routing + JSON serialization overhead |
| 10 KB JSON (sync handler) | **187,186** | Response serialization bottleneck |
| 10 KB JSON (async handler) | **184,059** | Async overhead negligible at scale |
| 10-row ORM query (SQLite) | **20,963–26,694** | Django ORM executor + SQLite file lock |
| JWT auth + DB load user | **40,312** | Rust JWT verify + ORM user fetch |
| Full middleware stack | **8,744** | Sessions, CSRF, auth, messages, CSP |
### What These Numbers Do NOT Tell You
- **Not per-request latency figures** — p50/p99 are available for select endpoints but these RPS numbers measure throughput under load
- **Excludes database time** for ORM benchmarks — measured with SQLite (single-writer file lock is the bottleneck); PostgreSQL uses more threads
- **Does not include network latency** — loopback test on same machine
- **Not a measure of developer productivity** — pure throughput comparison
### Cross-Framework Comparison (same machine, one process each, PostgreSQL)
Source: https://github.com/FarhanAliRaza/python-api-frameworks-benchmark (2026-08-30)
| Endpoint | Django-Bolt | Litestar + uvicorn | FastAPI + uvicorn |
|----------|-------------|-------------------|-------------------|
| 1 KB JSON | **43,541** | 15,477 | 7,517 |
| 10 KB JSON | **27,610** | 12,925 | 1,805 |
| 10 rows from PostgreSQL | **2,881** | 1,321 | 1,237 |
| JWT auth + load user | **4,478** | 1,155 | 941 |
### Reproduce
```bash
git clone https://github.com/dj-bolt/django-bolt.git && cd django-bolt
uv sync && just build
go install github.com/codesenberg/bombardier@latest
just save-bench # → python/benchmark/BENCHMARK.md
```
Source: https://bolt.farhana.li/benchmarks/ | https://github.com/dj-bolt/django-bolt/blob/master/python/benchmark/BENCHMARK.md
---
## Configuration
### Settings
```python
# settings.py
# Django-Bolt Configuration
BOLT = {
"HOST": "0.0.0.0",
"PORT": 8000,
"PROCESSES": 4,
"BACKLOG": 2048,
"KEEP_ALIVE": 30,
"DEBUG": False,
"EMIT_SIGNALS": False,
}
# JWT Configuration
JWT_SECRET_KEY = "your-secret-key"
JWT_ALGORITHM = "HS256"
JWT_EXPIRATION = 3600
# File Upload Settings
from django_bolt import FileSize
BOLT_MAX_UPLOAD_SIZE = FileSize.MB_50
BOLT_MEMORY_SPOOL_THRESHOLD = 5 * 1024 * 1024
# CORS Configuration
BOLT_CORS = {
"allow_origins": ["https://example.com"],
"allow_methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["*"],
"allow_credentials": True,
}
```
---
## Production Server: runbolt
### Worker Recycling (v0.11.0+)
```bash
# Recycle workers after memory threshold
python manage.py runbolt --max-rss 512000
# Limit worker lifetime
python manage.py runbolt --workers-lifetime 3600
# Auto-respawn failed workers
python manage.py runbolt --respawn-failed-workers
```
### Development Mode (v0.11.0+)
```bash
# Native Rust reloader
python manage.py runbolt --dev
# Custom reload directory
python manage.py runbolt --dev --reload-dir src/
```
---
## Best Practices
### Performance
1. **Use async ORM methods** - Always use `aget()`, `alist()`, `acreate()` in handlers
2. **Avoid N+1 queries** - Use `select_related()` for ForeignKey, `prefetch_related()` for ManyToMany
3. **Enable compression** - Use `CompressionMiddleware` for responses > 500 bytes
4. **Tune process count** - Set `--processes` to CPU core count for CPU-bound workloads
### Security
1. **Always validate input** - Use msgspec structs for request body validation
2. **Use HTTPS in production** - Terminate TLS at nginx/load balancer
3. **Configure BOLT_TRUSTED_PROXIES** - Required behind reverse proxies for accurate rate limiting
4. **Rotate JWT secrets** - Implement key rotation for long-lived deployments
### Maintainability
1. **Organize by feature** - Group related endpoints in feature modules
2. **Use dependency injection** - Extract reusable logic with `Depends()`
3. **Write tests** - Use `AsyncAPITestClient` for integration tests
4. **Document APIs** - Leverage auto-generated OpenAPI docs at `/docs`
---
## Command-Line Reference
```bash
# Development server with native Rust reloader
python manage.py runbolt --dev
# Production with custom settings
python manage.py runbolt --host 0.0.0.0 --port 8000 --processes 4
# Worker recycling
python manage.py runbolt --max-rss 512000 --workers-lifetime 3600
# Increase socket backlog
python manage.py runbolt --processes 4 --backlog 2048
# Adjust keep-alive timeout
python manage.py runbolt --processes 4 --keep-alive 30
# Skip startup checks
python manage.py runbolt --skip-checks
```
---
## Version Migration Gates
| Version | Breaking Change | Before / After |
|---------|-----------------|----------------|
| v0.4.0 | Python 3.12+ required | Requires upgrading runtime; no code changes |
| v0.6.0 | `SessionAuthentication` removed | **Before:**<br>`from django_bolt.auth import SessionAuthentication`<br>`api = BoltAPI(auth=[SessionAuthentication()])`<br><br>**After:**<br>Use `JWTAuthentication` or `APIKeyBearer` |
| v0.10.0 | Cookie-JWT CSRF check ON by default | **Before:**<br>`JWTAuthentication(cookie=True)`<br>(no CSRF check for API clients)<br><br>**After:**<br>`JWTAuthentication(cookie=False)`<br>for non-browser clients |
| v0.10.3 | `BOLT_TRUSTED_PROXIES` required behind proxies | **Before:**<br>(rate limiting shared across all callers behind proxy)<br><br>**After:**<br>`BOLT_TRUSTED_PROXIES = ["10.0.0.0/8", "192.168.0.0/16"]`<br>in settings.py |
| v0.11.0 | `Nested()` removed — use plain type hints | **Before:**<br>`author: Nested(AuthorSerializer)`<br><br>**After:**<br>`author: AuthorSerializer` |
---
## References
- **Official Docs**: https://bolt.farhana.li/
- **LLMs.txt**: https://bolt.farhana.li/llms.txt
- **Releases**: https://github.com/dj-bolt/django-bolt/releases
- **CHANGELOG**: https://github.com/dj-bolt/django-bolt/blob/main/CHANGELOG.md
- **Benchmarks**: https://bolt.farhana.li/benchmarks/
- **MCP Guide**: https://bolt.farhana.li/topics/mcp/
---
## Deep Dives
The following reference files contain detailed coverage of advanced topics. Load them on demand when working on specific features:
1. **auth-security.md** — Authentication, Permissions & Guards, Middleware, Rate Limiting, Error Handling
2. **responses-serialization.md** — Responses, msgspec Serializers, Pagination, Request Object, Dependency Injection
3. **websockets-uploads.md** — WebSockets, File Uploads
4. **orm-background.md** — Django ORM Patterns, Background Tasks
5. **deployment.md** — Deployment, MCP Servers
6. **drf-migration.md** — Comparison with DRF/Django Ninja, Migration from DRF
---
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!