Head-of-Line Blocking이란? 앞의 느린 작업 때문에 뒤의 빠른 작업까지 기다리는 현상 쉽게 이해하기
Head-of-Line Blocking은 Queue 맨 앞의 느린 작업 때문에 뒤의 빠른 작업까지 함께 지연되는 현상입니다. FIFO·Queue 분리·HTTP/2·3·Bulkhead·Starvation까지 초보 기준으로 정리합니다.
Queue에 A·B·C가 있고 A는 30초, B·C는 100ms라면 Worker가 하나이고 순서대로만 처리할 때 B·C는 A가 끝날 때까지 기다려야 합니다. 이처럼 Queue 앞쪽의 느린 작업 하나 때문에 뒤에 있는 빠른 작업들까지 함께 지연되는 현상을 Head-of-Line Blocking(HOL Blocking)이라고 합니다.
맨 앞의 느린 작업이 뒤의 모든 작업을 막아버린다
마트 계산대 비유
앞 손님 물건 300개, 뒤 손님 생수 한 병. 생수 계산은 몇 초면 끝나지만 앞 손님 때문에 기다립니다. 뒤 작업이 느린 게 아니라 앞 작업 때문에 느려진 것입니다. Head of Line = 줄의 맨 앞입니다.
사용자에게는 어떻게 보이나
간단한 API인데 30초 걸린다면, 실제 Service Time은 0.1초이고 Queue 대기가 30초일 수 있습니다. Queueing Theory처럼 Waiting Time과 Service Time을 나누면 코드 최적화만으로는 체감이 안 좋아지는 이유를 알 수 있습니다.
FIFO와 Long Job
FIFO는 공정하고 흔하지만, 처리 시간이 크게 다른 작업을 한 Queue에 넣으면 HOL이 커집니다. 영상 인코딩·AI 생성 같은 Long Job과 상태 조회·작은 알림을 같은 Worker가 처리하면 특히 위험합니다. 시간이 비슷한 작업만 있으면 영향은 작습니다.
Worker 증가 · Queue 분리 · Bulkhead
Worker를 늘리면 B·C가 A와 병렬로 갈 수 있지만, 긴 작업이 Worker를 전부 차지하면 짧은 작업이 다시 대기합니다. Short/Long Queue와 전용 Worker로 나누면 긴 작업이 짧은 작업 자원을 모두 가져가지 못합니다. 이는 Bulkhead와 같습니다. Priority로 짧은 작업을 먼저 하면 긴 작업이 영원히 밀리는 Starvation이 생길 수 있어 Aging이 필요할 수 있습니다.
Shortest Job First · Preemption
짧은 작업부터 처리하면 평균 대기 시간을 줄일 수 있지만, 긴 작업 Starvation·시간 예측 어려움이 있습니다. Preemption(선점)으로 긴 작업을 잠시 멈추고 긴급 작업을 먼저 할 수 있으나, Transaction·인코딩 등 모든 작업을 중간에 멈추기는 어렵습니다.
HTTP/1.1 · HTTP/2 · HTTP/3
HTTP에서도 HOL이 논의됩니다. HTTP/1.1에서는 연결 안 순차 처리로 앞 응답이 뒤를 막을 수 있어 브라우저가 여러 Connection을 쓰기도 했습니다. HTTP/2는 Stream Multiplexing으로 HTTP 계층 순차 대기를 크게 개선하지만, TCP 패킷 유실 시 같은 연결의 다른 Stream까지 지연될 수 있습니다(TCP 수준 HOL). HTTP/3(QUIC)는 Stream을 더 독립적으로 다뤄 그 영향을 줄입니다. 다만 앱 Queue의 느린 Job 문제는 HTTP/3만으로 해결되지 않습니다.
DB · 메시지 Queue · Partition
긴 Query·Lock·부족한 Connection이 짧은 Query를 막습니다. 메시지 Queue에서 Poison Message가 앞에 있고 순서를 강제하면 뒤 메시지가 전부 멈춥니다 — Dead Letter Queue로 빼내면 흐름이 이어집니다. 순서 보장과 처리량에는 Trade-off가 있어 Partition(사용자별 등)으로 격리하면 A가 막혀도 B는 진행할 수 있습니다. Hot Partition은 한 Partition에 트래픽이 몰려 그 안의 HOL·지연만 커지는 경우입니다.
완화 전략 묶음
Chunking으로 긴 Job을 나누고, 보고서 등은 동기 HTTP 대신 Job Queue로 넘기며, Deadline·Cancellation·최신 요청 우선·Request Coalescing·Cache·Timeout·Circuit Breaker·Bulkhead·Concurrency Limit·Admission을 상황에 맞게 조합합니다. 모니터링·Tracing에서는 Waiting/Service Time 분리와 Slow Job·Heavy Tail 분포를 봅니다.
자주 묻는 질문
HOL Blocking이란?
맨 앞의 느린 작업 때문에 뒤의 빠른 작업까지 함께 기다리는 현상입니다.
FIFO에서 왜 잘 생기나?
먼저 들어온 것을 반드시 먼저 처리하므로 앞 작업이 길면 뒤가 모두 기다립니다.
Worker만 늘리면 되나?
일부 완화되지만 긴 작업이 Worker를 전부 차지하거나 Backend 병목이 있으면 다시 생깁니다.
HTTP/2에도 있나?
HTTP Stream 병렬화는 좋아졌지만 TCP 패킷 유실이 여러 Stream에 영향을 줄 수 있습니다.
SEO와 관련있나?
SEO 전용 개념은 아닙니다. 중요 요청이 지속 지연되면 응답·체감에 영향을 줄 수 있습니다.
정리
Head-of-Line Blocking = 줄 맨 앞의 느린 작업이 뒤의 빠른 작업을 함께 기다리게 하는 현상입니다. B·C가 느린 게 아니라 A가 앞을 막아서입니다. Queue 분리·Bulkhead·Chunking·Timeout·Cancellation·Priority+Aging 등으로 줄입니다. 그런데 대기 이유는 앞의 느린 작업만이 아닙니다. 여러 작업이 동시에 같은 CPU·DB Connection·Lock을 얻으려 경쟁하면 서로 기다리며 성능이 떨어질 수 있습니다. 이처럼 제한된 자원을 동시에 쓰려다 경쟁하면서 대기와 성능 저하가 생기는 현상을 Resource Contention(리소스 컨텐션, 자원 경합)이라고 합니다.