[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

Tech Story/AI Cloud

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

 

 
[ kt cloud AI플랫폼팀 최지우 님 ]

📋 요약

이 글에서는 Python 기반 API Gateway 구축 과정에서
FastAPI 대신 Rust 런타임 기반의 웹 프레임워크 Robyn을 도입한 배경과 실측 성능 벤치마크 결과를 다룹니다.
고부하 환경에서의 Tail Latency 안정성과 서버 생존율 차이가
엔터프라이즈 AI 서비스의 인프라 선택에 실질적인 기준이 됨을 정리합니다.

#Robyn #FastAPI #API Gateway #Rust런타임 #Tail Latency

 


[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

최근 LLM 트렌드와 함께 AI 서비스의 아키텍처는 날이 갈수록 복잡해지고 있습니다. vLLM이나 TGI 같은 고성능 추론 엔진들은 자체적으로 API 서버 기능을 내장하고 있어 실행 즉시 모델과 통신할 수 있는 환경을 제공합니다. 하지만 실제 엔터프라이즈 환경에서 이러한 추론 엔진을 클라이언트에 직접 노출하는 경우는 드뭅니다.

 

단순히 답변을 생성하는 기능을 넘어, 실제 안정적인 서비스 운영을 위해서는 엔진 앞단에서 처리해야 할 운영 레이어가 필수적이기 때문입니다. 저희는 다음과 같은 핵심 요구사항을 해결하기 위해 AI 추론 엔진 전용 API Gateway 구축을 결정했습니다.

  • 비즈니스 파이프라인의 고도화: RAG를 위한 컨텍스트 검색, 동적 프롬프트 주입, 입출력 가드레일 등 엔진 외부에서 처리해야 할 로직이 비약적으로 늘어났습니다.
  • 중앙 집중식 거버넌스: 여러 모델 엔진에 대한 통합 인증, 사용자별 할당량 제한, 그리고 빌링을 위한 상세 추론 로그 수집이 필요합니다.
  • 고가용성 및 유연한 스케일링: 특정 엔진의 장애에 즉각 대응하고, 트래픽 부하에 따라 여러 대의 vLLM 인스턴스로 요청을 분산하는 지능형 로드 밸런싱이 필수적입니다.

이 과정에서 Python의 생산성을 유지하면서도, 병목없는 고성능을 내기 위해 Rust 런타임 위에서 동작하는 웹 프레임워크 Robyn을 도입하게 되었습니다

 

오늘 포스팅에서는 FastAPI의 대항마로 떠오르는 Robyn을 활용해 API Gateway를 구축한 과정과, 간단한 FastAPI vs Robyn 성능 벤치마크 결과를 공유하려 합니다.


1. Why Not FastAPI?

Python 웹 개발의 표준은 오랫동안 Flask였고, 최근 몇 년간은 FastAPI가 사실상의 표준으로 자리 잡았습니다. 저희 역시 초기 프로토타입은 FastAPI로 작성했습니다. 하지만 수만 건의 요청을 중계해야 하는 "API Gateway"라는 관점에서는 다음과 같은 태생적 한계를 마주하게 되었습니다.

1.1. Python의 태생적 한계와 GIL

FastAPI는 Starlette과 Uvicorn을 기반으로 비동기 처리를 아주 훌륭하게 수행합니다. 하지만 아무리 비동기로 동작하더라도 결국 Python 인터프리터라는 엔진 위에서 돌아간다는 사실은 변하지 않습니다.

 

API Gateway는 단순히 요청을 전달하는 것뿐만 아니라, 헤더의 유효성을 검사하고 페이로드를 검증하며 때로는 요청을 signing하는 등 작지만 반복적인 CPU 연산을 동반합니다. 이때 Python의 GIL(Global Interpreter Lock)은 동시성 처리에 있어 거대한 장벽이 됩니다. 아무리 많은 코어를 할당하더라도, 한 번에 하나의 스레드만 Python 바이트코드를 실행할 수 있기 때문에 고부하 상황에서는 컨텍스트 스위칭 오버헤드가 발생하며 응답 시간이 튀는 현상을 피하기 어렵습니다.

1.2. Robyn: Rust의 성능을 입다

이러한 한계를 극복하기 위해 저희가 주목한 것이 바로 Robyn입니다.

 

Robyn - A Fast, Innovator Friendly, and Community Driven Python Web Framework

Robyn is a high-performance async Python web framework powered by a Rust runtime. Build fast, scalable web applications with Python's simplicity and Rust's speed.

robyn.tech

 

Robyn은 기존 Python 프레임워크들과는 설계 사상부터 궤를 달리합니다.

  • Rust-powered Runtime: 서버의 핵심 엔진인 이벤트 루프와 워커가 Rust로 작성되었습니다. 요청을 수신하고 네트워크 소켓을 핸들링하는 가장 밑바닥의 로직이 Rust의 성능을 그대로 활용합니다.
  • True Concurrency: 요청을 수신하고 분배하는 핵심 아키텍처는 Rust의 멀티스레딩 모델을 따릅니다. 따라서 Python 레이어로 제어권이 넘어오기 전까지는 GIL의 간섭 없이 모든 CPU 코어를 최대로 활용할 수 있습니다.
  • Pythonic Interface: 가장 큰 매력은 이 강력한 성능을 사용하면서도 개발자는 익숙한 Python 문법을 그대로 쓸 수 있다는 점입니다.

마치 Rust라는 고성능 엔진에 Python이라는 편리한 인터페이스를 씌운 것과 같습니다. 성능이 중요한 코어 로직은 Rust가 처리하고, 가독성과 생산성이 중요한 비즈니스 로직은 Python으로 작성할 수 있다는 점에 주목했습니다.


2. Architecture & Implementation

저희의 목표는 명확했습니다. 추론 엔진 앞단에 위치하여 실질적인 서비스 게이트웨이 역할을 수행할 API 서버를 구축하는 것이었습니다. 사실 현재 vLLM과 같은 서빙 생태계의 주류 엔진들이 이미 FastAPI를 내장하여 API 기능을 제공한다는 점은, FastAPI가 Python 생태계에서 얼마나 견고한 신뢰와 대중성을 얻고 있는지 보여주는 확실한 증거입니다.

 

하지만 저희는 이미 익숙하고 검증된 FastAPI 대신, Robyn이라는 다소 과감한 선택지를 택했습니다. 주류 엔진들이 택한 길을 마다하고 Robyn을 선택한 이유는 '성능에 대한 집착' 때문이었습니다. 추론 엔진이 비즈니스 로직과 섞이지 않고 오직 연산에만 집중할 수 있도록, 그 앞단에서 트래픽을 처리하는 API 서버만큼은 압도적인 처리량을 보장해야 한다고 판단했습니다.

특히 저희가 주목한 전략은 이원화된 스택 구성을 통한 병목 현상의 근본적 격리였습니다.

  • 자원 제약의 중첩 방지: 백엔드 추론 엔진 레이어가 이미 Python 프레임워크 기반으로 동작하고 있다면, API 서버 레이어까지 같은 Python 스택을 사용할 경우 자원 관리 측면에서 Python 인터프리터의 제약(GIL 등)이 양쪽 레이어에서 중첩될 위험이 있습니다.
  • 독립적인 관문 구축: 입구에 아예 다른 엔진을 배치함으로써, 네트워크 I/O 핸들링과 프로토콜 파싱 단계에서의 부하를 Python 레이어로부터 완전히 독립시켰습니다.

결과적으로 어떤 고부하 상황에서도 추론 엔진의 성능에 사이드 이펙트를 주지 않는, 독립적이고 강력한 'Gateway'을 구축하고자 했습니다. 이러한 아키텍처적 결단은 이후 진행된 벤치마크 결과에서 그 가치를 수치로 증명해 보였습니다.

2.1. 예시 코드

Robyn의 가장 큰 장점은 Rust의 강력한 성능을 Python의 익숙한 문법으로 누릴 수 있다는 점입니다. 실제로 저희가 구축한 API 서버의 핵심 구조는 놀라울 정도로 심플합니다. 다음은 기본적인 Robyn 애플리케이션의 뼈대입니다.

from robyn import Robyn, Request, Response
import json
app = Robyn(__file__)
@app.get("/health")
async def health():
    return "OK"
@app.post("/data")
async def handle_data(req: Request):
    body = json.loads(req.body)
    result = {"status": "success", "received": body}
    return Response(
        status_code=200,
        headers={"Content-Type": "application/json"},
        description=json.dumps(result)
    )
if __name__ == "__main__":
    app.start(port=8080, host="0.0.0.0")

 

위 코드에서 볼 수 있듯, FastAPI나 Flask를 사용해 본 개발자라면 별도의 학습 곡선 없이 즉시 적응할 수 있는 수준입니다. 하지만 이 단순해 보이는 코드 밑단에서는 Rust의 멀티스레드 런타임이 동작합니다.

특히 주목할 점은 Response 객체를 다루는 방식입니다. Robyn은 네트워크 응답을 구성하는 저수준 작업들을 Rust 레이어에서 최적화하여 처리하므로, 개발자는 복잡한 튜닝 없이도 프레임워크가 제공하는 '기본적인 고성능'을 그대로 서비스에 녹여낼 수 있습니다.


3. Benchmark: FastAPI vs Robyn

단순한 프레임워크 비교를 넘어, 현재 운영 중인 서비스 백엔드의 API 서버를 FastAPI에서 Robyn으로 직접 변경해가며 실질적인 성능 변화를 확인했습니다.

3.1. 동시 접속자 50명 가정

정확한 데이터 검증을 위해 실제 AI 플랫폼의 서비스 엔진이 구동되는 동일한 인프라(VM) 환경에서 벤치마크를 수행했습니다.

  • CPU: Intel Xeon (Cascadelake) - 16 Cores
  • Memory: 90GB RAM

가장 먼저 비즈니스 로직이나 추론 오버헤드가 배제된 상태에서 프레임워크 자체의 네트워크 핸들링 능력을 측정했습니다. 단일 요청 환경에서는 두 프레임워크 모두 약 1.1ms의 오버헤드를 보이며 대등한 성능을 기록했습니다. 하지만 실제 서비스 환경을 가정하여 동시 접속자기반의 부하 테스트를 수행하자, 엔진의 기초 체력 차이가 극명하게 드러나기 시작했습니다.

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

부하 테스트의 첫 번째 지표인 초당 처리량(Requests Per Second, RPS) 결과입니다. 측정 결과, Robyn은 763.28 RPS를 기록하며 FastAPI(651.02 RPS) 대비 약 17.2% 향상된 성능을 보여주었습니다.

 

FastAPI가 Python의 이벤트 루프 제약 내에서 자원을 분배하며 병목을 형성하기 시작할 때, Rust 런타임 기반의 Robyn은 각 코어의 성능을 최대한 활용하며 더 많은 동시 요청을 안정적으로 소화해냈습니다. 이러한 처리량의 차이는 트래픽이 몰리는 피크 타임에 서버 인프라 비용을 절감하거나, 동일 자원에서 더 많은 사용자에게 서비스를 제공할 수 있는 실질적인 경쟁력이 됩니다.

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

하지만 진짜 놀라운 수치는 지연 시간(Latency)의 안정성에서 나타났습니다. 평균 응답 시간은 약 9ms의 차이였으나, 서비스의 품질을 결정짓는 상위 1% 지연 시간(P99)에서 Robyn(96.4ms)은 FastAPI(286.4ms)보다 약 3배나 더 빠른 안정성을 입증했습니다.

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

위 그래프에서 볼 수 있듯이, FastAPI는 요청이 누적될수록 지연 시간이 급격하게 우상향하는 Tail Latency 문제를 보였습니다. 이는 현재 구성에서 컨텍스트 스위칭 오버헤드를 겪고 있음을 시사합니다. 반면, Robyn은 마지막 99% 구간까지 응답 곡선을 완만하게 유지했습니다. Rust 기반 멀티스레드 런타임이 동시성 경쟁 상황에서도 얼마나 예측 가능한 성능을 보장하는지 확인된 셈입니다.

지표 Robyn FastAPI 개선율
처리량 (Requests/sec) 763.28 651.02 +17.2%
상위 99% 지연 (P99) 96.4ms 286.4ms +197%
최악의 응답 시간 (Max) 143.4ms 674.8ms +370%

3.2. 고부하 상황에서의 안정성 비교

프레임워크가 극한의 동시 접속 상황에서 얼마나 무너지지 않고 버티는지 확인하기 위해, 별도의 비즈니스 로직 없이 간단한 JSON 바디만 즉시 응답하는 조건으로 1,000명의 가상 유저가 동시에 접근하는 테스트를 진행했습니다. 이는 모델 추론 전 단계에서 프레임워크가 순수하게 네트워크 커넥션을 관리하는 능력을 측정하기 위함입니다.

지표 Robyn FastAPI 결과 분석
평균 응답 시간 (Avg) 0.1862s 0.1141s FastAPI가 수치상 우위
상위 95% 지연 (P95) 0.2775s 0.9216s Robyn이 3.3배 안정적
상위 99% 지연 (P99) 0.3432s 1.7410s Robyn이 5.1배 안정적
 

이 벤치마크 결과에서 가장 놀라운 점은 지연 시간 분포입니다.

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

FastAPI의 데이터를 보면 하위 50%까지는 0.02초로 매우 빠릅니다. 하지만 상위로 갈수록 지연 시간이 폭발적으로 증가합니다.

  • P90 (0.13s) → P95 (0.92s) → P99 (1.74s)

동시 접속자가 1,000명에 달하자 Python의 단일 이벤트 루프가 병목 현상을 일으키며, 운 좋게 먼저 처리된 요청은 빠르지만, 뒤에 줄 선 10% 이상의 유저는 1초가 넘는 지연을 경험하게 됩니다. 1,000명 중 100명은 답답한 경험을 하는 셈입니다.

반면 Robyn은 처음부터 끝까지 응답 시간이 매우 촘촘하게 모여 있습니다.

  • P90 (0.20s) → P95 (0.27s) → P99 (0.34s)

Rust 기반의 멀티스레드 런타임이 1,000개의 연결을 효율적으로 분산 처리하고 있음을 보여줍니다. 평균은 FastAPI보다 조금 느려 보일 수 있으나, 전체 사용자의 99%가 0.3초 내에 응답을 받습니다. 최악의 상황에서도 서비스 품질(QoS)이 일정하게 유지됩니다.

3.3. 시스템 한계 돌파 테스트 (-c 12000)

프레임워크가 단순히 느려지는 것을 넘어, "터지지 않고 버틸 수 있는가"를 확인하기 위해 12,000명의 동시 접속자가 한꺼번에 몰리는 테스트를 진행했습니다.

지표 Robyn FastAPI 결과 분석
성공한 요청 수 12,000 / 12,000 7,809 / 12,000 FastAPI 약 35% 실패
에러 발생 0건 4,191건 (EOF, Reset) FastAPI 서버 오류

 

결정적 차이: "성능보다 중요한 건 생존"

이번 테스트의 결과는 초당 처리량(RPS)이나 지연 시간을 비교하는 것이 의미가 없습니다. 서버가 살아남았느냐가 핵심입니다.

[비교분석] FastAPI는 충분히 빠르지 않다? Robyn과의 성능 차이 직접 비교

동시 접속자가 12,000명에 달하자 FastAPI(Uvicorn)는 쏟아지는 커넥션을 감당하지 못하고 4,156건의 EOF 에러와 다수의 Connection Reset을 내뱉었습니다. 이는 파이썬 이벤트 루프가 네트워크 소켓을 제때 처리하지 못해 OS 레벨에서 강제로 연결을 끊어버렸음을 의미합니다. 전체 요청의 1/3이 유실된, 사실상의 서비스 장애 상태입니다.

반면 Robyn은 12,000건의 요청 중 단 한 건의 에러도 없이 100% 성공(202 Accepted)시켰습니다. 응답 시간은 평균 1.2초대로 늘어났지만, 이는 서버가 죽지 않고 모든 대기열을 끝까지 처리해냈다는 증거입니다. Rust의 멀티스레드 런타임이 12,000개의 소켓을 안정적으로 핸들링하며 시스템의 안정성을 끝까지 지켜냈습니다.

엔지니어링 인사이트

벤치마크 결과가 시사하는 바는 명확합니다. 실제 서비스 운영 환경에서 가장 위협적인 요소는 평소의 속도가 아니라, 고부하 상황에서 간헐적으로 발생하는 지연이기 때문입니다.

  • Tail Latency의 압도적 방어력: 테스트 결과, FastAPI는 부하가 임계치에 도달할 때 P99 지연 시간이 평균 대비 무려 15배나 튀어버리는 불안정성을 보였습니다. 반면, Robyn은 1.8배 수준의 매우 타이트한 방어선을 유지했습니다. 이는 사용자에게 항상 일정한 응답성을 보장해야 하는 서비스 게이트웨이로서 엄청난 강점입니다.
  • 이벤트 루프의 한계 vs 멀티스레딩의 견고함: Python의 asyncio 기반 이벤트 루프는 동시 접속이 급증할 때 컨텍스트 스위칭 오버헤드로 인해 응답 지연이 도미노처럼 발생하는 구조적 취약점이 있습니다. 하지만 Robyn의 Rust 엔진은 시스템 레벨에서 멀티스레드를 직접 제어하며 수만 개의 커넥션을 훨씬 견고하고 공평하게 관리합니다.

결론적으로, Robyn은 단순한 '빠른 프레임워크'를 넘어섰습니다. 고부하 환경에서도 지연 시간의 요동을 최소화하고 서버의 생존력을 끝까지 보장해야 하는 엔터프라이즈 AI 플랫폼 API 서버로서의 적합성을 수치로 완벽히 증명해냈습니다. 저희는 이번 검증을 통해 얻은 확신을 바탕으로, Robyn을 플랫폼의 핵심 관문 엔진으로 채택하여 안정적인 API Gateway 환경을 구축할 수 있었습니다.


5. 결론 및 인사이트

이번 Robyn 도입과 벤치마크 과정은 단순히 더 빠른 프레임워크를 찾는 여정을 넘어, "Python의 유연함과 Rust의 견고함을 결합했을 때 인프라의 한계를 어디까지 확장할 수 있는가"를 실증적으로 확인한 과정이었습니다.

  • 성능 그 이상의 안정성: Robyn은 단순히 처리량(Throughput)이 높은 것을 넘어, 고부하 상황에서 CPU와 메모리 리소스를 매우 효율적이고 일정하게 제어했습니다. 이는 Nginx와 같은 저수준 설정의 복잡함에서 벗어나면서도, 시스템 레벨의 최적화 이점을 Python 코드로 직접 핸들링할 수 있다는 강력한 메리트를 제공합니다.
  • 성숙도와 기회비용: 물론 신생 프레임워크인 만큼 생태계의 성숙도는 기존 라이브러리들에 비해 부족할 수 있습니다. 예상치 못한 동작을 디버깅하거나 공식 문서 외의 오픈소스 코드를 직접 분석해야 하는 수고로움이 따르지만, 이는 성능적 우위를 선점하기 위해 지불해야 할 합당한 비용이기도 합니다.

도입 가이드

  • 추천: 극한의 성능이 요구되는 AI/ML 서빙 레이어, Python의 기민한 개발 속도와 Rust의 Low-level 제어력이 모두 필요한 고성능 API 서비스
  • 고려사항: 풍부한 레퍼런스와 커뮤니티의 검증된 가이드가 필수적인 보수적인 프로젝트 환경에서는 기술적 난도가 높게 느껴질 수 있습니다.

기술의 주류 여부와 상관없이, 서비스의 병목을 해결하고 최적의 사용자 경험을 제공할 수 있는 기술을 탐구하는 것은 엔지니어에게 매우 가치 있는 일입니다. 실제로 저희 AI서비스의 핵심 관문으로 Robyn을 도입하며 얻은 성능적 이점과 안정성은 선택이 틀리지 않았음을 증명해주고 있습니다. 이번 Robyn 도입 경험은 단순히 하나의 프레임워크를 익힌 것을 넘어, 향후 Rust 기반의 시스템 최적화까지 기술적 시야를 확장하는 중요한 기반이 되었습니다.

kt cloud 플랫폼 바로가기

❓ 자주 묻는 질문 (FAQ)

Q. 실제 추론 워크로드에서도 차이가 유지되나요?
A. 모델 추론이 들어가면 절대 latency는 GPU 및 추론엔진 성능에 의존합니다. 하지만 Gateway 레이어의 역할은
  • queue 형성 억제
  • burst traffic 흡수
  • inference layer 보호
이기 때문에 high concurrency 상황에서의 request distribution 안정성 측면에서는 동일한 패턴의 차이를 확인했습니다.

📚 관련/출처

https://robyn.tech/