한 고객사가 야간에 대량 동기화 작업을 시작했습니다. 그 고객사의 API 호출이 몰리면서 다른 고객사의 관리자 화면까지 느려집니다. 서버를 더 늘려 잠깐 버틸 수는 있어도, 한 고객이 공유 자원을 얼마까지 사용할 수 있는지 정하지 않으면 같은 일이 반복됩니다. 레이트 리밋은 고객을 막기 위한 벌칙이 아니라 공유 서비스의 공정성을 지키는 계약입니다.
무엇을 제한할지부터 정한다
‘분당 요청 수’는 이해하기 쉽지만 모든 API의 비용이 같지는 않습니다. 작은 조회 한 번과 수만 건 보고서 생성 한 번을 똑같이 세면 실제 부하를 반영하지 못합니다. 먼저 병목이 생기는 자원을 찾습니다. 데이터베이스 연결 수, 동시에 실행 중인 무거운 요청, 검색 인덱스 작업, 외부 API 할당량처럼 서비스가 먼저 포화되는 곳이 기준입니다.
경계도 여러 개입니다. 전체 서비스 상한은 시스템을 보호하고, 테넌트 상한은 고객사 간 간섭을 줄이며, 사용자 또는 API 키 상한은 특정 스크립트의 실수를 제한합니다. 모두 같은 숫자를 쓰지 않습니다. 읽기와 쓰기, 동기 조회와 오래 걸리는 작업도 다른 정책이 필요할 수 있습니다. Azure의 Throttling 패턴 역시 애플리케이션 인스턴스·개별 테넌트·서비스 전체의 자원 사용을 구분해 제한하도록 설명합니다.
테넌트 ID를 신뢰할 수 있게 확인한다
제한 키를 요청 본문의 고객사 이름으로 잡으면 호출자가 다른 고객사를 사칭해 할당량을 소모시킬 수 있습니다. 인증된 토큰이나 서버가 검증한 조직 식별자를 기준으로 사용량을 집계합니다. 한 사람이 여러 고객사에 속할 수 있다면 현재 선택한 조직과 실제 데이터 접근 권한을 먼저 확인해야 합니다. API 키 하나를 여러 고객사가 공유하는 구조도 누가 얼마를 썼는지 설명하기 어렵습니다.
토큰 버킷은 흔한 구현 방식입니다. 일정한 속도로 채워지는 토큰을 요청이 소비하므로 짧은 순간의 정상적인 버스트는 허용하면서 지속적인 과부하는 제한할 수 있습니다. 하지만 알고리즘을 고르기 전에 ‘허용할 순간 피크와 회복 속도’를 제품 정책으로 정해야 합니다. 복수 서버에서 사용량을 세면 카운터의 일관성도 고려해야 합니다.

거절할 때도 API 계약을 지킨다
고객별 할당량 초과에는 보통 HTTP 429를 쓰고, 잠시 기다렸다 재시도해도 되는 경우에는 Retry-After를 제공합니다. 서비스 전체가 과부하인 상황은 503처럼 구분할 수 있습니다. 응답 본문에는 어떤 범위의 제한인지, 언제 다시 시도할 수 있는지, 요청 ID가 무엇인지 알려주면 고객사 개발자가 대응할 수 있습니다. 단, 내부 구성이나 타 고객의 사용량은 노출하지 않습니다.
클라이언트는 429를 받았을 때 즉시 무한 재시도하면 안 됩니다. 권장 대기 시간을 따르고, 재시도 횟수와 전체 시간을 제한합니다. 여러 작업이 동시에 깨어나지 않도록 작은 무작위 지연을 섞을 수도 있습니다. Azure의 Retry Storm 설명처럼 과도한 재시도는 복구 중인 서비스를 더 압박합니다.

운영 지표는 거절 횟수만으로 부족하다
테넌트별 요청률, 429 비율, 동시 실행 수, 대기 시간, 요청 비용이 높은 엔드포인트를 함께 봅니다. 제한에 걸린 고객이 항상 같은 고객인지, 제품이 권장하는 사용 방식으로도 제한에 자주 걸리는지 살펴야 합니다. 정당한 업무가 막힌다면 정책을 조정하거나 대량 작업 전용 API·비동기 경로를 제공하는 것이 맞을 수 있습니다.
무료·유료 요금제에 다른 상한을 줄 수는 있지만 가격표의 숫자만으로 서버 안전을 보장할 수 없습니다. 고객에게 약속한 할당량과 시스템이 실제로 감당할 수 있는 동시 처리량을 분리해 관리합니다. 부하가 낮을 때 한 고객에게 더 허용할지, 초과분을 큐에 넣을지, 즉시 거절할지도 미리 정합니다. 큐를 쓰는 경우 처리 지연과 작업 상태를 고객에게 보여줘야 합니다.
정책을 처음 도입할 때는 바로 차단하기보다 일정 기간 ‘차단했을 요청’을 기록하는 관찰 모드가 유용합니다. 이 기간에 정상 고객의 월말 배치 작업이나 관리자 보고서가 얼마나 영향을 받는지 확인합니다. 계약상 보장한 호출량과 실제 트래픽 패턴이 다르면 고객과 조정해야 합니다. 제한 정책의 변경 이력도 남겨 고객 문의에 설명할 수 있게 합니다.
적용 체크리스트
- 공유 자원의 실제 병목과 제한 단위를 찾았는가?
- 검증된 테넌트 ID를 기준으로 사용량을 분리하는가?
- 순간 버스트와 지속 부하에 다른 반응을 주는가?
- 429 응답에 안전한 재시도 안내가 있는가?
- 정상 고객의 업무가 반복해서 막히는지 측정하는가?
좋은 제한 정책은 호출을 무조건 적게 만드는 정책이 아닙니다. 한 고객의 급증 속에서도 다른 고객이 일을 계속하고, 제한을 받은 고객은 무엇을 조정해야 하는지 이해할 수 있게 만드는 정책입니다.
#API레이트리밋 #멀티테넌트 #SaaS아키텍처 #429응답 #RetryAfter #토큰버킷 #API운영 #공정한사용량 #트래픽제어 #서비스안정성