Rust-Powered Engine

Hurricane 2.0 replaced Tornado's Python asyncio event loop with Granian, a lightning-fast HTTP server built directly on Rust’s Hyper and Tokio runtimes.


Architecture Overview

Rendering diagram...

Why Rust Over Python Event Loops?

Previous versions of Hurricane used Tornado to bridge asynchronous networking with Django's synchronous WSGI layer. Under high concurrency, Python's single-threaded event loop became a bottleneck:

  1. GIL Contention: Switching between Python coroutines and worker thread pools incurred high CPU context-switching overhead.
  2. Buffer Saturation: Large file uploads or request storms flooded Python's memory heap before threads could process them.
  3. Event Loop Starvation: Blocking C libraries or compute-heavy tasks temporarily froze probe responsiveness.

With Granian:

  • Rust Handles the Network: Socket connection management, TLS termination, HTTP 1.1/2 parsing, and keep-alive pools run entirely in compiled Rust without touching Python or the Global Interpreter Lock (GIL).
  • Native Thread Workers: For WSGI applications, Granian's WSGIWorker manages OS worker threads directly from Rust, invoking the WSGI callable only when a worker thread is free.
  • Zero-Copy File Streaming: Static and media files are streamed with minimal memory footprint.

Zero-Config WSGI & ASGI Auto-Detection

Hurricane automatically inspects your Django configuration on boot and switches to the optimal engine without requiring manual flags:

Rendering diagram...
  • Classic Django Projects: If WSGI_APPLICATION = "myproject.wsgi.application" is present, Hurricane boots with Granian's multithreaded WSGI engine.
  • Async & Channels Projects: If ASGI_APPLICATION = "myproject.asgi.application" is configured, Hurricane automatically runs with Granian's asynchronous ASGI engine.
  • Manual Override: You can force a specific execution mode via the --mode flag (or MODE in settings.py):
    python manage.py serve --mode=asgi
    
    (The legacy --interface flag remains supported as an alias).

⚡ Comparative Benchmarks: Tornado vs. Granian

We pit the classic Tornado-based Hurricane against the new Granian-powered engine using Locust under identical high-concurrency conditions:

MetricTornado BaselineGranian (New Engine) 🦀Difference
False Readiness Failures (HTTP 400)160 flapping events0 events-100.0% (Eliminated!)
Peak Throughput (RPS)313.3 req/s630.9 req/s+101.4% (2x faster)
P50 Median Latency130.0 ms66.0 ms-49.2% (Half the wait)
P99 Tail Latency220.0 ms120.0 ms-45.5% faster
Probe Latency Under Load170.0 ms94.0 ms-44.7% faster

Under heavy traffic, Tornado mistook pending asyncio task counts for saturated request backlogs, triggering 160 false unready events that pulled pods out of service endpoints. Granian completely eliminates false unready flaps while doubling throughput.

Explore the reproducible benchmark suite, load scenarios, and raw result datasets at django-hurricane/django-hurricane-bench on GitHub.

Card title

Card description