Granian Server
Granian is a high-performance Rust HTTP server for Python applications. It supports ASGI, WSGI, and RSGI interfaces with HTTP/1.1 and HTTP/2 protocols.
Why Granian?
- Performance: ~50,000 req/s vs Uvicorn's ~45,000 req/s in benchmarks
- Memory: ~15MB base footprint per worker
- HTTP/2: Native h2c (HTTP/2 cleartext) support
- Rust: Memory-safe, no GIL contention in the server layer
Installation
pip install granian
Command Line Usage
ASGI (FastAPI)
# Basic
granian --interface asgi myapp.main:app
# With workers and HTTP/2
granian --interface asgi --workers 4 --http 2 myapp.main:app
# Full configuration
granian --interface asgi \
--host 0.0.0.0 \
--port 8000 \
--workers 4 \
--runtime-threads 2 \
--http 2 \
--loop uvloop \
myapp.main:app
WSGI (Django)
# Basic
granian --interface wsgi myapp.wsgi:application
# With workers and HTTP/2
granian --interface wsgi --workers 4 --http 2 myapp.wsgi:application
Programmatic Usage
ASGI Configuration
"""Granian ASGI server configuration example.
Shows how to run FastAPI applications with Granian.
"""
from granian import Granian
from granian.constants import HTTPModes, Interfaces, Loops
# Basic ASGI configuration
server = Granian(
target="myapp.main:app",
address="0.0.0.0",
port=8000,
interface=Interfaces.ASGI,
workers=4,
)
# With HTTP/2 support (h2c - HTTP/2 cleartext)
server_h2 = Granian(
target="myapp.main:app",
address="0.0.0.0",
port=8000,
interface=Interfaces.ASGI,
workers=4,
runtime_threads=2,
http=HTTPModes.http2, # Enable HTTP/2
loop=Loops.uvloop, # Use uvloop for better performance
)
# Start the server
# server.serve()
WSGI Configuration
"""Granian WSGI server configuration example.
Shows how to run Django applications with Granian.
"""
from granian import Granian
from granian.constants import HTTPModes, Interfaces
# Basic WSGI configuration for Django
server = Granian(
target="myapp.wsgi:application",
address="0.0.0.0",
port=8000,
interface=Interfaces.WSGI,
workers=4,
)
# With HTTP/2 support
server_h2 = Granian(
target="myapp.wsgi:application",
address="0.0.0.0",
port=8000,
interface=Interfaces.WSGI,
workers=4,
blocking_threads=2,
http=HTTPModes.http2,
)
# Start the server
# server.serve()
HTTP/2 and h2c
Granian supports HTTP/2 over cleartext (h2c) which is useful for internal services behind a load balancer that terminates TLS.
HTTP Modes
| Mode | Value | Description |
|---|---|---|
| Auto | auto |
Automatic detection (default) |
| HTTP/1.1 | 1 |
Force HTTP/1.1 only |
| HTTP/2 | 2 |
Force HTTP/2 (h2c) |
h2c Client Testing
# HTTP/2 with prior knowledge (direct h2c)
curl --http2-prior-knowledge http://localhost:8000/
# HTTP/1.1 to HTTP/2 upgrade (may not work with all servers)
curl --http2 http://localhost:8000/
h2c Upgrade Limitation
The HTTP/1.1 to HTTP/2 upgrade mechanism (curl --http2) may not work with Granian. Use --http2-prior-knowledge for direct HTTP/2 connections, or use HTTPS where ALPN handles protocol negotiation.
Configuration Options
| Option | CLI Flag | Default | Description |
|---|---|---|---|
| Interface | --interface |
rsgi |
asgi, wsgi, or rsgi |
| Host | --host |
127.0.0.1 |
Bind address |
| Port | --port |
8000 |
Bind port |
| Workers | --workers |
1 |
Number of worker processes |
| Runtime Threads | --runtime-threads |
1 |
Async runtime threads (ASGI) |
| Blocking Threads | --blocking-threads |
auto | Threads for blocking ops (WSGI) |
| HTTP | --http |
auto |
HTTP version: auto, 1, 2 |
| Loop | --loop |
auto |
Event loop: auto, asyncio, uvloop |
| Backlog | --backlog |
1024 |
Socket backlog size |
| Backpressure | --backpressure |
- | Max concurrent requests per worker |
Production Recommendations
Worker Count
# CPU-bound: match CPU cores
granian --workers $(nproc) --interface asgi myapp.main:app
# I/O-bound: 2-4x CPU cores
granian --workers $(($(nproc) * 2)) --interface asgi myapp.main:app
With Application Kit
For FastAPI applications using Application Kit:
# Development
DEVELOPMENT=yes granian --interface asgi \
--workers 1 \
--reload \
myapp.main:app
# Production with HTTP/2
granian --interface asgi \
--workers 4 \
--runtime-threads 2 \
--http 2 \
--backpressure 256 \
myapp.main:app
See Also
- Granian GitHub
- Running Your App - Overview and quick start