Skip to content
1월 24, 2026chattiboyDjango

daphne vs gunicorn

Daphne는 ASGI 서버, Gunicorn은 기본적으로 WSGI 서버고, 이 차이가 WebSocket 동작 여부를 결정해.


요약

  • Gunicorn (WSGI)
    → HTTP 요청/응답(동기, 단발성)만 처리
    → WebSocket 프로토콜 자체를 이해하지 못함
  • Daphne (ASGI)
    → HTTP + WebSocket + lifespan 등 지속 연결 프로토콜 처리
    → WebSocket 네이티브 지원

핵심 차이: WSGI vs ASGI

1️⃣ WSGI (Gunicorn의 기본 세계관)

WSGI는 애초에 이렇게 정의돼 있어:

Request → Application → Response → Connection 종료

특징:

  • 요청당 하나의 response
  • connection을 오래 붙잡고 상태를 유지하는 개념이 없음
  • HTTP Upgrade (WebSocket handshake) 이후의 프레임 통신 모델이 없음

그래서:

  • WebSocket handshake 이후
  • send/receive 루프를 돌려야 하는데
    WSGI 인터페이스에는 그 자리가 아예 없음

👉 Gunicorn은 “정상적으로 설계된 WSGI 서버”라서 WebSocket이 안 되는 게 맞음


2️⃣ ASGI (Daphne의 세계관)

ASGI는 처음부터 이렇게 정의됨:

Client ↔ Server ↔ Application
          (long-lived connection)

인터페이스 자체가 이벤트 기반이야:

async def application(scope, receive, send):
    ...
  • scope: protocol 정보 (http, websocket)
  • receive: 클라이언트 이벤트 수신
  • send: 서버 → 클라이언트 이벤트 전송

WebSocket은 이렇게 들어와:

scope["type"] == "websocket"

그리고 이벤트는:

{"type": "websocket.connect"}
{"type": "websocket.receive"}
{"type": "websocket.disconnect"}

👉 프로토콜 레벨에서 WebSocket이 1급 시민


“근데 Gunicorn도 WebSocket 된다고 들었는데?”

맞아. 하지만 조건부야.

Gunicorn + ASGI Worker

Gunicorn 자체는 그냥 Process Manager야.
여기에 ASGI worker를 붙이면 이야기가 달라져.

대표 조합:

  • gunicorn -k uvicorn.workers.UvicornWorker
  • gunicorn -k daphne.server.DaphneWorker (거의 안 씀)

이 경우 구조는:

Client
  ↓
Gunicorn (master/worker 관리)
  ↓
Uvicorn/Daphne (ASGI server)
  ↓
ASGI App

👉 WebSocket이 되는 이유는 Gunicorn 때문이 아니라
👉 Uvicorn/Daphne가 ASGI 서버이기 때문


Daphne vs Uvicorn (ASGI 서버 간 차이)

항목DaphneUvicorn
출신Django ChannelsStarlette/FastAPI
이벤트 루프Twistedasyncio / uvloop
HTTP 성능보통매우 좋음
WebSocket 안정성매우 성숙성숙
Django 친화성★★★★★★★★
운영 난이도약간 높음낮음

Django + Channels 기준에선:

  • 공식 레퍼런스: Daphne
  • 실무 트렌드: Uvicorn 점점 증가

왜 “WebSocket이 동작하는 게 다르게 느껴질까?”

운영 관점에서 체감 차이는 여기서 나와:

1️⃣ 연결 유지 모델

  • Daphne: connection당 event loop 관리가 명확
  • Gunicorn(WSGI): connection 유지 개념 자체 없음 → 바로 끊김

2️⃣ Reverse Proxy 영향

Nginx에서:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

ASGI 서버는 이걸 이해
WSGI 서버는 무시

그래서:

  • Gunicorn만 쓰면 → handshake 이후 바로 종료
  • Daphne/Uvicorn → 정상 연결 유지

실무 권장 아키텍처

Django + WebSocket

[Nginx]
   ↓
[Daphne or Uvicorn]
   ↓
[Django ASGI + Channels]

Django + HTTP only

[Nginx]
   ↓
[Gunicorn (WSGI)]
   ↓
[Django WSGI]

혼합 (요즘 제일 흔함)

HTTP  → Gunicorn (WSGI)
WS   → Uvicorn/Daphne (ASGI)

또는

전부 ASGI (Uvicorn)

결론

  • WebSocket 동작 차이는 구현 문제 ❌
  • 프로토콜 철학(WSGI vs ASGI)의 차이 ⭕
  • Gunicorn은 WebSocket을 “못하는 게 아니라”
    하도록 설계되지 않았음
  • Daphne는 WebSocket을 위해 태어남