Throttling DynamoDB — Kenapa Terjadi dan Cara Memperbaikinya
Throttling adalah cara DynamoDB memberi tahu Anda bahwa sebuah batas tersentuh — tapi ada empat batas berbeda, tiga exception berbeda, dan perbaikan untuk satu penyebab justru memperburuk penyebab lainnya. Menaikkan kapasitas tabel tidak berguna untuk hot key; beralih ke on-demand juga tidak berguna untuk hot key dan tetap bisa mem-throttle berdasarkan aturannya sendiri. Panduan ini adalah payungnya: batas mana yang sebenarnya Anda sentuh, bagaimana metriknya membedakan, dan perbaikan yang cocok untuk tiap penyebab.
Kenapa DynamoDB mem-throttle permintaan saya?
Salah satu dari empat alasan yang terdokumentasi: satu partisi melampaui batas per-partisinya yang tetap, yaitu 3.000 read unit atau 1.000 write unit per detik (sebuah hot key — terjadi di kedua mode kapasitas); tabel melampaui RCU/WCU provisioned-nya (mode provisioned); akun melampaui kuota throughput di tingkat region; atau sebuah tabel on-demand tumbuh lebih cepat daripada dua kali lipat puncaknya sebelumnya dalam 30 menit. Perbaikannya bergantung pada yang mana, jadi diagnosis dulu sebelum Anda mengubah ukuran apa pun.
Empat skenario throttling
Halaman troubleshooting AWS sendiri membagi throttling menjadi tepat empat kasus:
- Throughput key-range (partisi) terlampaui — kedua mode. Setiap partisi dirancang untuk maksimum 3.000 read unit dan 1.000 write unit per detik (dokumentasi partition key), dan ukuran item ikut diperhitungkan. Tidak ada setelan di tingkat tabel yang menaikkannya; hanya desain key yang menyebarkannya. Ini adalah kasus hot partition, dan tabelnya bisa tampak sangat kurang terpakai sementara ia di-throttle.
- Provisioned throughput terlampaui — mode provisioned. Konsumsi mengalahkan RCU/WCU provisioned tabel (atau sebuah GSI), dan bantalan burst capacity ~5 menit sudah habis. Tangga perbaikannya ada di sisi kapasitas: auto scaling, provision yang lebih tinggi, atau ganti mode.
- Kuota di tingkat akun terlampaui. Kuota akun per region membatasi total throughput — secara default 40.000 read unit dan 40.000 write unit per tabel, dan untuk mode provisioned 80.000 RCU dan 80.000 WCU per akun (kuota); ini adalah default awal, bisa disesuaikan lewat Service Quotas, dan tabel on-demand tidak punya kuota throughput di tingkat akun.
- Throughput maksimum on-demand terlampaui. On-demand seketika mengakomodasi hingga dua kali lipat puncak sebelumnya; tumbuh melewati dua kali lipat dalam 30 menit dan ia bisa mem-throttle (dokumentasi on-demand). Tabel on-demand baru sanggup menahan 4.000 penulisan/detik dan 12.000 pembacaan/detik sejak awal. Untuk lonjakan bertahap yang terencana (peluncuran, sale, migrasi), pre-warm tabelnya dengan warm throughput alih-alih berharap kenaikannya landai.
Tiga exception, dan field yang menyebut penyebabnya
ProvisionedThroughputExceededException— throttling kapasitas mode provisioned: "you exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes". Detailnya ada di halaman error khususnya.ThrottlingException— operasi control-plane yang dikeluarkan terlalu cepat, dan, pada tabel on-demand, operasi data-plane apa pun yang lajunya terlalu tinggi (itulah exception di balik aturan dua-kali-puncak — lihat halaman error on-demand dan ThrottlingException).RequestLimitExceeded— batas throughput di tingkat akun: wilayah "hubungi AWS Support", dibahas di halaman error-nya.
Ketiganya ditandai bisa di-retry, dan ketiganya kini membawa nilai
ThrottlingReason terstruktur berbentuk resource + operasi + batas —
TableReadProvisionedThroughputExceeded,
IndexWriteKeyRangeThroughputExceeded, TableWriteAccountLimitExceeded, dan
seterusnya (referensi error).
Bacalah reason-nya, bukan cuma kelas exception-nya: ia menyebut resource-nya
(tabel atau index), arah operasinya, dan yang mana dari empat batas itu yang Anda
sentuh — dan itu persis diagnosisnya. Satu kehati-hatian yang dipaksakan
dokumentasinya sendiri: halaman-halaman AWS berbeda pendapat soal apakah
throttling batas akun muncul sebagai RequestLimitExceeded atau sebagai
ThrottlingException dengan reason AccountLimitExceeded, jadi sandarkan
penanganan Anda pada string reason-nya.
Apa yang menyerap beban sebelum Anda di-throttle
Dua mekanisme bawaan melunakkan batas, dan mengetahui tepinya menjelaskan "kemarin masih jalan kok":
- Burst capacity menyimpan hingga lima menit (300 detik) kapasitas baca dan tulis yang tak terpakai untuk lonjakan — tapi DynamoDB juga bisa memakainya untuk pemeliharaan latar belakang "without prior notice", dan AWS secara eksplisit mencatat bahwa detailnya bisa berubah. Jangan mendesain bergantung pada burst; perlakukan sebagai keberuntungan.
- Adaptive capacity secara otomatis dan seketika menggeser throughput ke arah partisi yang panas dan bisa mengisolasi sebuah item yang sering diakses ke partisinya sendiri — tapi hanya "provided that traffic does not exceed your table's total provisioned capacity or the partition maximum capacity". Ia menyeimbangkan ulang kemiringan; ia tidak pernah mengangkat plafon per-partisi 3.000/1.000, dan ia tidak akan memecah koleksi item ketika tabelnya punya LSI. Halaman troubleshooting AWS saat ini bersandar pada split-for-heat — partisi yang memecah diri di bawah panas berkelanjutan — yang butuh waktu dan tidak membantu satu hot key.
Diagnosis dari metriknya
CloudWatch memisahkan request dari event, dan pembedaan itulah yang mengerjakan diagnosisnya (referensi metrik):
ThrottledRequestsmenghitung sebuah request satu kali kalau ada event di dalamnya yang di-throttle — sebuahPutItempada tabel dengan tiga GSI adalah satu request tapi empat write event. Di dalam sebuah batch, ia hanya bertambah kalau setiap item di-throttle.ReadThrottleEvents/WriteThrottleEventsmenghitung setiap event yang di-throttle — sebuahBatchGetItemuntuk 10 item adalah 10 eventGetItem. Untuk melihat throttle tulis sebuah GSI, Anda harus meng-query metriknya denganTableNamesekaligusGlobalSecondaryIndexName— beginilah GSI back-pressure bersembunyi dari dashboard di tingkat tabel.- Metrik event spesifik-reason yang lebih baru
(
WriteProvisionedThroughputThrottleEvents,ReadKeyRangeThroughputThrottleEvents,…AccountLimitThrottleEvents,…MaxOnDemandThroughputThrottleEvents) memecah hitungannya berdasarkan empat penyebab yang sama — kalau region Anda menampilkannya, mereka menjawab pertanyaan "batas yang mana" secara langsung.
Satu jebakan: SDK me-retry permintaan yang di-throttle secara otomatis — mode retry standar melakukan 3 percobaan total secara default (peluncuran retry opt-in 2026 memindahkan klien DynamoDB ke 4 percobaan dengan jeda yang lebih rapat). Karena itu throttling ringan muncul sebagai latensi, bukan sebagai error; awasi metrik throttle-nya, bukan cuma log exception Anda.
GSI back-pressure: throttle yang menunjuk tabel yang salah
Kalau ada GSI yang tidak sanggup menyerap amplifikasi tulis, "DynamoDB throttles
writes to the base table to maintain data consistency"
(dokumentasi throttling GSI)
— bahkan ketika tabel dasarnya masih punya kapasitas berlebih. ResourceArn
exception-nya menunjuk ke index, tapi operasi yang gagal adalah penulisan tabel
dasar Anda. Setiap index butuh rencana kapasitasnya sendiri (dan
policy auto scaling-nya sendiri);
kenapa GSI mem-throttle tulisan tabel dasar
membahas mekanismenya.
Cocokkan perbaikan dengan penyebabnya
| Penyebab | Yang memperbaikinya | Yang tidak |
|---|---|---|
| Hot key / partisi | Desain key yang menyebarkan beban (hot partition); waktu untuk split-for-heat | Menaikkan kapasitas tabel, beralih ke on-demand |
| Kapasitas provisioned | Auto scaling, minimum yang lebih tinggi, atau on-demand | Retry saja — malah menambah beban |
| GSI back-pressure | Skalakan index-nya; ubah sparse index atau projection | Menskalakan tabel dasarnya |
| Kuota akun | Kenaikan lewat Service Quotas | Setelan di tingkat tabel |
| Lonjakan bertahap on-demand | Pre-warm (warm throughput); sebarkan kenaikannya selama 30+ menit | Menunggu — dua-kali-puncak turun perlahan |
Lakukan di DynoTable
Sebagian besar throttling akibat ulah sendiri berawal dari pembacaan yang
biayanya lebih besar daripada tampaknya: sebuah Scan yang difilter tetap
mengonsumsi pembacaan penuh. Pratinjau biaya pra-eksekusi DynoTable menunjukkan
apakah sebuah statement menjadi Query atau Scan, index yang dikenainya, dan
perkiraan biaya baca sebelum Anda membelanjakannya — perbaikan throttling
termurah adalah pembacaan mahal yang tidak Anda jalankan. Panduan
Scan vs Query membahas perbedaannya;
kalkulator ukuran item gratis mengubah
sebuah item nyata menjadi angka RCU/WCU yang dipakai untuk mengukur batas-batas
di atas.
Jebakan dan langkah berikutnya
- Retry memperbesar kelebihan beban. Backoff sudah dibangun ke dalam SDK, tapi loop retry ketat di tingkat aplikasi di atas retry SDK melipatgandakan tekanan tepat pada partisi yang sedang kepayahan.
- Batch menyembunyikan throttling parsial. Sebuah
BatchWriteItemmengembalikan item yang tak terproses alih-alih melempar exception selama ada item yang berhasil — periksaUnprocessedItems, bukan cuma exception. - Tampilan di tingkat tabel berbohong soal GSI. Selalu grafikkan throttle event per index; dashboard tabel dasar terlihat bersih selama back-pressure.
- Perbaikan kapasitas makan menit; desain key itu selamanya. Auto scaling bereaksi dalam ~5 menit, kenaikan kuota butuh tiket dukungan, tapi sebuah hot key mengikuti Anda ke setiap mode kapasitas — curahkan usaha di tempat yang berbunga: cara kerja partition key.
Unduh DynoTable untuk melihat rencana Scan-lawan-Query dan biaya baca setiap query sebelum ia berjalan terhadap kapasitas Anda.