학습일지/Language

Python FastAPI vs Go Web Application 성능테스트 비교 영상 정리

inspirit941 2025. 5. 3. 18:26
반응형

https://youtu.be/CdkAMceuoBg?si=G2AxWUA9v1wIiuyd

FastAPI와 Go standard Library로 만든 Web Application의 성능 비교.

 

 

 

소스코드:
https://github.com/antonputra/tutorials/tree/231/lessons/231

 

tutorials/lessons/231 at 231 · antonputra/tutorials

DevOps Tutorials. Contribute to antonputra/tutorials development by creating an account on GitHub.

github.com

 

Test 1. Baseline

하드코딩으로 간단한 Objects를 만들어서 json으로 응답하는 예시.

측정 항목

  • client side Latency: p99
  • throughput: RPS 계산
  • CPU / Memory Usage
  • Error Rate (Availability)
  • CPU throttling.

Test 2.

측정 항목

  • Post 요청을 받았을 때, request Body 파싱 + UUID와 timestamp 생성 + Postgres에 record 저장
  • DB 저장이 끝나면 Cache Set 진행. cache set에 걸리는 Latency (p90)
    • cache는 Memcache 사용
  • Postgres와 Memcache의 CPU 사용량, Connection Pool size 확인.

측정 환경

  • memcached: AWS m7a.xlarge instance
  • postgres: AWS 2xlarge EC2 instance
  • EKS with 2 instance group
    • 애플리케이션을 실행할 m7a.large
    • Prometheus, Grafana, 부하를 발생시킬 client를 배포할 compute-optimized Graviton (c8g.4xlarge)
      • 메모리가 딱히 필요하지 않으므로, general instance보다 비용이 약간 저렴하다고 함

Test 1 결과

스크린샷_2025-05-10_오후_2.26.57

다른 벤치마크 테스트에서도 그랬듯, Python의 CPU 사용량은 다른 어떤 애플리케이션 구현과 비교해도 높았다.

  • Python의 경우 빠르게 p99 Latency가 증가. Golang 대비 2배 이상.
  • 13000 TPS 무렵부터 fastAPI 앱의 RPS가 더 이상 증가하지 못한다.
    • CPU usage가 full로 차면서, k8s의 CPU throttling이 잡히기 시작
  • 25000 TPS 즈음에 Python 앱이 Fail 상태가 된다.
    • availability 수치가 0으로 변경.
    • 애플리케이션이 과부하됐을 때 발생하는 상황임.
    • client의 request에 timeout 또는 500 status가 발생.

FastAPI의 성능이 Django보다 소폭 낫지만, 그렇게까지 큰 성능차이는 아닌 거 같다고.

  • Golang 앱은 대략 62000 TPS까지 버티는 걸 볼 수 있음.

스크린샷_2025-05-10_오후_2.37.48

RPS: FastAPI는 13000 TPS를 넘지 못하지만, Golang은 62000 TPS까지 버텨냈다.

 

 

스크린샷_2025-05-10_오후_2.37.38

Latency: FastAPI는 fail 발생해서 latency가 뒤죽박죽인 반면, go는 낮고 안정적인 latency

 

 

 

스크린샷_2025-05-10_오후_7.14.30

CPU usage: FastAPI는 초반 10~15분만에 cpu 사용량을 100% 찍음. 따라서 cpu throttle이 전반적으로 많이 발생함.

 

 

 

스크린샷_2025-05-10_오후_7.15.52

Availability: ratio of successful request / # of all requests

 

 

 

 

스크린샷_2025-05-10_오후_7.16.54

Memory: go가 전체적으로 더 낮은 메모리를 사용하고, spike 튀는 지점은 app fail 발생할 때임.

 

 

 

cf. k8s Go application이라면, go user thread를 pod limit에 맞춰주는 게 좋다. 그래야 k8s 앱에서 cpu throttling이 발생하지 않음.

 

env:
- name: GOMAXPROC
  valueFrom:
    resourceFieldRef:
      resource: limits.cpu
resources:
  requests:
    memory: 2Gi
    cpu: 1500m
  limits:
    memory: 4Gi
    cpu: 2000m

 


Test 2 결과

스크린샷_2025-05-10_오후_7.23.30

Connection Pool Size는 최대 500으로 설정해두었음.

  • POST 요청이 오면 request body 파싱해서
  • Postgres DB에 저장
  • 저장한 데이터를 Memcached 에 Cache Set 한다.

overall: FastAPI는 테스트 시작 10여분 만에 limit에 도달한 반면, go는 limit 도달까지 1시간 걸림.

  • DB latency, Cache Set, Request Latency도 Go가 훨씬 낮다.
  • FastAPI의 RPS는 800을 넘지 못한다. Go의 경우 테스트에서는 한계점을 찾지 못함.
  • go가 막판에 spike가 발생한 이유는 memcached가 떠 있는 linux box의 file descriptor limit을 낮게 설정했기 때문. 정상적으로 높여주면 TPS는 계속 올라간다.

스크린샷_2025-05-10_오후_8.39.05스크린샷_2025-05-10_오후_8.39.17

반응형