피드로 돌아가기
From ThreadPoolExecutor to httpx AsyncClient: True Async Refactoring
Dev.toDev.to
Backend

Fake Async 탈피를 통한 응답 속도 3배 개선 및 메모리 28% 절감

From ThreadPoolExecutor to httpx AsyncClient: True Async Refactoring

JustJinoIT2026년 6월 7일4intermediate

Context

ThreadPoolExecutor를 활용해 동기 호출을 비동기로 래핑한 Fake Async 구조로 인한 확장성 저하 발생. Thread 기반의 동시성 제어로 인해 요청 수 증가 시 Thread Overhead 증가 및 메모리 사용량 급증이라는 병목 지점 확인.

Technical Solution

  • ThreadPoolExecutor를 제거하고 Native Async I/O를 지원하는 httpx AsyncClient 도입
  • Lazy Loading 패턴을 적용한 Client 초기화 구조로 불필요한 리소스 할당 방지
  • httpx.Limits 설정을 통한 Max Connection 및 Keep-alive Connection의 정밀한 제어
  • Async Context Manager 구현을 통한 HTTP Connection의 안정적인 생명주기 관리
  • 루프 기반의 run_in_executor 방식에서 Event Loop 기반의 Non-blocking I/O 모델로 전환

Impact

  • 평균 응답 속도: 450ms에서 150ms로 3배 단축
  • 메모리 사용량: 250MB에서 180MB로 약 28% 감소
  • 동시 처리 용량: 3개에서 10개 요청으로 3.3배 증가
  • 100개 동시 요청 처리 시간: 15초에서 5초로 3배 단축

Key Takeaway

동기 라이브러리를 Thread Pool로 감싸는 방식은 임시방편일 뿐이며, 고성능 I/O 바운드 서비스에서는 설계 단계부터 Async-first 관점의 Native Async Client 채택이 필수적임.


1. 코드 내 loop.run_in_executor 또는 ThreadPoolExecutor 사용 여부 전수 조사

2. I/O 집중 작업 시 requests 대신 httpx나 aiohttp 같은 Non-blocking 라이브러리 검토

3. Connection Pooling 설정(Max Connections, Keep-alive)이 인프라 환경에 최적화되었는지 검증

4. Client 객체의 생명주기 관리를 위해 Async Context Manager 적용 여부 확인

원문 읽기