본문으로 건너뛰기
피드

FastAPI 호환 Python 프레임워크, Zig HTTP 코어로 14배 빠름 — TurboAPI

backend 약 9분
vote
0
댓글
북마크

FastAPI 코드와 완전 호환되면서 HTTP 처리 레이어를 Zig으로 교체한 TurboAPI가 공개됨. HTTP-only 벤치마크에서 FastAPI 대비 평균 14.1x, POST 라우트 최대 18x 빠르고, Zig 네이티브 Postgres 드라이버까지 결합하면 266k req/s도 달성함. 아직 알파 단계이며 TLS/WebSocket/HTTP2 미지원.

  • 1

    HTTP-only 벤치마크 평균 FastAPI 대비 14.1x 빠름 (POST /items 최대 18.0x)

  • 2

    HTTP + DB 엔드투엔드에서 FastAPI+asyncpg 대비 최대 29x 처리량

  • 3

    Python은 비즈니스 로직만 실행, 파싱·라우팅·유효성 검사·응답은 전부 Zig

  • 4

    FastAPI 임포트 한 줄 교체로 마이그레이션 가능, 데코레이터·Depends() 호환

  • 5

    알파 단계: TLS 없음, WebSocket 미완성, Python 3.14t + Zig 0.15+ 필요

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에서는 한 번도 안 파싱함:

  1. dhi 유효성 검사: dhi_validator.zig가 JSON 파싱 + 타입/제약조건 검사. 유효하지 않으면 422 반환, GIL 취득 없음
  2. **Python dict 변환: jsonValueToPyObject()가 Zig JSON 트리를 PyDict/PyList/PyUnicode 등으로 변환해서 핸들러에 넘김

Python 핸들러는 model_class(</strong>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 생태계 의존도가 높은 서비스가 타깃 유스케이스.

GitHub: https://github.com/justrach/turboAPI

Go/Rust 전환이 부담스러운 ML/AI 중심 Python 팀을 정확히 타깃으로 잡은 포지셔닝이 흥미함. 순수 처리량은 Go에 못 미친다는 걸 작자 스스로 인정하면서도 '14x면 FastAPI 병목은 해결된다'는 현실적인 트레이드오프를 내세움. 다만 Python 3.14t 프리스레딩 빌드가 필수 요구사항인 점은 실제 도입 장벽이 될 수 있음.

댓글

댓글

댓글을 불러오는 중...

backend

잘못된 추상화보다 중복이 낫다는 샌디 메츠의 고전 조언

샌디 메츠는 중복을 없애려다 잘못된 추상화를 만들면 코드가 조건문과 파라미터로 부풀어 더 위험해진다고 말한다. 이미 틀어진 추상화는 억지로 보존하지 말고, 다시 호출부에 인라인해서 중복을 되살린 뒤 현재 요구사항에 맞는 새 구조를 찾는 편이 빠르다는 주장이다.

backend

리눅스 커널, 6년·360개 넘는 패치 끝에 strncpy 제거

리눅스 커널이 오랫동안 버그의 원인이던 strncpy API 사용을 Linux 7.2에서 제거했어. NUL 종료 동작이 직관적이지 않고 불필요한 zero-fill로 성능 문제도 있던 API를 6년 동안 약 362개 커밋으로 걷어낸 작업임.

backend

덕디비는 왜 빠를까: 서버 없는 분석 엔진의 내부 구조 뜯어보기

DuckDB가 단일 바이너리, 인프로세스 실행, 컬럼형 저장, 최적화 패스, Parquet 푸시다운으로 빠른 분석 쿼리를 처리하는 방식을 깊게 설명한 글이다. 6GB Parquet 파일을 노트북에서 바로 SQL로 읽는 경험 뒤에 어떤 설계가 깔려 있는지 따라간다.

backend

피지독, 포스트그레스를 수평 확장시키겠다고 550만 달러 투자 유치

피지독은 포스트그레스 앞단에 프록시를 두고 샤딩과 라우팅을 처리해 수평 확장을 가능하게 하겠다는 오픈소스 프로젝트다. 이미 프로덕션에서 초당 200만 건이 넘는 쿼리를 처리하고, 확인된 규모만 20테라바이트 이상을 샤딩했다고 밝히며 550만 달러 투자를 공개했다.

backend

펜타시스템, EDB 포스트그레SQL로 국내 엔터프라이즈 DB 전환 시장 공략

펜타시스템테크놀러지가 EDB와 파트너 계약을 맺고 국내에 EDB 포스트그레SQL 기반 데이터 플랫폼을 공급한다. 기존 상용 DBMS 정책 변화로 비용 부담이 커진 기업들을 겨냥해, 오픈소스 기반 엔터프라이즈 데이터 플랫폼 전환 수요를 잡겠다는 전략이다. 금융, 공공, 제조, 유통, 클라우드, AI 데이터 분석 환경까지 적용 범위를 넓히려는 움직임이다.