A lightweight, high-performance API framework for Python with the elegance of FastAPI and the speed of light.
Tachyon API combines the intuitive decorator-based syntax you love with minimal dependencies and maximal performance. Built with Test-Driven Development from the ground up, it offers a cleaner, faster alternative with full ASGI compatibility.
from tachyon_api import Tachyon, Struct, Body, Query
app = Tachyon()
class User(Struct):
name: str
email: str
@app.get("/")
def hello():
return {"message": "Tachyon is running at lightspeed!"}
@app.post("/users")
def create_user(user: User = Body()):
return {"created": user.name}
@app.get("/search")
def search(q: str = Query(...), limit: int = Query(10)):
return {"query": q, "limit": limit}pip install tachyon-api
tachyon run # uvloop + httptools + reload, served at :8000๐ Docs: http://localhost:8000/docs
Benchmarked against FastAPI 0.136.1 (Pydantic v2) ยท 1 worker ยท 100 concurrent connections ยท uvloop + httptools ยท precompiled Cython extensions (shipped by default โ see below)
| Scenario | FastAPI | Tachyon | Speedup |
|---|---|---|---|
| Hello World | 10,314 req/s | 49,755 req/s | 4.82x |
| Path + query params | 7,166 req/s | 37,598 req/s | 5.25x |
| Body validation (Struct) | 8,371 req/s | 40,916 req/s | 4.89x |
| Nested body (complex Struct) | 8,027 req/s | 39,994 req/s | 4.98x |
| Response model serialization | 6,343 req/s | 47,561 req/s | 7.50x |
| Header param + auth | 8,701 req/s | 45,415 req/s | 5.22x |
| Dependency injection | 6,449 req/s | 45,610 req/s | 7.07x |
| Multiple query params | 6,264 req/s | 34,111 req/s | 5.45x |
| Total throughput | 61,635 req/s | 340,960 req/s | 5.53x |
Latency: ~2.3ms (Tachyon) vs ~13ms (FastAPI) on average.
Benchmark code in
benchmark/. Run withbash benchmark/run_benchmark.sh.
pip install tachyon-api ships prebuilt wheels with all 27 Cython extensions already compiled for:
| Platform | Architectures | CPython |
|---|---|---|
| Linux | x86_64, aarch64 | 3.10 ยท 3.11 ยท 3.12 ยท 3.13 |
| macOS | arm64 (Apple Silicon) | 3.10 ยท 3.11 ยท 3.12 ยท 3.13 |
| Windows | x86_64 | 3.10 ยท 3.11 ยท 3.12 ยท 3.13 |
No manual build step. No Cython required. The numbers above are what you get out of the box.
Not on the list? (macOS Intel, Alpine, etc.)
pipfalls back to the sdist and compiles from.pyxsource โ requires a C compiler andpip install tachyon-api[fast](which pulls in Cython). If compilation fails, the framework still works: runtime falls back to the pure-Python siblings of every.pyxmodule automatically.
Same code, same workload โ the only difference is whether the 27 Cython .so extensions are loaded:
| Scenario | Compiled | Pure-Python | ฮ |
|---|---|---|---|
| Hello World | 49,755 req/s | 47,899 req/s | +3.9% |
| Path + query params | 37,598 req/s | 31,901 req/s | +17.9% |
| Body โ simple Struct | 40,916 req/s | 35,623 req/s | +14.9% |
| Body โ nested Struct | 39,994 req/s | 35,204 req/s | +13.6% |
| Response model | 47,561 req/s | 40,604 req/s | +17.1% |
| Header param + auth | 45,415 req/s | 39,380 req/s | +15.3% |
| Dependency injection | 45,610 req/s | 38,552 req/s | +18.3% |
| Multiple query params | 34,111 req/s | 29,803 req/s | +14.5% |
| TOTAL | 340,960 req/s | 298,966 req/s | +14.0% |
The biggest wins concentrate on real framework work โ DI resolution (+18.3%), path/query parsing (+17.9%), response model (+17.1%), and validation (+13โ15%). Hello-world barely moves (+3.9%): the framework is already a tiny slice of that request.
- Radix trie routing โ O(k) path matching vs Starlette's O(Nรregex) scan; trie compiled to C
- Middleware bypass โ HTTP requests skip Starlette's
ServerErrorMiddlewareandExceptionMiddlewareentirely; exceptions handled directly in each closure - Endpoint pre-compilation โ
inspect.signature(),isinstancechains, type resolution, andmsgspec.Decodercreation run once at startup, not per request - No-Request fast path โ endpoints with no parameters skip
Request()creation and call the ASGI handler directly - msgspec โ validation and deserialization in C, 5โ10x faster than Pydantic
- Direct serialization โ
Structresponses usemsgspec.json.encode()directly (no Python intermediate step) - Pre-built ASGI dicts โ response send payloads constructed once in
__init__, not recreated per request - No middleware bloat โ Tachyon mounts only what you register; FastAPI adds ~15 middlewares by default
| Category | Features |
|---|---|
| Core | Decorators API, Routers, Middlewares, ASGI compatible |
| Parameters | Path, Query, Body (incl. Body(List[Struct])), Header, Cookie, Form, File (all with alias=) |
| Validation | msgspec Struct (ultra-fast), automatic 422 errors, configurable body size limit (default 2 MB) |
| DI | @injectable (3 scopes: singleton / request / transient), Depends() (sync + async), circular dep detection |
| Security | HTTPBearer, HTTPBasic, OAuth2, API Keys (Header / Query / Cookie), SecurityHeadersMiddleware (X-Frame-Options, CSP, HSTS, โฆ) |
| Async | Background Tasks (failures logged, not silenced), WebSockets with typed path params + DI |
| Performance | orjson serialization, @cache decorator, endpoint pre-compilation, 27 precompiled Cython extensions (shipped by default) |
| Docs | OpenAPI 3.0 (incl. List[Struct] arrays + multipart/form-data), Scalar UI, Swagger, ReDoc (XSS-safe HTML generation) |
| CLI | Project scaffolding, code generation, linting, AI-agent skill installer |
| Testing | TachyonTestClient (sync), create_client() (async, full httpx kwargs), dependency_overrides |
| Architecture | Atomic SRP modules across app/, processing/, responses/, openapi/, security/ โ 27 compiled to .so for the hot path (v1.2.x refactor + v1.2.9 Cython sprint) |
| Guide | Description |
|---|---|
| Getting Started | Installation and first project |
| Architecture | Clean architecture patterns |
| Dependency Injection | @injectable and Depends() |
| Parameters | Path, Query, Body, Header, Cookie, Form, File |
| Validation | msgspec Struct validation |
| Security | JWT, Basic, OAuth2, API Keys |
| Caching | @cache decorator |
| Lifecycle Events | Startup/Shutdown |
| Background Tasks | Async task processing |
| WebSockets | Real-time communication |
| Testing | TachyonTestClient |
| CLI Tools | Scaffolding and generation |
| Request Lifecycle | How requests are processed |
| Migration from FastAPI | Migration guide |
| Best Practices | Recommended patterns |
| Cython Build | Precompiled wheels, source builds, and the .py/.pyx fallback model |
A complete example demonstrating all Tachyon features is available in example/:
cd example
pip install -r requirements.txt
tachyon run example.app:appThe KYC Demo exercises every v1.2.x feature:
- ๐ JWT Authentication + API Keys
- ๐ค Customer CRUD + bulk endpoint (
Body(List[Struct])) - ๐ KYC Verification with Background Tasks
- ๐ Document Uploads (
multipart/form-data) - ๐ WebSocket โ legacy plain-string + modern DI-injected with
room_id: uuid.UUID - ๐ DI scopes โ
singleton(services),request(correlation context),transient(ID generator) - ๐ก๏ธ Security headers + opt-in CORS allow-list
- ๐จ Custom exception handler for the
KYCExceptionhierarchy - ๐งช 17 tests (
pytest example/tests/), including async tests viacreate_client
Demo credentials: [email protected] / demo123
๐ See example/README.md for full details.
| Package | Purpose |
|---|---|
starlette |
ASGI framework |
msgspec |
Ultra-fast validation/serialization |
orjson |
High-performance JSON |
uvicorn |
ASGI server |
Tachyon's request hot path is a thin chain of composed collaborators โ every piece is single-responsibility and ready for Cython compilation:
client
โ
โโโ Tachyon.__call__ (ASGI entry โ sets scope["app"])
โ โ
โ โโโ ASGIEntry lazy build of HTTP app
โ โ
โ โโโ HTTPDispatcher HTTP โ trie ยท WS/lifespan โ Starlette
โ โ
โ โโโ MiddlewareStack user-registered middlewares (CORS, Securityโฆ)
โ โ
โ โโโ TachyonDispatcher (Cython cdef) โ radix trie match O(k)
โ โ
โ โโโ _ASGIHandler (no-param fast path, 2 sends only)
โ โ
โ โโโ handler closure
โ โโโ ParameterPipeline โ 8 atomic extractors
โ โ (body / query / query-list / header / cookie / form / file / path)
โ โโโ DependencyResolver โ OverrideLookup / ScopeCache /
โ โ ClassFactory / CallableFactory
โ โโโ ResponseProcessor (msgspec encode if Struct)
โ โโโ ExceptionTable (walks subclass handlers)
โ
โโโ TachyonJSONResponse | TachyonBytesResponse | _InternalErrorResponse
(pre-built ASGI dicts, zero extra allocations per response)
The v1.2.x SRP refactor decomposed the monolithic hot path into atomic modules
with __slots__ and full type hints โ direct cdef class candidates. The
v1.2.9 Cython sprint then compiled 27 of them to .so, keeping every .py
sibling as a transparent fallback (Python prefers .so automatically).
๐ Full architecture documentation
from tachyon_api import injectable, Depends
@injectable # singleton (default) โ one per app
class DB:
def __init__(self):
self.pool = "..."
@injectable(scope="request") # one per HTTP request
class RequestContext:
def __init__(self):
import uuid
self.correlation_id = str(uuid.uuid4())
@injectable(scope="transient") # new instance every time it's injected
class IdGenerator:
def __init__(self):
self._seq = 0
@app.get("/users/{id}")
def get_user(id: str, db: DB = Depends(), ctx: RequestContext = Depends()):
return {"id": id, "trace": ctx.correlation_id}from tachyon_api.security import HTTPBearer, OAuth2PasswordBearer
bearer = HTTPBearer()
@app.get("/protected")
async def protected(credentials = Depends(bearer)):
return {"token": credentials.credentials}๐ Full Security documentation
from tachyon_api.background import BackgroundTasks
@app.post("/notify")
def notify(background_tasks: BackgroundTasks):
background_tasks.add_task(send_email, "[email protected]")
return {"status": "queued"}๐ Full Background Tasks documentation
import uuid
from tachyon_api import injectable, Depends
@injectable
class RoomBroadcaster:
async def join(self, ws, room_key: str): ...
@app.websocket("/ws/rooms/{room_id}") # typed UUID path param
async def room(
websocket,
room_id: uuid.UUID, # auto-converted; 1008 on mismatch
broadcaster: RoomBroadcaster = Depends(), # @injectable DI in WS
):
await broadcaster.join(websocket, str(room_id))
while True:
await websocket.send_json({"room": str(room_id)})๐ Full WebSockets documentation
# Create project (generates .env.example, config.py with dotenv, clean arch)
tachyon new my-api
# Start development server (uvloop + httptools auto-detected, reload on)
tachyon run
# List all registered routes
tachyon routes
# Generate a full CRUD module
tachyon g service users --crud
# Generate an ASGI middleware skeleton
tachyon g middleware auth
# Code quality
tachyon lint allName validation: hyphens auto-converted to underscores (my-api โ my_api), Python keywords rejected with a clear error.
Teach your AI coding assistant (Claude Code, Cursor, Copilot, OpenCode, Codex) how to write correct Tachyon code:
tachyon install-skill # generates context files for all tools
tachyon install-skill --cursor # only .cursorrules
tachyon install-skill --claude # only CLAUDE.md
tachyon install-skill --copilot # only .github/copilot-instructions.mdInstalls knowledge about Body() requirement, Struct vs BaseModel, DI patterns, CLI commands, and anti-patterns. Safe to run multiple times.
# Sync โ Starlette TestClient compatible
from tachyon_api.testing import TachyonTestClient
def test_hello():
client = TachyonTestClient(app)
assert client.get("/").status_code == 200
# Async โ httpx.AsyncClient over ASGI transport
import pytest
from tachyon_api.testing import create_client
@pytest.mark.asyncio
async def test_hello_async():
async with create_client(app, headers={"X-Trace": "abc"}) as client:
response = await client.get("/")
assert response.status_code == 200pytest tests/ -v๐ Full Testing documentation
| Feature | Tachyon | FastAPI |
|---|---|---|
| Throughput | ~341k req/s total | ~62k req/s total |
| Latency | ~2.3ms avg | ~14ms avg |
| Routing | Radix trie O(k) | Regex scan O(N) |
| Serialization | msgspec + orjson | Pydantic v2 |
| Request compilation | Once at startup | Per request |
| Middleware overhead | User-only stack | +2 auto middleware layers |
| Bundle size | Minimal (4 deps) | Larger (~15 deps) |
| Learning curve | Easy (FastAPI-like) | Easy |
| Type safety | Full (msgspec Struct) | Full (Pydantic) |
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests (
pytest tests/ -v) - Commit your changes
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
See CHANGELOG.md for version history.
Upcoming:
- Response streaming
- GraphQL support
- Multi-worker benchmarks
- Benchmark suite vs Litestar / BlackSheep / Robyn
- SQLAlchemy async integration guide
Built with ๐ by developers, for developers