AI Agent 과부하 제어, 요청이 몰릴 때 백프레셔와 우선순위를 정하는 기준
AI Agent 요청이 한꺼번에 몰릴 때 무조건 큐에 쌓지 않고, 수용량·우선순위·백프레셔·로드 셰딩·재시도 신호를 정하는 실무 기준을 정리합니다.
월요일 오전 9시, 고객 문의 분류 Agent와 보고서 생성 배치가 동시에 시작됐다고 해보겠습니다. 외부 모델 API가 느려지자 워커는 요청을 끝내지 못하고, 웹훅과 재시도는 계속 들어옵니다. 대기열 숫자는 늘지만 실제로 제시간에 끝나는 업무는 오히려 줄어듭니다.
이때 워커 수만 늘리면 모델 API 한도, 데이터베이스 연결, CRM 호출, 비용까지 함께 압박할 수 있습니다. 과부하 제어는 모든 요청을 일단 받는 기술이 아니라, 지금 끝낼 수 있는 일만 받아 중요한 업무의 유효 처리량을 지키는 운영 규칙입니다.

핵심 요약
- 평시 처리량이 아니라 모델 API·DB·외부 도구를 포함한 병목 단계별 안전 수용량과 과부하 신호를 먼저 정합니다.
- 입력은 수락·지연·합치기·기능 축소·거절 중 하나로 처리합니다. 무제한 대기열은 순간 폭주를 장애 이후까지 미루는 방식일 뿐입니다.
- 우선순위는 고객 영향, 업무 마감, 되돌리기 난이도, 나중에 다시 처리할 수 있는지를 기준으로 정하고 고객·업무별 공정성도 함께 둡니다.
- 상위 단계가 속도를 줄일 수 있도록 폴링 일시 중지, 배치 축소, 명시적 지연 응답, 지원되는 경우 429와 Retry-After 같은 백프레셔 신호를 전달합니다.
- 재시도는 한 계층에서 제한된 예산으로 실행하고 백오프와 지터를 적용합니다. queue_depth보다 oldest_item_age, 거절률, 재시도 증폭률, 유효 처리량을 함께 봅니다.
과부하 제어의 목표는 모든 요청을 받는 것이 아니라, 받은 요청을 약속한 시간 안에 끝낼 수 있는 상태를 지키는 것입니다.
과부하 제어는 동시성·타임아웃·멱등성과 무엇이 다를까
동시 실행 제어는 같은 자원에 대해 지금 누가 실행할 수 있는지를 정합니다. 과부하 제어는 서로 다른 업무라도 현재 시스템과 의존 서비스가 더 받아낼 수 있는지, 새 요청을 받아야 하는지를 판단합니다.
타임아웃은 이미 수락한 실행을 언제 더 기다리지 않을지 정하고, 멱등성은 재시도가 최종 부수효과를 중복시키지 않게 합니다. 과부하 제어가 없으면 타임아웃된 요청이 다시 들어와 입력 부하를 더 키울 수 있습니다.
부분 실패 복구는 여러 단계 중 일부만 끝났을 때 이어갈 지점과 보상 작업을 다룹니다. 실무에서는 수용 여부, 동시 실행 수, 종료 시점, 중복 방지, 복구 지점을 각각 정해야 한 규칙의 빈틈을 다른 규칙이 메울 수 있습니다.
먼저 과부하를 어떤 신호로 판단할지 정합니다
CPU 한 가지로는 부족합니다. AI 자동화는 모델 응답, 벡터 검색, 파일 변환, 데이터베이스 연결, SaaS API처럼 병목이 여러 단계에 흩어져 있고, 한 단계가 느려져도 다른 단계의 CPU는 여유로워 보일 수 있습니다.
- queue_depth와 oldest_item_age: 대기 건수와 가장 오래 기다린 업무의 나이를 함께 봅니다. 적은 건수라도 마감이 지난 한 건이 계속 남아 있을 수 있습니다.
- end_to_end_latency와 deadline_miss_total: 모델 호출 시간만이 아니라 입력 수신부터 실제 업무 완료까지 걸린 시간과 약속 시각 초과를 봅니다.
- active_concurrency와 saturation: 워커 수, DB 연결, 외부 API 슬롯, 파일 변환 프로세스가 설정 한도에 얼마나 가까운지 단계별로 봅니다.
- reject·throttle·429와 downstream_error: 우리가 거절한 요청과 외부 서비스가 감속시킨 요청을 분리해 어느 경계에서 막히는지 확인합니다.
- offered_load와 goodput: 들어온 요청 수보다 오류 없이 업무 마감 안에 완료된 요청 수가 유지되는지 봅니다.
임계값은 다른 회사의 숫자를 복사하지 않습니다. 평시·업무 시작 시각·정기 배치·외부 API 지연 상황을 따로 재현하고, 처리량이 더 늘지 않거나 지연이 급격히 커지는 지점보다 여유 있게 수용 상한을 둡니다.
요청을 받았을 때 행동은 다섯 가지로 정합니다
입력 경계에서 업무 종류와 현재 포화도를 보고 행동을 고릅니다. 가장 비싼 모델 호출이나 외부 쓰기를 시작한 뒤 버리는 것보다, 인증·스키마 검증·업무 키 확인 직후에 결정하는 편이 낭비가 적습니다.
- 즉시 수락: 마감 안에 끝낼 여유가 있고 하위 서비스 한도도 남았을 때 실행합니다. 수락 응답은 실제 처리 가능성을 의미해야 합니다.
- 지연 또는 감속: 짧은 폭주라면 제한된 대기열에 넣고, 스케줄러·폴러·업스트림이 새 입력 속도를 낮추게 합니다.
- 합치기 또는 교체: 같은 문서의 미리보기, 같은 날짜의 보고서처럼 최신 결과만 의미가 있으면 대기 요청을 하나로 합치거나 오래된 요청을 교체합니다.
- 안전한 기능 축소: 선택적 요약·추천·서식 변환은 생략하되, 고객 발송이나 데이터 수정처럼 위험한 단계는 축소 모드로 임의 실행하지 않습니다.
- 명시적 거절 또는 사람 인계: 마감을 지킬 수 없거나 위험한 요청은 조용히 쌓지 말고 이유, 다시 시도할 시점, 대체 경로, 담당자 인계 상태를 남깁니다.
AWS Builders' Library가 설명하듯 로드 셰딩은 초과 요청을 일찍 덜어내 수락한 요청의 지연과 유효 처리량을 지키는 방식입니다. 거절 자체를 없애려다 전체 요청이 늦게 실패하는 상태를 만들지 않는 것이 핵심입니다.
우선순위와 공정성을 한 세트로 설계합니다
- 업무 영향: 고객에게 이미 약속된 응답, 보안·정산·장애 복구는 단순 미리보기나 재생성보다 먼저 처리할 수 있습니다.
- 업무 마감: '중요 고객' 같은 고정 라벨보다 실제 남은 시간과 지연 비용을 봅니다. 마감이 없는 배치는 낮은 우선순위로 이동할 수 있습니다.
- 고객·워크플로우 격리: 한 고객의 대량 업로드나 한 종류의 배치가 전체 실행 슬롯을 차지하지 않도록 고객별 한도와 공정한 대기열을 둡니다.
- 기아 방지: 낮은 우선순위 업무도 기다린 시간이 길어지면 점진적으로 순위를 올리거나 별도 예약 용량에서 처리합니다.
우선순위는 한 업무가 모든 제한을 우회하는 면허가 아닙니다. Kubernetes API Priority and Fairness처럼 중요 흐름을 보호하되, 초과 트래픽은 제한된 대기열이나 거절 정책으로 분리하고 같은 등급 안에서도 한 요청 흐름이 다른 흐름을 굶기지 않게 해야 합니다.
백프레셔가 입력 단계까지 전달되게 만드는 6단계
백프레셔는 워커 내부 변수 하나가 아니라 입력을 만드는 상위 단계가 속도를 줄이도록 보내는 신호입니다. 큐만 천천히 소비하고 웹훅·배치·재시도가 같은 속도로 계속 들어오면 압력은 사라지지 않습니다.
- 병목 지도를 만듭니다. 입력 API, 검증, 모델, 검색, 외부 도구, 저장 단계마다 동시 실행 수·평균 처리시간·외부 한도를 기록합니다.
- 비싼 작업 전에 admission gate를 둡니다. API 수신, 스케줄 실행, 메시지 소비, 폴링 시작 지점에서 현재 포화도와 업무 등급을 확인합니다.
- 대기열의 최대 건수와 최대 나이를 정합니다. 한쪽만 정하면 짧은 요청과 긴 요청이 섞일 때 실제 대기 위험을 놓칠 수 있습니다.
- 업스트림 반응을 연결합니다. 폴링을 늦추고, 배치 크기를 줄이고, 예약 시간을 미루고, 지원되는 HTTP 경계에서는 429와 Retry-After처럼 다시 시도할 조건을 명확히 보냅니다.
- 포화 시 업무별 행동을 연결합니다. 최신 요청 합치기, 선택 기능 생략, 별도 저속 큐 이동, 명시적 거절, 사람 인계 중 무엇을 쓸지 정합니다.
- 버스트와 의존 서비스 지연을 주입해 시험합니다. 평소보다 많은 입력뿐 아니라 모델 API가 느려지고 DB 연결이 줄어든 상황에서도 중요한 업무의 완료가 유지되는지 확인합니다.
HTTP 429는 요청이 일정 시간에 너무 많았음을 알리는 표준 응답이고 Retry-After는 다시 시도할 시간을 함께 알릴 수 있습니다. 다만 모든 웹훅이나 SaaS가 이 신호를 지원하지는 않으므로, 예약 재실행·상태 페이지·사람 인계 같은 업무 수준의 반응도 준비해야 합니다.
대기열과 재시도가 과부하를 증폭하지 않게 합니다
- 대기열은 짧은 순간 폭주를 흡수하는 완충 장치입니다. 지속 입력이 지속 처리량보다 크면 결국 차기 때문에 자동 확장이나 무제한 보관의 대체가 아닙니다.
- 건수뿐 아니라 oldest_item_age, 업무 마감, 예상 처리시간을 보고 수락합니다. 이미 마감을 넘길 요청을 오래 보관한 뒤 실행하지 않습니다.
- 재시도는 호출 체인의 한 계층에서만 책임지고 총 시도 횟수와 전체 시간 예산을 제한합니다. 여러 계층이 각각 재시도하면 하위 서비스 부하가 빠르게 증폭됩니다.
- 일시 오류에만 지수 백오프와 지터를 적용하고, 상대가 Retry-After를 제공하면 그 신호를 우선합니다. 모든 클라이언트가 같은 시각에 다시 시작하지 않게 합니다.
- 영구 오류, 권한 오류, 잘못된 입력, 업무 마감 경과는 자동 재시도하지 않습니다. 외부 쓰기는 멱등성 키와 현재 상태 확인 뒤 재개합니다.
운영 화면에는 retry_attempt_total / original_request_total 같은 재시도 증폭률을 추가하세요. 원 요청은 그대로인데 하위 호출만 늘어난다면 새 고객 수요가 아니라 복구 로직이 과부하를 만들고 있을 수 있습니다.
업무 시나리오별로 포화 정책을 다르게 둡니다
고객 문의를 분류하고 CRM을 갱신하는 Agent
새 문의의 기본 접수와 고객에게 보이는 상태는 먼저 보호합니다. 선택적 요약·추천은 축소할 수 있지만 CRM 쓰기 실패를 성공처럼 숨기지 않습니다. 고객별 동시성 한도와 전체 예약 용량을 두고, 지연 시 예상 처리 상태를 보여줍니다.
대량 문서를 요약하거나 RAG 인덱스를 갱신하는 배치
대화형 질문보다 낮은 우선순위로 두고 입력 속도를 조절합니다. 같은 데이터 소스의 새 버전이 오면 아직 시작하지 않은 옛 요청을 합치고, 온라인 업무가 포화되면 배치를 일시 중지한 뒤 체크포인트에서 이어갑니다.
캠페인 보고서와 미리보기를 생성하는 자동화
제출 마감이 있는 최종 보고서는 예약 용량을 확보하고, 반복 클릭으로 들어온 미리보기는 최신 한 건만 남깁니다. 마감 안에 끝낼 수 없는 새 요청은 조용히 대기시키지 말고 가능한 완료 시각이나 수동 경로를 안내합니다.
과부하 제어가 무너지는 흔한 이유
- 오토스케일만 믿습니다. 병목이 외부 모델 API, DB 연결, 단일 공유 자원, 비용 한도라면 워커 증설이 오히려 호출 폭주를 키울 수 있습니다.
- 대기열을 무제한으로 엽니다. 장애가 끝난 뒤 마감이 지난 요청과 재시도가 한꺼번에 풀려 두 번째 과부하를 만듭니다.
- 모든 호출 계층이 재시도합니다. 사용자 화면, API, 워커, SDK가 각각 두세 번 시도하면 하위 서비스에는 원 요청보다 훨씬 많은 호출이 도착합니다.
- 전역 우선순위 하나만 둡니다. 한 고객이나 한 긴 배치가 같은 등급의 다른 업무까지 굶길 수 있으므로 고객·업무별 공정성이 필요합니다.
- 비싼 모델 호출과 파일 변환을 끝낸 뒤 마지막 저장 단계에서만 거절합니다. 가능한 한 앞단에서 유효성, 용량, 마감, 중복 여부를 판단해야 합니다.
운영 대시보드에서 볼 지표
- offered / accepted / delayed / coalesced / shed_total: 들어온 요청이 어떤 정책으로 처리됐는지 업무·고객·사유별로 봅니다.
- queue_depth / oldest_item_age / deadline_miss_total: 대기열 크기, 가장 오래된 업무, 업무 마감 초과를 함께 봅니다.
- active_concurrency / configured_limit / downstream_saturation: 워커, 모델, DB, 외부 도구별 현재 사용량과 한도 차이를 봅니다.
- goodput / end_to_end_p95·p99 / error_rate: 들어온 양이 아니라 마감 안에 유용하게 완료한 양과 지연·오류를 봅니다.
- retry_amplification / 429_total / Retry-After 준수율: 원 요청 대비 재시도 호출, 감속 응답, 클라이언트가 실제로 기다렸는지를 봅니다.
경보는 단순 큐 건수보다 '가장 오래된 업무가 고객 마감의 일정 비율을 넘음', '유효 처리량이 줄면서 재시도 증폭률이 오름'처럼 조합해 만드세요. 캐시나 모델 변경 뒤에는 같은 부하 시험을 다시 실행해 안전 수용량을 갱신합니다.
배포 전 과부하 제어 체크리스트
자주 묻는 질문
Q. 백프레셔와 속도 제한(rate limiting)은 같은가요?
속도 제한은 일정 시간에 허용할 요청 수를 제한하는 한 가지 장치입니다. 백프레셔는 현재 처리 상태를 상위 단계에 전달해 폴링, 배치, 재시도, 입력 자체가 느려지게 만드는 더 넓은 흐름입니다. 고정 속도 제한만으로는 하위 서비스가 갑자기 느려진 상황을 충분히 반영하지 못할 수 있습니다.
Q. 고객 요청을 거절하면 사용자 경험이 더 나빠지지 않나요?
늦게 실패하거나 성공처럼 보인 뒤 사라지는 요청보다, 지연 이유와 예상 재개 시점, 대체 경로를 명확히 알려주는 편이 운영상 안전합니다. 중요한 입력은 접수 상태만 먼저 저장하고 실행은 제한된 큐로 넘기거나, 위험도가 높으면 담당자 인계로 전환할 수 있습니다.
Q. 오토스케일링을 적용하면 로드 셰딩은 없어도 되나요?
아닙니다. 계산 자원이 병목이고 충분히 빨리 늘릴 수 있다면 오토스케일링이 도움이 됩니다. 하지만 모델 API 한도, DB 연결, 외부 SaaS, 순서가 필요한 공유 자원, 비용 한도는 워커만 늘려 해결되지 않으므로 수용 제어와 백프레셔가 함께 필요합니다.
HeyRatty와 요청이 몰려도 끝까지 운영되는 자동화를 설계하려면
HeyRatty는 Agent를 연결하기 전에 병목 단계, 업무 마감, 고객별 입력 패턴, 외부 서비스 한도, 수용·지연·거절·사람 인계 흐름을 함께 정리합니다. 그래야 자동화가 바쁠 때도 중요한 업무를 보호하고, 큐와 재시도가 조용히 장애를 키우지 않습니다.
처음부터 복잡한 트래픽 플랫폼을 도입할 필요는 없습니다. 요청이 가장 자주 몰리는 자동화 하나를 골라 '지금 몇 건까지 끝낼 수 있는가', '넘친 요청은 무엇을 합치고 무엇을 미룰 것인가', '상위 단계는 어떤 신호를 받고 속도를 줄일 것인가'부터 적어보세요. 현재 흐름이 복잡하다면 HeyRatty가 작은 부하 시험과 운영 체크리스트부터 함께 설계할 수 있습니다.
참고 및 이미지 출처
- AWS Builders' Library — Using load shedding to avoid overload
- Google SRE — Handling Overload / Managing Load
- Kubernetes Documentation — API Priority and Fairness
- RFC 6585 Section 4 — 429 Too Many Requests
- 이미지 원본: Wikimedia Commons 「Hartwell Dam Spillway Release - July 9, 2013 (9256762362).jpg」 · 촬영 Doug Young / 소유·제공 U.S. Army Corps of Engineers Savannah District · Commons에서 CC BY 2.0 확인; 미국 연방정부 저작물로 미국 내 퍼블릭 도메인 · Commons가 제공한 1920×1280 JPEG URL을 직접 사용했습니다. 로컬 생성 이미지 0장.