FastAPI 호환 Python 프레임워크, Zig HTTP 코어로 14배 빠름 — TurboAPI
요약
기사 전체 정리
FastAPI를 Zig HTTP 코어로 교체하면 14배 빨라진다 — TurboAPI
FastAPI 코드베이스 그대로 두고 HTTP 처리만 Zig으로 바꿔치기 하는 실험적 프레임워크 TurboAPI가 공개됨. 아직 알파 단계지만 벤치마크 수치가 꽤 인상적임.
이게 뭔가
Python은 그대로, HTTP 파싱·라우팅·유효성 검사·응답 직렬화는 전부 Zig이 처리하는 구조임. FastAPI와 호환되는 라우트 데코레이터(@get, @post 등)를 그대로 쓰면서 속도만 올리는 게 목표임.
핵심 아이디어: Python은 비즈니스 로직만 실행. 나머지는 다 Zig.
벤치마크: HTTP-only (캐시 비활성화 기준)
| 엔드포인트 | TurboAPI | FastAPI | 배속 |
|---|---|---|---|
| GET /health | 140,586/s | 11,264/s | 12.5x |
| GET / | 149,930/s | 11,252/s | 13.3x |
| GET /json | 147,167/s | 10,721/s | 13.7x |
| GET /users/123 | 145,613/s | 9,775/s | 14.9x |
| POST /items | 155,687/s | 8,667/s | 18.0x |
| GET /status201 | 146,442/s | 11,991/s | 12.2x |
| 평균 | 14.1x |
제목에 7x라고 나와 있는데 실제 HTTP-only 벤치마크 평균은 14.1x임. POST 라우트는 18x까지 나옴.
벤치마크: HTTP + DB 엔드투엔드 (캐시 전부 끈 상태)
| 라우트 | TurboAPI + pg.zig | FastAPI + asyncpg | FastAPI + SQLAlchemy |
|---|---|---|---|
| GET /health | 266,351/s | 9,161/s | 5,010/s |
| GET /users/{id} (1000개 ID) | 80,791/s | 5,203/s | 1,983/s |
| GET /users?age_min=20 | 71,650/s | 3,162/s | 1,427/s |
| GET /search?q=user_42% | 13,245/s | 3,915/s | 1,742/s |
pg.zig이라는 Zig 네이티브 Postgres 드라이버까지 같이 쓰면 GET /health에서 266k/s도 나옴. FastAPI + asyncpg 대비 약 29배.
어떻게 이런 수치가 나오나
디스패치 경로 최적화
라우트를 분석해서 가장 가벼운 디스패치 경로를 정적으로 배정함:
- native_ffi: Python 자체를 완전히 건너뜀. GIL 없음, 인터프리터 없음. C/Zig 핸들러 전용
- simple_sync_noargs:
PyObject_CallNoArgs사용. 인자 없는 GET 핸들러 - model_sync: Zig이 JSON 파싱하고 Python dict 만들어서 넘김.
json.loads없음 - simple_sync: 헤더·바디 파싱, 정규식
- body_sync: 헤더 파싱, 정규식
- enhanced: 풀 Python 디스패치 (Depends(), 미들웨어 등)
model_sync 경로 설명
dhi.BaseModel을 쓰는 POST 라우트라면 JSON을 Zig에서 두 번 파싱하고 Python에서는 한 번도 안 파싱함:
- dhi 유효성 검사:
dhi_validator.zig가 JSON 파싱 + 타입/제약조건 검사. 유효하지 않으면 422 반환, GIL 취득 없음 - Python dict 변환:
jsonValueToPyObject()가 Zig JSON 트리를 PyDict/PyList/PyUnicode 등으로 변환해서 핸들러에 넘김
Python 핸들러는 model_class(**data) 한 줄만 하면 됨.
제로카피 응답
응답 경로에서 Zig이 PyUnicode_AsUTF8()로 Python 문자열의 내부 버퍼 포인터를 얻어 write()를 소켓에 직접 호출함. memcpy 없고 임시 버퍼 없고 힙 할당 없음.
CORS
Python 미들웨어 대신 Zig 네이티브 CORS. 시작 시 헤더를 한 번만 렌더링하고 memcpy로 주입. 오버헤드 0% (Python 미들웨어로 처리하면 ~24% 오버헤드였다고 함).
현재 됨 / 안 됨
됨:
- FastAPI 호환 라우트 데코레이터
- 경로 파라미터, 쿼리 파라미터, JSON 요청 바디
- async 핸들러, Depends() 의존성 주입
- OAuth2, Bearer/Basic 인증, API Key
- CORS, GZip 미들웨어
- APIRouter, 백그라운드 태스크
- Python 3.14t 프리스레딩 지원
- Native FFI 핸들러 (C/Zig, Python 없이)
- 응답 캐싱, DB 결과 캐싱
미완성:
- WebSocket (작업 중)
- HTTP/2 + TLS (작업 중)
- Cloudflare Workers WASM 타겟 (예정)
알파 경고: 프로덕션 전에 꼭 읽을 것
- TLS 없음 — nginx나 Caddy를 앞에 두어야 함
- slow-loris 방어 없음 — 리버스 프록시에서 read timeout 설정 필요
- 최대 바디 크기 설정 불가 — 하드코딩된 16MB 제한
- WebSocket 미완성
- HTTP/2 미구현
- Python 3.14t 자체가 아직 새로움 — C 익스텐션 스레드 세이프 여부 불확실
요구사항이 Python 3.14t (프리스레딩 빌드)랑 Zig 0.15+임. Python을 소스에서 빌드해야 해서 세팅이 좀 번거로울 수 있음.
"그냥 Go/Rust 쓰면 되잖아" 반론에 대해
작자도 이 비판이 순수 처리량 기준으로는 맞다고 인정함. TurboAPI의 포지션:
- PyTorch, transformers, LangChain 같은 ML/AI 라이브러리 — Go/Rust에는 이 수준의 생태계가 없음
- SQLAlchemy, Alembic 등 ORM 생태계
- 팀 친숙도 — Rust 전환은 6~12개월 소요
- Stripe SDK, boto3, Celery 같은 라이브러리 커버리지
- FastAPI 코드베이스라면 임포트 한 줄만 바꾸면 됨
| 시나리오 | 추천 |
|---|---|
| 순수 JSON 프록시, 비즈니스 로직 없음 | Go |
| 임베디드, 바이너리 크기 < 1MB | Rust |
| 기존 Go/Rust 팀 | 그대로 |
| HTTP/2, gRPC 지금 바로 필요 | Go |
| Python ML/데이터 의존성 많음 | TurboAPI |
| FastAPI 코드베이스, 10-20x 처리량 필요 | TurboAPI |
마무리
MIT 라이선스로 공개됨. 아직 알파라 프로덕션 직접 투입은 무리지만, FastAPI 기반 서비스에서 처리량 병목을 겪고 있고 Go/Rust 전환이 부담스럽다면 지켜볼 만한 프로젝트임. 특히 ML 추론 API처럼 Python 생태계 의존도가 높은 서비스가 타깃 유스케이스.
댓글
댓글
댓글을 불러오는 중...