DynamoDB ProvisionedThroughputExceededException
요약 — 테이블이나 인덱스가 처리할 수 있는 것보다 빠르게 읽거나 쓰고 있습니다. 테이블을 온디맨드 용량으로 전환하고, 프로비저닝된 RCU/WCU를 올리거나 오토 스케일링을 켜고, SDK의 기본 지수 백오프 재시도를 유지하고, 하나의 파티션 키가 뜨거워지지 않도록 트래픽을 분산하세요.
무엇을 의미하는가
ProvisionedThroughputExceededException: You exceeded your maximum allowed
provisioned throughput for a table or for one or more global secondary indexes.프로비저닝된 용량 테이블에서 읽기/쓰기 용량 단위를 초과했습니다 — 전체적으로 초과했거나, 더 흔하게는 단일 파티션에서 초과한 것입니다. HTTP 400이지만 ValidationException과 달리 재시도할 수 있습니다. AWS SDK가 지수 백오프로 자동 재시도하므로 가끔 발생하는 것은 정상입니다. 지속적으로 발생한다면 실제로 용량이 부족하거나 핫 키가 있다는 뜻입니다. 이 오류에는 ThrottlingReason 필드(예: TableReadProvisionedThroughputExceeded)와 영향받은 리소스의 ARN이 함께 담기므로, 어떤 테이블이나 인덱스가 어떤 작업 유형에서 스로틀링되었는지 알 수 있습니다.
왜 발생하는가
- 실제 트래픽에 비해 용량이 부족함.
- 핫 파티션 — 트래픽이 하나의 파티션 키에 몰려서, 테이블 전체로는 여유로워 보이는데도 단일 파티션 몫의 용량이 소진되는 경우.
- 오토 스케일링이 따라잡지 못하는 급증 트래픽 — 오토 스케일링은 소비된 용량 지표에 반응해 용량을 조정하므로, 갑작스러운 계단식 변화는 확장이 반영되기 전에 스로틀링을 일으킵니다.
- 한꺼번에 모든 용량을 소비하는 대규모 Scan이나 벌크 임포트.
- 쓰기 속도보다 용량이 낮은 GSI — 스로틀링된 GSI는 기본 테이블도 스로틀링시킵니다.
어떻게 해결하는가
- 트래픽이 예측하기 어렵다면 온디맨드 용량으로 전환하세요 — 자동으로 확장되어 이 오류가 사실상 사라집니다(대신 요청당 과금됩니다).
- 프로비저닝 모드를 유지한다면 프로비저닝된 RCU/WCU를 올리거나, 합리적인 목표 사용률로 오토 스케일링을 켜세요.
- 지수 백오프 재시도를 유지하세요 — SDK가 기본으로 해주니 끄지 마세요. 버스트가 심한 워크로드에는 적응형 재시도 모드를 사용하세요.
- 핫 파티션을 해결하세요 — 키의 카디널리티를 높이거나 핫 키를 쓰기 샤딩해서 부하가 여러 파티션에 퍼지게 하세요.
- 벌크 작업의 속도를 제한하고, 자주 읽는 데이터를 캐싱(DAX 또는 앱 캐시)해 읽기 압력을 줄이세요.
FAQ
ProvisionedThroughputExceededException은 어떻게 해결하나요? 테이블이나 인덱스가 처리할 수 있는 것보다 빠르게 읽거나 쓰고 있는 것입니다. 테이블을 온디맨드 용량으로 전환하고, 프로비저닝된 RCU/WCU를 올리거나 오토 스케일링을 켜고, SDK의 기본 지수 백오프 재시도를 유지하고, 하나의 파티션 키가 뜨거워지지 않도록 트래픽을 분산하세요.
재현하기
테이블을 1 RCU로 프로비저닝하고, 4 KB에 살짝 못 미치는 항목 하나를 넣은 뒤, 강력한 일관성 읽기를 빡빡한 루프로 반복하세요:
import boto3
ddb = boto3.client('dynamodb', region_name='us-east-1')
# table created with ProvisionedThroughput={'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1}
ddb.put_item(TableName='my-table', Item={'pk': {'S': 'A'}, 'blob': {'S': 'x' * 3500}})
while True:
ddb.get_item(TableName='my-table', Key={'pk': {'S': 'A'}}, ConsistentRead=True)실제 출력:
ProvisionedThroughputExceededException: The level of configured provisioned throughput for the table was exceeded. Consider increasing your provisioning level with the UpdateTable API.
HTTP 400SDK 재시도를 끈 채 갓 만든 테이블에서 오류가 나기까지 49번의 읽기가 걸렸습니다. 그 숫자가 흥미로운 지점입니다. 1 RCU 테이블은 두 번째 요청에서 실패하지 않습니다. DynamoDB가 먼저 누적된 버스트 용량을 빌려주기 때문이죠 — 그래서 일찍 끝나는 부하 테스트는 건강하지 않은 테이블을 건강하다고 보고합니다. 착시의 나머지 절반은 SDK입니다. 스로틀링된 요청을 기본으로 대신 재시도하니까요. 위처럼 재시도를 끄지 않으면 이 오류는 지연 문제로 번질 때까지 보이지 않습니다.
관련 오류
- ThrottlingException — 계정/컨트롤 플레인 속도 제한.
- 여유 용량이 있는데도 스로틀링(핫 파티션) — 하나의 파티션 키가 트래픽을 빨아들이는 경우.
- 온디맨드 처리량 초과 — 온디맨드 모드의 대응 오류.
- ItemCollectionSizeLimitExceededException
- 코드 예제: Node.js의 BatchWriteItem — UnprocessedItems 백오프 재시도 패턴.
- 학습: 온디맨드 vs 프로비저닝 · 핫 파티션
참고 자료
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- Troubleshooting throttling in Amazon DynamoDB — Amazon DynamoDB Developer Guide
- Best practices for designing and using partition keys effectively in DynamoDB — Amazon DynamoDB Developer Guide
- Quotas in Amazon DynamoDB — Amazon DynamoDB Developer Guide
위에 링크된 공식 AWS 문서를 기준으로 2026-07-13에 마지막으로 검증했습니다.
2026-07-26에 SDK 재시도를 끈 채 1 RCU로 프로비저닝한 테이블에서 boto3 1.43.56을 통해 us-east-1의 실제 DynamoDB 서비스로 재현했습니다 — 위 출력은 그대로 옮긴 것입니다.