← 블로그 목록

Developer Knowledge

개발자가 알아야 할 지식: 레이트 리미팅, 친절한 거절도 시스템 설계다

트래픽 폭주와 남용을 막기 위한 rate limit 설계 원칙, 429 응답, Retry-After, 사용자 경험을 정리합니다.

IETF
  • 개발자가 알아야 할 지식
  • HTTP
  • Reliability
  • API Design

서비스를 안정적으로 운영하려면 모든 요청을 끝까지 받아주는 것만큼, 일부 요청을 제때 거절하는 능력도 중요합니다.

왜 개발자가 알아야 하나

레이트 리미팅은 일정 시간 동안 허용할 요청 수를 제한하는 기법입니다. 로그인 시도, 검색 API, 파일 업로드, 메시지 발송, 결제 검증, AI 추론 호출처럼 비용이 크거나 남용될 수 있는 기능에서 특히 중요합니다.

개발자가 이 개념을 알아야 하는 이유는 레이트 리밋이 단순한 방화벽 설정이 아니기 때문입니다. 어디를 기준으로 제한할지, 초과했을 때 어떤 응답을 줄지, 정상 사용자와 공격자를 어떻게 구분할지, 클라이언트가 언제 재시도해야 할지까지 제품과 API 계약이 함께 걸려 있습니다.

제한이 없으면 작은 버그도 장애가 됩니다. 모바일 앱의 자동 재시도 루프, 배치 작업의 잘못된 스케줄, 봇의 반복 요청, 외부 파트너의 급격한 트래픽 증가가 모두 같은 하위 시스템을 압박할 수 있습니다. 좋은 레이트 리밋은 시스템을 보호하면서도 정상 사용자가 무엇을 해야 하는지 알게 해줍니다.

핵심 개념

첫 번째 결정은 기준입니다. IP 주소, 사용자 ID, API 키, 조직 ID, 디바이스, 엔드포인트, 비용 단위 중 무엇으로 제한할지 정해야 합니다. 로그인 실패는 계정과 IP를 함께 봐야 하고, 유료 API는 고객 조직이나 API 키 단위가 더 자연스러울 수 있습니다.

두 번째는 알고리즘입니다. 고정 윈도우는 단순하지만 경계 시점에 요청이 몰릴 수 있습니다. 슬라이딩 윈도우는 더 부드럽지만 구현 비용이 있습니다. 토큰 버킷은 평소에는 토큰을 채우고 순간적인 burst를 일정 부분 허용할 수 있어 API에서 자주 쓰입니다.

세 번째는 응답 계약입니다. HTTP에서는 너무 많은 요청을 의미하는 429 Too Many Requests가 쓰입니다. 가능하면 Retry-After 헤더나 남은 한도 정보를 함께 제공해 클라이언트가 무작정 재시도하지 않게 해야 합니다. 제한은 서버 내부 사정이 아니라 클라이언트와 맺는 계약입니다.

작은 예시 또는 체크리스트

예를 들어 이미지 생성 API가 있다고 합시다. 요청 하나가 비싸고 처리 시간이 길다면 사용자별 분당 요청 수, 조직별 일일 총량, 동시 실행 수를 따로 제한할 수 있습니다. 초과 시에는 429와 함께 “몇 초 뒤 다시 시도하라”는 정보를 주고, UI는 버튼을 잠시 비활성화하거나 대기열 상태를 보여주는 편이 낫습니다.

  • 제한 기준이 IP 하나에만 묶여 있어 공유 네트워크 사용자를 과하게 막고 있지 않은가?
  • 로그인, 검색, 업로드, 알림 발송처럼 비용과 남용 위험이 큰 경로에 별도 정책이 있는가?
  • 초과 응답이 429와 재시도 힌트를 명확히 제공하는가?
  • 클라이언트가 429를 받았을 때 즉시 반복 재시도하지 않는가?
  • 운영자가 한도 초과율, 차단 대상, 상위 호출자를 볼 수 있는가?
  • 유료 플랜, 내부 관리자, 파트너 API처럼 서로 다른 사용량 정책이 코드에 명확히 표현되어 있는가?

실무에서 자주 생기는 오해

  • “CDN이나 WAF에서 막으면 끝난다”는 오해가 있습니다. 엣지 제한은 중요하지만 사용자 ID, 조직 ID, 기능별 비용처럼 애플리케이션만 아는 기준도 있습니다.

  • “429는 장애다”라고만 보는 것도 부족합니다. 정상적으로 설계된 제한은 장애가 아니라 보호 장치입니다. 다만 한도 초과가 급증하면 사용자 경험 문제나 클라이언트 버그를 의심해야 합니다.

  • “강하게 막을수록 안전하다”도 항상 맞지 않습니다. 너무 낮은 한도는 정상 사용자를 밀어내고, 너무 불친절한 응답은 클라이언트의 공격적인 재시도를 부릅니다.

  • “읽기 요청은 제한하지 않아도 된다”는 생각도 위험합니다. 검색, 추천, 리포트, AI 요약처럼 읽기라도 계산 비용이 큰 요청은 충분히 시스템을 무너뜨릴 수 있습니다.

오늘 바로 적용해보기

먼저 최근 장애나 느린 API 하나를 골라 호출자별 요청 분포를 확인해보세요. 평균 요청 수보다 상위 1% 호출자가 시스템에 주는 압박을 보는 것이 중요합니다.

다음으로 429 응답을 클라이언트가 어떻게 처리하는지 확인하세요. 웹, 앱, 배치, 파트너 SDK가 같은 방식으로 재시도하지 않을 수 있습니다. 특히 즉시 재시도 루프가 있으면 레이트 리밋이 오히려 부하 증폭기가 됩니다.

마지막으로 한도 정책을 문서화하세요. 어떤 기준으로, 어느 시간 창에서, 초과 시 어떤 응답을 주는지 적어두면 운영자와 클라이언트 개발자가 같은 계약을 보고 움직일 수 있습니다.

더 알아보기

오늘의 takeaway

좋은 레이트 리밋은 사용자를 막는 장벽이 아니라, 시스템이 모두에게 계속 응답하기 위한 질서입니다.