FastAPI-compatible web framework with Rust HTTP core - 2-3x faster with Python 3.13 free-threading
Project description
TurboAPI
The FastAPI you know. The speed you deserve.
Meet Turbito — the tiny Rust-powered engine that makes your FastAPI fly.
The Problem • The Solution • Meet Turbito • Quick Start • What's New • Benchmarks
The Problem
You love FastAPI. The clean syntax. The automatic validation. The beautiful docs. But then you deploy to production, and the reality hits:
"Why is my simple API only handling 8,000 requests per second?"
You've optimized your database queries. Added caching. Switched to async. Still not fast enough. The bottleneck isn't your code—it's the framework itself.
Python's GIL (Global Interpreter Lock) means only one thread executes Python code at a time. JSON serialization happens in pure Python. HTTP parsing happens in pure Python. Every microsecond adds up.
The Solution
TurboAPI is FastAPI with a Rust-powered engine. Same API. Same syntax. 1.3-1.8x faster.
# This is all you change
from turboapi import TurboAPI as FastAPI
Everything else stays exactly the same.
Why It's Faster
| What FastAPI Does | What TurboAPI Does | Speedup |
|---|---|---|
| HTTP parsing in Python | HTTP parsing in Rust (Hyper/Tokio) | 3x |
JSON with json.dumps() |
SIMD-accelerated JSON (simd-json) | 2x |
| GIL-bound threading | Python 3.13 free-threading | 2x |
| dict-based routing | Radix tree with O(log n) lookup | 1.5x |
| Async via asyncio | Async via Tokio work-stealing | 1.2x |
The result? Your existing FastAPI code runs faster without changing a single line of business logic.
Meet Turbito
Turbito is the little engine inside TurboAPI.
While you write normal FastAPI code, Turbito is:
- Parsing HTTP in Rust (Hyper/Tokio)
- Serializing JSON with SIMD acceleration
- Scheduling async work with Tokio's work-stealing scheduler
- Dodging the GIL like a speed demon
You never see Turbito. You just feel the speed.
What's New
v0.5.21 — Free-Threading Stability Release
This release fixes critical issues when running with free-threaded Python (3.13t) and Metal/MLX GPU frameworks:
| Fix | Description |
|---|---|
| Memory Corruption | Fixed race condition where request body bytes were corrupted when using async handlers with MLX models loaded |
| Response Serialization | Response objects now properly serialize their content instead of string representation |
| Async BaseModel | Async handlers with BaseModel parameters now correctly receive the validated model instance |
| JSON Parsing | Added Python fallback for edge cases where simd-json is too strict |
Technical Deep Dive: When running free-threaded Python with Metal GPU frameworks, memory can be accessed concurrently by the CPU and GPU. We now use defensive copying (PyBytes::new() in Rust, bytes(bytearray()) in Python) to ensure request data is isolated before processing.
# Upgrade to get the fixes
pip install --upgrade turboapi
Quick Start
Installation
pip install turboapi
Requirements: Python 3.13+ (free-threading recommended for best performance)
Hello World
from turboapi import TurboAPI
app = TurboAPI()
@app.get("/")
def hello():
return {"message": "Hello World"}
app.run()
That's it. Your first TurboAPI server is running at http://localhost:8000.
Async Handlers (New!)
TurboAPI now supports true async with Tokio-powered execution:
from turboapi import TurboAPI
import asyncio
app = TurboAPI()
@app.get("/sync")
def sync_handler():
return {"type": "sync", "message": "Fast!"}
@app.get("/async")
async def async_handler():
await asyncio.sleep(0.001) # Simulated I/O
return {"type": "async", "message": "Even faster under load!"}
app.run()
Async handlers are automatically detected and routed through Tokio's work-stealing scheduler for optimal concurrency.
Let Turbito Off the Leash
For maximum performance, run with Python's free-threading mode:
PYTHON_GIL=0 python app.py
This unlocks Turbito's full power by removing the GIL bottleneck. True parallelism, finally.
Benchmarks
Real numbers matter. Here's TurboAPI vs FastAPI on identical hardware:
Latest Benchmark Results
| Endpoint | TurboAPI | FastAPI | Improvement |
|---|---|---|---|
| Sequential Latency | |||
| GET / | 0.76ms | 1.05ms | 1.4x faster |
| GET /benchmark/simple | 0.61ms | 0.81ms | 1.3x faster |
| GET /benchmark/medium | 0.61ms | 0.77ms | 1.3x faster |
| GET /benchmark/json | 0.72ms | 1.04ms | 1.4x faster |
| Concurrent Latency | |||
| GET / | 2.05ms | 2.53ms | 1.2x faster |
| GET /benchmark/json | 2.17ms | 3.90ms | 1.8x faster |
Throughput (requests/second)
| Endpoint | TurboAPI | FastAPI | Speedup |
|---|---|---|---|
| GET / (hello world) | 19,596 | 8,336 | 2.4x |
| GET /json (object) | 20,592 | 7,882 | 2.6x |
| GET /users/{id} (path params) | 18,428 | 7,344 | 2.5x |
| POST /items (model validation) | 19,255 | 6,312 | 3.1x |
Async Handler Performance
| Metric | Sync Handler | Async Handler | Notes |
|---|---|---|---|
| Sequential (100 req) | 0.66ms | 0.76ms | Similar performance |
| Concurrent (200 req) | 108ms batch | 139ms batch | Sync faster for CPU-bound |
| I/O Wait (1ms sleep) | 2.22ms | 2.06ms | Async wins for I/O |
Key Insight: Use async handlers when you have actual I/O operations (database, network). For pure CPU work, sync handlers are slightly faster.
Run Your Own Benchmarks
# Quick benchmark
python benches/python_benchmark.py
# Full comparison with FastAPI
python tests/benchmark_comparison.py
# Async vs Sync comparison
python benches/async_comparison_bench.py
Async Support
How Async Works in TurboAPI
TurboAPI uses a hybrid async architecture:
┌─────────────────────────────────────────────────────────┐
│ Your Python Handlers │
│ @app.get("/sync") @app.get("/async") │
│ def handler(): async def handler(): │
├─────────────────────────────────────────────────────────┤
│ Handler Classification │
│ simple_sync │ body_sync │ simple_async │ body_async │
├─────────────────────────────────────────────────────────┤
│ Tokio Runtime (Rust) │
│ Work-stealing scheduler • 14 workers │
├─────────────────────────────────────────────────────────┤
│ pyo3-async-runtimes │
│ Python coroutines ↔ Rust futures conversion │
└─────────────────────────────────────────────────────────┘
Handler Types
TurboAPI automatically classifies handlers for optimal dispatch:
| Handler Type | Description | Use Case |
|---|---|---|
simple_sync |
Sync, no body | GET endpoints |
body_sync |
Sync, with body | POST/PUT without complex types |
model_sync |
Sync, with model validation | POST with dhi models |
simple_async |
Async, no body | GET with I/O operations |
body_async |
Async, with body | POST/PUT with I/O operations |
enhanced |
Full Python wrapper | Complex dependencies |
When to Use Async
# Use sync for pure computation
@app.get("/compute")
def compute():
result = sum(i * i for i in range(1000))
return {"result": result}
# Use async for I/O operations
@app.get("/fetch-data")
async def fetch_data():
async with aiohttp.ClientSession() as session:
async with session.get("https://api.example.com/data") as resp:
return await resp.json()
# Use async for database operations
@app.get("/users/{user_id}")
async def get_user(user_id: int):
user = await database.fetch_one(query, values={"id": user_id})
return {"user": user}
Migration Guide
TurboAPI is designed as a drop-in replacement for FastAPI. Here's how to migrate:
Step 1: Change Your Imports
# Before (FastAPI)
from fastapi import FastAPI, Depends, HTTPException, Query, Path
from fastapi.responses import JSONResponse, HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
# After (TurboAPI)
from turboapi import TurboAPI as FastAPI, Depends, HTTPException, Query, Path
from turboapi.responses import JSONResponse, HTMLResponse
from turboapi.middleware import CORSMiddleware
Step 2: Update Your Models
TurboAPI uses dhi instead of Pydantic (it's API-compatible):
# Before (Pydantic)
from pydantic import BaseModel
# After (dhi)
from dhi import BaseModel
Step 3: Run Your App
# FastAPI way still works
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
# Or use TurboAPI's built-in server (faster)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
That's it. Your FastAPI app is now a TurboAPI app.
Feature Parity
Everything you use in FastAPI works in TurboAPI:
| Feature | Status | Notes |
|---|---|---|
| Route decorators (@get, @post, etc.) | ✅ | Full parity |
| Path parameters | ✅ | With type coercion |
| Query parameters | ✅ | With validation |
| Request body (JSON) | ✅ | SIMD-accelerated |
| Response models | ✅ | Full support |
| Async handlers | ✅ | Tokio-powered |
| Dependency injection | ✅ | Depends() with caching |
| OAuth2 authentication | ✅ | Password & AuthCode flows |
| HTTP Basic/Bearer auth | ✅ | Full implementation |
| API Key auth | ✅ | Header/Query/Cookie |
| CORS middleware | ✅ | Rust-accelerated |
| GZip middleware | ✅ | Configurable |
| Background tasks | ✅ | Async-compatible |
| WebSocket | ✅ | HTTP upgrade support |
| HTTP/2 | ✅ | With server push |
| APIRouter | ✅ | Prefixes and tags |
| HTTPException | ✅ | With custom headers |
| Custom responses | ✅ | JSON, HTML, Redirect, etc. |
Real-World Examples
API with Authentication
from turboapi import TurboAPI, Depends, HTTPException
from turboapi.security import OAuth2PasswordBearer
app = TurboAPI(title="My API", version="1.0.0")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.get("/users/me")
def get_current_user(token: str = Depends(oauth2_scheme)):
if token != "secret-token":
raise HTTPException(status_code=401, detail="Invalid token")
return {"user": "authenticated", "token": token}
Async Database Access
from turboapi import TurboAPI
import asyncpg
app = TurboAPI()
pool = None
@app.on_event("startup")
async def startup():
global pool
pool = await asyncpg.create_pool("postgresql://localhost/mydb")
@app.get("/users/{user_id}")
async def get_user(user_id: int):
async with pool.acquire() as conn:
row = await conn.fetchrow("SELECT * FROM users WHERE id = $1", user_id)
return dict(row) if row else {"error": "Not found"}
Request Validation
from dhi import BaseModel, Field
from typing import Optional
class CreateUser(BaseModel):
name: str = Field(min_length=1, max_length=100)
email: str = Field(pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
age: Optional[int] = Field(default=None, ge=0, le=150)
@app.post("/users")
def create_user(user: CreateUser):
return {"created": True, "user": user.model_dump()}
CORS and Middleware
from turboapi.middleware import CORSMiddleware, GZipMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://yourapp.com"],
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(GZipMiddleware, minimum_size=1000)
Architecture
TurboAPI's secret is a hybrid architecture where Python meets Rust:
┌──────────────────────────────────────────────────────────┐
│ Your Python Application │
│ (exactly like FastAPI code) │
├──────────────────────────────────────────────────────────┤
│ TurboAPI (FastAPI-compatible layer) │
│ Routing • Validation • Dependency Injection │
├──────────────────────────────────────────────────────────┤
│ Handler Classification (Phase 3+4) │
│ simple_sync │ body_sync │ simple_async │ body_async │
├──────────────────────────────────────────────────────────┤
│ PyO3 Bridge (zero-copy) │
│ Rust ↔ Python with minimal overhead │
├──────────────────────────────────────────────────────────┤
│ TurboNet (Rust HTTP Core) │
│ • Hyper + Tokio async runtime (14 worker threads) │
│ • SIMD-accelerated JSON (simd-json) │
│ • Radix tree routing │
│ • Zero-copy response buffers │
│ • pyo3-async-runtimes for async handler support │
└──────────────────────────────────────────────────────────┘
Python handles the logic you care about. Routes, validation rules, business logic—all in Python.
Rust handles the heavy lifting. HTTP parsing, JSON serialization, connection management—the parts that need to be fast.
The result: FastAPI's developer experience with systems-level performance.
Building from Source
Want to contribute or build from source?
git clone https://github.com/justrach/turboAPI.git
cd turboAPI
# Create venv with Python 3.13 free-threading
python3.13t -m venv venv
source venv/bin/activate
# Build the Rust extension
pip install maturin
maturin develop --release
# Install Python package
pip install -e ./python
# Run tests
PYTHON_GIL=0 python -m pytest tests/ -v
# Run benchmarks
python benches/python_benchmark.py
python tests/benchmark_comparison.py
Roadmap
Completed ✅
- Rust HTTP core (Hyper/Tokio)
- SIMD JSON serialization & parsing
- Python 3.13 free-threading support
- FastAPI feature parity (OAuth2, Depends, Middleware)
- Radix tree routing with path parameters
- Handler classification for optimized fast paths
- Async handler optimization (Tokio + pyo3-async-runtimes)
- WebSocket HTTP upgrade support
- HTTP/2 with server push
In Progress 🚧
- OpenAPI/Swagger auto-generation
Planned 📋
- GraphQL support
- Database connection pooling
- Prometheus metrics
- Distributed tracing
- gRPC support
Community
- Issues & Features: GitHub Issues
- Discussions: GitHub Discussions
- Documentation:
License
MIT License. Use it, modify it, ship it.
Built for developers who love FastAPI.
Powered by Turbito ⚡
pip install turboapi
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file turboapi-0.5.22.tar.gz.
File metadata
- Download URL: turboapi-0.5.22.tar.gz
- Upload date:
- Size: 2.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40d0d22bd302df4a50c5a7f6b6b44e08f5dc6afeb27325255b114196cebb6eba
|
|
| MD5 |
ece7e6d5764e1cdc8609422eaa4a1632
|
|
| BLAKE2b-256 |
f725a18ab80da8461e7bbff633d2b1f982168d13c32377d23065f16f32bcc207
|
File details
Details for the file turboapi-0.5.22-cp314-cp314t-macosx_11_0_arm64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314t-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.14t, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
757ef36ca1f3e71075dc92db26ffbc15c42f83264d6f3c29b54e84cda0d3fae4
|
|
| MD5 |
99084082ea1fe92a1d1689fe478ea5f6
|
|
| BLAKE2b-256 |
680f68284a5b28f520ceee39e6ba2ad0f9cbf6e93fbdae27fcc3cef0a4796fb9
|
File details
Details for the file turboapi-0.5.22-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d6699a5501891ab8bc3db77602e1c404cf56e72900315ace50f29a033e43065
|
|
| MD5 |
b3378bfeaa2d928076f604af6a3b69db
|
|
| BLAKE2b-256 |
081e6c77de104f6ec3af0ca1fd44ea66d47d214160eb70df286a756a50784b74
|
File details
Details for the file turboapi-0.5.22-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.14, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e68e869935db9165a94228ff76307d9b4bef3199e20821838092cf83922ebf2
|
|
| MD5 |
5a5c7fba8faded1a9aeab9850544c557
|
|
| BLAKE2b-256 |
de427257ec0bca3f84dc07b7f8fa9d3d0fce766c87f55d025b35bce91d76f665
|
File details
Details for the file turboapi-0.5.22-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.14, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
287b50521b98e9f0c0e6a01d467bf14830d6b0647742844741b62f96c8de212e
|
|
| MD5 |
4ac2baa4d1c36084510c9e7c78787e91
|
|
| BLAKE2b-256 |
648667099c46bbf171a26afe56aad397c9cd56b2b14d7ab37211a2c0319e34c9
|
File details
Details for the file turboapi-0.5.22-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f2de34a0a83c92ac948c46bc6891589e1330c61fad591505ae19955fc5e1286
|
|
| MD5 |
efbec83881489d4ac958e798c430b216
|
|
| BLAKE2b-256 |
a5ce411495a8d5f1ba8c54c21f5701b499ce29bca9d0479ce7f408197ec2e0e9
|
File details
Details for the file turboapi-0.5.22-cp314-cp314-macosx_10_12_x86_64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp314-cp314-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.14, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c68198480fe2c6f61c9a1b56413cb0cf9f2e5a1abb5c4776c461eca68c7c7ef4
|
|
| MD5 |
fa8aec2830de35f2a789c59d32fae504
|
|
| BLAKE2b-256 |
ae8fb52f3b3aee55df83a5443b8fe4f2414b22a8ce44e5f1b2a4cf5e30fedbce
|
File details
Details for the file turboapi-0.5.22-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee2fe86fd66a71f72e7e46b2cb095fcfad7744d780510fc96c1d0be0cd5d7b37
|
|
| MD5 |
e5e515b3d5503f6381745049265139d4
|
|
| BLAKE2b-256 |
7f4702dcf5a4ea5556986a463f7c48a9e55c880eab6cab6cdb258f98649cf14f
|
File details
Details for the file turboapi-0.5.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d85b805b85a3d1fa096b94b2ec50fa242cf2c8dbf6daf5fd24c0838b7bfe2245
|
|
| MD5 |
626f1d56ef6a95956f5f1464bd0b2baf
|
|
| BLAKE2b-256 |
950f0094c3581e187758313b725f1dbad87fd5d6cf2ba5dabb56914eb92c239a
|
File details
Details for the file turboapi-0.5.22-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d9d0079fbedd98d5adbc63ced0e5f5eea04259ffc2d0c5c7d20a4c835d23c58
|
|
| MD5 |
c2dfd8a68ddc39f061fe86a4a2f6bfb1
|
|
| BLAKE2b-256 |
9e43b047471cf4f0e38b3dfd9984e39cac093e63ad95a47605a14fbe2c6620d9
|
File details
Details for the file turboapi-0.5.22-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7446011e78c41a65c52c4256502d9c5a1427cfd71ae0c009ba75e48066dd0eb6
|
|
| MD5 |
16e59975be5d2a0616f3478f9720dc67
|
|
| BLAKE2b-256 |
db8206367ac3bb046d01a066a06d98bdafd015405ec079092b6099cb496854a1
|
File details
Details for the file turboapi-0.5.22-cp313-cp313-macosx_10_12_x86_64.whl.
File metadata
- Download URL: turboapi-0.5.22-cp313-cp313-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.13, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44779244907f2217025fb037d43fdc0fde677414611e3527431966c66e614b20
|
|
| MD5 |
667b615b3e03a760edf721bf0cb892a1
|
|
| BLAKE2b-256 |
c3c61d57f65ffd81d4017c14f1ffb73a89c8a339b5a9f416374b13c66a0c1b2d
|