HTTP Error 429 Too Many Requests: 원인 분석과 해결 방법

HTTP Error 429란 무엇인가?
HTTP error 429는 Too Many Requests(요청이 너무 많음)를 의미하는 클라이언트 오류 상태 코드입니다. 서버가 정해진 시간 내에 너무 많은 요청을 받았다고 판단하여, 속도를 줄일 때까지 추가 요청 처리를 일시적으로 거부하는 것입니다.
이 오류는 RFC 6585에 정의되어 있으며, HTTP 레이트 리미팅(속도 제한) 메커니즘의 일부입니다. API를 다루는 개발자에게 가장 흔한 오류 중 하나이지만, 일반 사용자도 웹사이트를 탐색하다가 마주칠 수 있습니다.
429 상태 코드는 다른 4xx 오류와 성격이 다릅니다. 403 오류는 접근 권한이 없다는 뜻이고, 401 오류는 인증이 필요하다는 뜻입니다. 반면 429 오류는 인증 정보에는 문제가 없지만, 요청을 너무 빠르게 보내고 있다는 의미입니다.
서버가 429 응답을 반환할 때 Retry-After 헤더를 포함하는 경우가 있는데, 이 헤더는 다음 요청을 보내기까지 정확히 얼마나 기다려야 하는지 알려줍니다.
429 오류는 어떻게 표시되나?
429 오류는 사용 중인 브라우저, 애플리케이션, API 클라이언트에 따라 다르게 표시됩니다. 가장 흔한 표시 형태를 정리하면 다음과 같습니다:
| 환경 | 오류 메시지 |
|---|---|
| Chrome / Edge | 429 Too Many Requests |
| Firefox | 429 Too Many Requests |
| Nginx | 429 Too Many Requests (nginx) |
| Apache | 429 Too Many Requests |
| Cloudflare | Error 429 — Rate Limited |
| API 응답 | {"error": "rate_limit_exceeded", "retry_after": 60} |
| WordPress | 429 Too Many Requests — You have been rate limited |
| cURL | HTTP/1.1 429 Too Many Requests |
서버 측 문제를 나타내는 500 오류와 달리, 429는 클라이언트 측 오류입니다. 서버 자체는 정상적으로 작동하고 있으며, 과도한 요청으로부터 자신을 보호하기 위해 요청을 거부하는 것입니다.
레이트 리미팅의 작동 원리
레이트 리미팅(속도 제한)은 특정 시간 범위 내에 클라이언트가 보낼 수 있는 요청 수를 제어하는 기술입니다. 설정된 한도를 초과하면 서버는 HTTP 429로 응답합니다.
일반적으로 사용되는 레이트 리미팅 알고리즘은 다음과 같습니다:
고정 윈도우(Fixed Window) — 서버가 시간 창당 N개의 요청을 허용합니다(예: 분당 100개 요청). 카운터는 고정된 간격으로 초기화됩니다.
슬라이딩 윈도우(Sliding Window) — 고정 윈도우와 유사하지만, 각 요청마다 시간 창이 이동합니다. 윈도우 경계에서 발생하는 갑작스러운 트래픽 폭주를 방지합니다.
토큰 버킷(Token Bucket) — 서버가 일정한 속도로 토큰을 보충합니다. 각 요청은 토큰 하나를 소비하며, 토큰이 모두 소진되면 요청이 거부됩니다.
리키 버킷(Leaky Bucket) — 폭주 규모에 관계없이 일정한 속도로 요청을 처리합니다. 초과 요청은 대기열에 쌓이거나 폐기됩니다.
대부분의 API는 응답 헤더를 통해 레이트 리미팅 정보를 알려줍니다. 주로 사용되는 헤더로는 X-RateLimit-Limit(최대 허용 요청 수), X-RateLimit-Remaining(현재 윈도우에서 남은 요청 수), X-RateLimit-Reset(윈도우가 초기화되는 시점)이 있습니다.
서비스가 어떤 알고리즘을 사용하는지 이해하면, 한도 내에서 클라이언트를 설계하여 429 오류를 피할 수 있습니다.
HTTP Error 429의 주요 원인
429 오류는 다양한 상황에서 발생할 수 있습니다. 주로 영향을 받는 대상별로 분류한 주요 원인은 다음과 같습니다:
| 원인 | 영향 대상 | 설명 |
|---|---|---|
| API 레이트 리미트 초과 | 개발자 | 서비스가 허용하는 분당/시간당 API 요청 수를 초과함 |
| 과도한 페이지 요청 | 방문자 | 페이지를 너무 빠르게 새로고침하거나 동시에 너무 많은 탭을 열었음 |
| 웹 스크래핑 / 봇 | 개발자 | 자동화 스크립트가 웹사이트에 너무 빠르게 접근하여 레이트 리미팅이 작동함 |
| 무차별 대입 공격 방어 | 방문자 | 로그인 실패가 너무 많아 보안 레이트 리미팅이 작동함 |
| DDoS 방어 | 모든 사용자 | Cloudflare, AWS WAF 등의 서비스가 트래픽 급증을 차단함 |
| 공유 IP 레이트 리미팅 | 방문자 / VPN 사용자 | 같은 IP를 사용하는 여러 사용자(VPN, 프록시, 회사 네트워크)가 합산하여 한도를 초과함 |
| 레이트 리미팅 설정 오류 | 웹사이트 관리자 | 서버 측 레이트 리미팅이 너무 엄격하게 설정되어 정상 트래픽이 차단됨 |
| 플러그인 또는 테마 문제 | 웹사이트 관리자 | WordPress 플러그인이 과도한 API 호출을 하거나 크론 작업이 너무 자주 실행됨 |
| 웹훅 폭주 | 개발자 | 설정 오류가 있는 웹훅이 실패한 전송을 짧은 간격으로 재시도함 |
방문자를 위한 429 오류 해결 방법
웹사이트를 탐색하다가 429 오류를 발견했다면, 아래 해결 방법을 순서대로 시도해보세요. 가장 간단한 방법부터 시작합니다.
1. 잠시 기다린 후 다시 시도
가장 간단한 해결 방법은 기다리는 것입니다. 429 오류는 일시적인 것으로, 서버가 영구적으로 차단하는 것이 아니라 속도를 줄여달라고 요청하는 것입니다.
30초에서 몇 분 정도 기다린 후 다시 시도하세요. 대부분의 레이트 리미팅은 1~5분 내에 해제됩니다. 그래도 429가 계속 표시되면 더 오래 기다리세요. 일부 서비스는 시간 단위 또는 일 단위로 제한을 적용합니다.
페이지를 반복적으로 새로고침하지 마세요. 새로고침할 때마다 새로운 요청이 발생하여 레이트 리미팅 기간이 연장될 수 있습니다.
2. 브라우저 캐시 및 쿠키 삭제
캐시된 데이터나 쿠키가 레이트 리미팅을 유발하는 경우가 있습니다. 이를 삭제하면 문제가 해결될 수 있습니다:
Chrome:
Ctrl+Shift+Delete(Windows) 또는Cmd+Shift+Delete(Mac) 누르기 → "쿠키" 및 "캐시된 이미지" 선택 → "데이터 삭제" 클릭Firefox:
Ctrl+Shift+Delete누르기 → "캐시" 및 "쿠키" 선택 → "지금 삭제" 클릭Edge:
Ctrl+Shift+Delete누르기 → "쿠키" 및 "캐시된 데이터" 선택 → "지금 지우기" 클릭Safari: Safari → 설정 → 개인 정보 보호 → 웹 사이트 데이터 관리 → 모두 제거
삭제 후 브라우저를 완전히 닫았다가 다시 열고 사이트에 접속하세요.
3. VPN 또는 프록시 연결 해제
VPN이나 프록시를 사용 중이라면, 수백 명의 다른 사용자와 같은 IP 주소를 공유하고 있을 수 있습니다. 이들의 요청이 합산되어 서버의 한도를 초과하면, 해당 IP의 모든 사용자가 레이트 리미팅에 걸립니다.
VPN 연결을 해제하고 일반 인터넷 연결로 사이트에 접속해보세요. 429 오류가 사라지면, VPN IP가 원인이었던 것입니다.
VPN을 반드시 사용해야 한다면, 다른 서버 위치로 전환하여 새로운 IP 주소를 받아보세요.
4. 브라우저 확장 프로그램 비활성화
일부 브라우저 확장 프로그램은 사용자가 모르는 사이에 백그라운드에서 요청을 보냅니다. 광고 차단기, 가격 비교 도구, SEO 확장 프로그램, 자동 새로고침 플러그인 등이 추가적인 요청을 발생시켜 레이트 리미팅을 유발할 수 있습니다.
확인하려면 시크릿/프라이빗 창에서 사이트를 열어보세요(대부분의 확장 프로그램이 기본적으로 비활성화됩니다). 429 오류가 사라지면, 확장 프로그램 중 하나가 원인입니다.
확장 프로그램을 하나씩 비활성화하여 문제가 되는 것을 찾으세요. Chrome에서는 chrome://extensions/에서 개별적으로 끄고 켤 수 있습니다.
5. 다른 네트워크에서 시도
위의 방법으로도 해결되지 않으면, 서버가 사용자의 IP 주소를 구체적으로 제한하고 있을 수 있습니다. 다음을 시도해보세요:
Wi-Fi에서 모바일 데이터로 전환하세요(다른 IP를 받게 됩니다). 완전히 다른 네트워크에서 사이트에 접속해보세요. 회사나 학교 네트워크를 사용 중이라면 집에서 시도해보세요. 대규모 네트워크는 하나의 공인 IP를 공유하기 때문입니다.
What Is My IP 도구를 사용하면 현재 IP 주소가 변경되었는지 확인할 수 있습니다.
개발자를 위한 429 오류 해결 방법
API를 호출하는 애플리케이션을 개발 중이라면, 429 오류는 코드가 너무 빠르게 요청을 보내고 있다는 의미입니다. 올바른 처리 방법을 알아보겠습니다.
1. 지수 백오프 구현
지수 백오프(Exponential Backoff)는 업계 표준 재시도 전략입니다. 429를 받은 즉시 재시도하는 대신, 재시도 간의 대기 시간을 점진적으로 늘립니다:
첫 번째 재시도: 1초 대기. 두 번째 재시도: 2초 대기. 세 번째 재시도: 4초 대기. 네 번째 재시도: 8초 대기. 이런 식으로 계속합니다.
JavaScript로 구현한 기본 코드는 다음과 같습니다:
async function fetchWithBackoff(url, options = {}, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
// Check Retry-After header first
const retryAfter = response.headers.get('Retry-After');
const delay = retryAfter
? parseInt(retryAfter) * 1000
: Math.pow(2, attempt) * 1000; // Exponential backoff
console.log(`Rate limited. Retrying in ${delay / 1000}s...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
throw new Error('Max retries exceeded');
}여러 클라이언트가 정확히 같은 타이밍에 재시도하는 것을 방지하려면 지터(jitter, 무작위 변동)를 추가하세요. 지연 시간 계산을 Math.pow(2, attempt) * 1000 + Math.random() * 1000으로 바꾸면 됩니다.
2. Retry-After 헤더 준수
서버가 429 응답을 반환할 때, 정확히 얼마나 기다려야 하는지 알려주는 Retry-After 헤더를 포함하는 경우가 많습니다. 이 헤더에는 초 단위의 숫자 또는 HTTP 날짜가 포함될 수 있습니다:
Retry-After: 60은 60초 동안 대기하라는 뜻입니다. Retry-After: Thu, 06 Mar 2026 12:00:00 GMT는 해당 시각까지 대기하라는 뜻입니다.
자체 백오프 로직을 적용하기 전에 항상 이 헤더를 먼저 확인하세요. 대기 시간에 관해서는 코드보다 서버가 더 정확히 알고 있습니다.
import requests
import time
def make_request(url):
response = requests.get(url)
if response.status_code == 429:
retry_after = response.headers.get('Retry-After', '5')
wait_time = int(retry_after)
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(wait_time)
return make_request(url) # Retry after waiting
return response3. API 응답 캐싱
애플리케이션이 동일한 API 호출을 여러 번 수행한다면, 매번 API를 호출하는 대신 응답을 캐싱하세요. 요청 수를 획기적으로 줄일 수 있습니다.
자주 접근하는 데이터에는 인메모리 캐시(Redis 또는 간단한 Map 등)를 사용하세요. 데이터의 변경 빈도에 따라 적절한 TTL(유효 기간)을 설정합니다.
예를 들어, 도메인의 DNS 레코드를 조회하는 경우 5분 이내에 결과가 변경될 가능성은 거의 없으므로, 캐싱하는 것이 효율적입니다.
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function cachedFetch(url) {
const cached = cache.get(url);
if (cached && Date.now() - cached.time < CACHE_TTL) {
return cached.data;
}
const response = await fetch(url);
const data = await response.json();
cache.set(url, { data, time: Date.now() });
return data;
}4. 폴링 대신 웹훅 사용
변경 사항을 확인하기 위해 API를 반복적으로 호출하고 있다면(예: 10초마다 주문 상태 확인), 서비스가 지원하는 경우 웹훅으로 전환하세요.
웹훅을 사용하면 변경이 발생했을 때 서버가 애플리케이션에 업데이트를 직접 보내주므로, 지속적인 폴링이 필요 없습니다. 시간당 수천 건의 API 호출을 단 몇 건으로 줄일 수 있습니다.
대부분의 최신 API(Stripe, GitHub, Twilio, Shopify 등)가 웹훅을 지원합니다. API 문서에서 웹훅 설정 방법을 확인하세요.
5. 더 높은 레이트 리미트 요청
정당하게 더 많은 API 호출이 필요하다면, 서비스 제공업체에 문의하세요. 많은 API가 유료 플랜이나 인증된 애플리케이션에 대해 더 높은 레이트 리미트를 제공합니다.
더 높은 한도를 요청할 때는 사용 사례를 설명하고 예상 요청량을 제시하세요. Google APIs, Twitter API, GitHub API 등은 모두 상향된 한도를 요청하는 절차를 갖추고 있습니다.
일부 API는 단일 요청으로 여러 리소스를 가져올 수 있는 벌크 엔드포인트를 제공하여 전체 호출 수를 줄일 수 있게 해줍니다.
웹사이트 관리자를 위한 429 오류 해결 방법
방문자나 API 사용자가 429 오류를 겪고 있다면, 서버 설정에 문제가 있는 것입니다. 진단 및 해결 방법을 알아보겠습니다.
1. 레이트 리미팅 규칙 조정
정상적인 사용자가 429 오류를 겪고 있다면, 레이트 리미팅이 너무 엄격하게 설정되어 있을 수 있습니다. 설정을 검토하고 조정하세요.
Nginx에서는 레이트 리미팅 모듈(ngx_http_limit_req_module)이 요청 속도를 제어합니다:
# Define rate limit zone: 10 requests per second per IP
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
# Allow bursts of 20, no delay for first 10
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
}
}burst 매개변수가 중요합니다. 이를 설정하면 짧은 트래픽 급증에도 429가 발생하지 않습니다. 이 설정 없이는 일반적인 브라우징 패턴에서도 한도에 도달할 수 있습니다.
Apache에서는 mod_ratelimit 또는 mod_evasive를 사용하고, Node.js에서는 express-rate-limit 같은 패키지를 사용하세요.
2. 신뢰할 수 있는 IP 화이트리스트 등록
특정 클라이언트(모니터링 서비스, 결제 처리 업체, 자체 마이크로서비스)가 레이트 리미팅에 걸린다면, 해당 IP 주소를 화이트리스트에 추가하세요.
Nginx에서는 map을 사용하여 신뢰할 수 있는 IP에 대해 레이트 리미팅을 우회할 수 있습니다:
geo $rate_limit {
default 1;
192.168.0.0/16 0; # Internal network
10.0.0.0/8 0; # Internal network
203.0.113.50 0; # Payment processor
}
map $rate_limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=api:10m rate=10r/s;검색 엔진 봇(Googlebot, Bingbot)이 레이트 리미팅에 걸리고 있다면 반드시 화이트리스트에 추가하세요. 이들을 차단하면 SEO에 악영향을 미칩니다. 역방향 DNS 조회를 사용하면 봇의 정체를 확인할 수 있습니다.
3. WAF 및 CDN 설정 확인
Cloudflare, AWS WAF, Sucuri 등의 보안 서비스를 사용 중이라면, 원본 서버가 아닌 해당 서비스의 레이트 리미팅 규칙이 429 오류의 원인일 수 있습니다.
Cloudflare에서는 보안 → WAF → Rate Limiting Rules를 확인하세요. 어떤 규칙이 작동하고 있는지 확인하고 임계값을 조정할 수 있습니다. Cloudflare의 기본 "I'm Under Attack" 모드는 특히 공격적으로 작동합니다.
AWS WAF에서는 Web ACL 규칙 중 rate-based 규칙을 확인하세요. 최소 임계값은 5분당 100개 요청입니다. 이 값이 트래픽 수준에 적합한지 확인하세요.
한도를 조정하기 전에 CDN 분석을 통해 정상 트래픽과 봇 트래픽을 구분하세요.
4. 서버 성능 최적화
서버가 부하를 감당하지 못하여 안전 장치로 레이트 리미팅이 작동하는 경우, 429 오류가 발생할 수 있습니다. 서버 성능을 개선하면 레이트 리미팅 한도를 안전하게 높일 수 있습니다.
주요 최적화 방법으로는 응답 캐싱을 활성화하여 백엔드 부하를 줄이고, 정적 자산에 CDN을 사용하고, Redis나 Memcached로 데이터베이스 쿼리 캐싱을 추가하고, 데이터베이스 연결에 커넥션 풀링을 구현하며, 트래픽이 충분한 경우 로드 밸런싱으로 수평 확장하는 것이 있습니다.
HTTP Headers 도구를 사용하면 캐싱 헤더가 올바르게 설정되어 있는지 확인할 수 있습니다.
429 오류와 다른 HTTP 오류 비교
429 오류는 다른 HTTP 상태 코드와 혼동하기 쉽습니다. 각각의 차이점을 정리하면 다음과 같습니다:
| 상태 코드 | 이름 | 의미 | 핵심 차이점 |
|---|---|---|---|
| [401](/blog/http-401-unauthorized) | Unauthorized | 인증이 필요함 | 자격 증명이 없거나 유효하지 않음 |
| [403](/blog/403-forbidden-error) | Forbidden | 접근이 영구적으로 거부됨 | 권한이 없음 |
| **429** | **Too Many Requests** | **일시적으로 레이트 리미팅됨** | **요청을 너무 빠르게 보내고 있음** |
| [500](/blog/http-error-500) | Internal Server Error | 서버 오류 발생 | 서버 측 버그 또는 장애 |
| [502](/blog/http-error-500) | Bad Gateway | 업스트림 서버 장애 | 프록시가 백엔드에 연결하지 못함 |
| [503](/blog/http-error-503) | Service Unavailable | 서버 과부하 또는 점검 중 | 서버가 너무 바빠서 응답할 수 없음 |
| [504](/blog/504-gateway-timeout) | Gateway Timeout | 업스트림 서버 응답 시간 초과 | 백엔드가 시간 내에 응답하지 않음 |
핵심 차이점은 429는 일시적이고 의도적이라는 것입니다. 서버는 정상적으로 작동하고 있으며, 자체 보호를 위해 요청을 거부하기로 능동적으로 결정한 것입니다. 반면 5xx 오류는 실제로 서버에 문제가 발생했음을 나타냅니다.
429 오류를 예방하는 방법
예방이 치료보다 낫습니다. 429 오류를 사전에 방지하기 위한 모범 사례를 소개합니다:
API 문서 숙지 — 코드를 작성하기 전에 레이트 리미팅 한도를 확인하세요. 대부분의 서비스가 한도를 명확하게 공개합니다.
사용량 모니터링 —
X-RateLimit-Remaining헤더를 추적하여 한도에 얼마나 가까운지 파악하세요.요청 일괄 처리 — 개별 호출 대신 벌크 엔드포인트를 사용하세요.
요청 분산 — 한꺼번에 보내지 말고 API 호출을 시간에 걸쳐 균등하게 분배하세요.
API 키 사용 — 인증된 요청은 보통 익명 요청보다 더 높은 레이트 리미트를 받습니다.
서킷 브레이커 구현 — 반복적으로 429를 받으면, 냉각 기간 동안 요청 전송을 완전히 중단하세요.
레이트 리미트 시뮬레이터로 테스트 — 개발 환경에서 429 응답을 시뮬레이션하여 오류 처리가 제대로 작동하는지 확인하세요.
429 응답 로깅 — 레이트 리미팅이 언제, 어디서 발생하는지 기록하여 요청 패턴을 최적화하세요.
서버 속도 제한 헤더 확인
DNS Robot의 무료 HTTP 헤더 도구를 사용하여 Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining 등 서버의 응답 헤더를 확인하세요.
Try HTTP Headers CheckerFrequently Asked Questions
HTTP error 429는 "Too Many Requests(요청이 너무 많음)"를 의미합니다. 짧은 시간 내에 너무 많은 요청을 보내서 서버가 레이트 리미팅을 적용하고 있다는 뜻입니다. 일시적인 차단이므로 몇 분 기다린 후 다시 시도하면 됩니다.