ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] Async 코드가 느려지는 순간들 — 실무에서 가장 많이 하는 실수들
    IT 2026. 1. 23. 11:39

    async 코드가 느려지는 순간들

    실무에서 가장 많이 하는 실수들

    async / await를 도입하면 많은 사람들이 이렇게 기대합니다.

    “이제 우리 서비스는 빨라질 거야.”

    하지만 실제 현장에서는 종종 정반대의 경험을 하게 됩니다. async로 바꿨는데 오히려 느려졌거나, CPU 사용률이 치솟거나, 이유 없이 응답이 밀리는 상황을 만납니다.

    이 글에서는 async 자체의 문제가 아니라, 실무에서 정말 자주 발생하는 패턴들을 중심으로, async 코드가 느려지는 이유를 정리해보려 합니다.


    1. async 함수 안에 CPU-bound 로직이 있을 때

    가장 흔하면서도 가장 치명적인 경우입니다.

    async def handler():
        result = 0
        for i in range(10**7):
            result += i
        return result

    문법적으로는 async 함수지만, 이 코드는 전혀 비동기적이지 않습니다. 실행되는 동안 이벤트 루프는 양보받지 못하고, 다른 작업은 모두 멈춥니다.

    이런 경우 async는 아무런 이점도 주지 못합니다. 오히려 “비동기인데 왜 이렇게 느리지?”라는 혼란만 남깁니다.

    해결 방향은 명확합니다.

    • CPU 연산은 executor나 별도 프로세스로
    • 이벤트 루프는 흐름 관리에만 집중

    2. async 함수 안에서 동기 I/O를 호출할 때

    다음은 정말 자주 보이는 코드입니다.

    async def fetch_data():
        data = requests.get(url)
        return data.text

    겉으로 보면 문제 없어 보이지만, requests는 동기 라이브러리입니다. 이 한 줄 때문에 이벤트 루프 전체가 블로킹됩니다.

    이 문제의 무서운 점은, 코드 리뷰 단계에서는 잘 보이지 않는다는 것입니다. async 문법 안에 있기 때문에 안전하다고 착각하기 쉽습니다.

    원칙은 단순합니다.

    • async 함수 안에서는
    • 반드시 비동기 라이브러리를 사용한다

    3. await를 너무 늦게 만나는 구조

    다음과 같은 구조도 종종 성능 문제를 만듭니다.

    async def process():
        preprocess()
        preprocess()
        preprocess()
        await io_task()

    이 코드에서 await를 만나기 전까지, 이벤트 루프는 아무런 제어권도 얻지 못합니다. 즉, async 함수지만 사실상 동기 함수처럼 동작합니다.

    async 코드에서는 가능한 한 빨리 await를 만나는 구조가 유리합니다.


    4. async + for 루프의 조합

    비동기 작업을 반복 처리할 때 이런 코드를 쉽게 작성합니다.

    for item in items:
        await process(item)

    이 코드는 안전하지만, 동시에 매우 느릴 수 있습니다. 각 작업이 순차적으로 실행되기 때문입니다.

    실무에서는 보통 다음과 같은 의도가 숨어 있습니다.

    “여러 개를 동시에 처리하고 싶다”

    그럴 때는 구조를 바꿔야 합니다.

    • 작업을 모아서
    • 동시에 스케줄링하고
    • 한 번에 기다린다

    5. 무심코 들어간 블로킹 함수 하나

    time.sleep(1)

    이 한 줄은 async 코드 전체를 멈춥니다. 이벤트 루프는 이 함수가 끝날 때까지 아무것도 할 수 없습니다.

    실무에서 이 문제는 특히 로그 처리, 임시 딜레이, 레거시 코드에서 자주 등장합니다.

    async 환경에서는 항상 이 질문을 던져야 합니다.

    “이 함수는 이벤트 루프에게 제어권을 돌려주는가?”


    6. async는 빨라지는 기술이 아니다

    마지막으로 가장 중요한 오해를 짚고 넘어가야 합니다.

    async는 성능을 자동으로 올려주는 기술이 아닙니다.

    • async는 병렬 실행을 하지 않고
    • CPU를 더 많이 쓰지도 않으며
    • 기다림을 숨길 뿐입니다

    그래서 async는 다음과 같은 상황에서만 빛납니다.

    • 네트워크 요청이 많을 때
    • 대기 시간이 길 때
    • 동시에 처리해야 할 작업 수가 많을 때

    마무리

    async 코드가 느려질 때, 문제는 대부분 async가 아니라 우리가 async를 대하는 방식에 있습니다.

    정리하면 이렇습니다.

    • 이벤트 루프는 매우 정직하다
    • 양보하지 않는 코드는 반드시 문제를 만든다
    • async는 규율이 중요한 모델이다

    이 감각이 생기면, async는 더 이상 불안한 기술이 아니라, 예측 가능한 도구가 됩니다.

Designed by Tistory.