Zettelkasten

Gunicorn은 WSGI 프로세스 매니저, Uvicorn은 ASGI 이벤트 루프 서버다

·수정 2026.06.02·수정 2

요약

  • Gunicorn은 WSGI(동기) 기반 pre-fork 프로세스 매니저, Uvicorn은 ASGI(비동기) 기반 이벤트 루프 서버다.
  • WSGI 표준은 1회성 동기 응답 모델이라 WebSocket 같은 양방향 연결을 표현할 수 없다.
  • 프로덕션에서는 gunicorn -k uvicorn.workers.UvicornWorker 패턴으로 두 서버의 강점을 결합한다.

본문

핵심 차이

항목 Gunicorn Uvicorn
프로토콜 WSGI (동기) ASGI (비동기)
지원 통신 HTTP/1.1 HTTP/1.1, WebSocket, HTTP/2
워커 모델 pre-fork 멀티 프로세스 단일 프로세스 + asyncio
기반 Python sync uvloop + httptools (C 기반)
적합 Flask, Django (sync) FastAPI, Starlette, Channels

Gunicorn의 강점: 프로세스 관리

Master 1개 + Worker N개 구조로, 워커의 생사만 Master가 관리한다.

  • Self-healing: 워커가 OOM/segfault로 죽으면 Master가 즉시 새 워커를 fork
  • Worker timeout: --timeout 30 으로 응답 못하는 워커 강제 kill 후 재생성
  • Graceful reload (SIGHUP): 새 워커 fork → 준비되면 기존 워커는 진행 중 요청 끝까지 처리 후 종료
  • Graceful shutdown (SIGTERM): 새 요청 거부 + 처리 중 요청은 --graceful-timeout 동안 완료 대기 (K8s preStop과 잘 맞음)
  • Max requests: --max-requests 1000 --max-requests-jitter 50으로 메모리 누수를 운영적으로 회피
  • 시그널 제어: HUP(reload), TERM(shutdown), USR1(log reopen), USR2(zero-downtime upgrade), TTIN/TTOU(워커 +1/-1)

Uvicorn의 강점: 비동기 I/O

  • ASGI 표준 → async def 핸들러, 단일 프로세스에서 수천 동시 연결 처리
  • WebSocket, SSE, long-polling 등 양방향/지속 연결 지원
  • uvloop + httptools 덕분에 raw 성능이 매우 빠름
  • 단일 프로세스라 CPU 코어 활용엔 약함 → 멀티 워커 필요

WebSocket은 WSGI 위에서 불가능

WSGI 인터페이스 자체가 def app(environ, start_response) → 한 번 호출 후 응답 반환하는 모델이라 HTTP Upgrade 후 양방향 통신을 표현할 수 없다.

구성 WebSocket
Gunicorn (sync worker)
Gunicorn (gevent/eventlet) ⚠️ 일부 라이브러리 한정 hack
Gunicorn + UvicornWorker ✅ (실질적으로 Uvicorn이 처리)
Uvicorn 단독
Daphne, Hypercorn

실전 조합 패턴

gunicorn app.main:app \
  -w 4 \
  -k uvicorn.workers.UvicornWorker \
  -b 0.0.0.0:8000 \
  --timeout 30 \
  --max-requests 1000 \
  --max-requests-jitter 50
  • Gunicorn: 워커 4개 fork + 죽으면 재시작 + 시그널 처리
  • UvicornWorker: 각 워커 안에서 ASGI 이벤트 루프 실행

→ Gunicorn의 안정적인 프로세스 관리 + Uvicorn의 async 성능을 모두 얻는다.

선택 기준

  • Django/Flask sync → Gunicorn 단독
  • FastAPI 로컬 개발 → uvicorn main:app --reload
  • FastAPI 프로덕션 → Gunicorn + UvicornWorker
  • 컨테이너 환경(K8s)에서 프로세스 관리를 오케스트레이터에 맡길 경우 → Uvicorn 0.30+ 단독도 OK

참고