Mengapa GSI men-throttle penulisan base table di DynamoDB
Anda menulis ke tabel Anda. Penulisan gagal dengan throughput exception — tapi exception itu menyebut sebuah Global Secondary Index, bukan tabelnya. Tabel punya kapasitas tersisa.
Datang dari SQL, itu omong kosong: indeks sekunder tidak bisa memblokir sebuah
INSERT. Di DynamoDB ia bisa, dan mekanismenya disebut GSI back-pressure.
Mengapa GSI DynamoDB men-throttle penulisan base table?
DynamoDB men-throttle penulisan base table karena setiap penulisan juga direplikasi ke setiap GSI, dan jika sebuah partition GSI tidak bisa menyerap porsinya, DynamoDB menerapkan back-pressure untuk mencegah indeks tertinggal permanen. Jadi GSI key yang under-provisioned atau berkardinalitas rendah menjadi batas keras pada laju tulis base table Anda.
- Penulisan ke base table juga menulis ke setiap GSI. Jika sebuah GSI tidak bisa menyerap porsinya, DynamoDB men-throttle penulisan base table untuk mencegah indeks tertinggal permanen. (AWS docs)
- Base table yang merata tidak menyelamatkan Anda. GSI dipartisi berdasarkan
key-nya sendiri. Sebuah GSI key berkardinalitas rendah (seperti
status) menciptakan hot index partition bahkan saat penulisan base table tersebar sempurna. - Exception berbohong soal korbannya.
ResourceArnmenunjuk ke GSI; operasi yang sebenarnya ter-throttle adalah penulisan Anda ke tabel. - Solusinya adalah kapasitas atau desain key, bukan loop retry — naikkan throughput GSI, atau pilih partition key GSI yang menyebar.
Bagaimana satu penulisan menyentuh indeks
Sebuah PutItem pada base table bukanlah satu penulisan. DynamoDB mereplikasi
atribut item yang diproyeksikan ke setiap GSI secara asinkron, pada model
eventually consistent. Satu penulisan logis menyebar ke N penulisan fisik —
tabel plus setiap indeks.
Replikasi itu tidak gratis dan tidak opsional. GSI harus mengikuti, atau indeks makin menyimpang dari tabel pada setiap operasi.
Untuk menghentikan penyimpangan itu, DynamoDB menerapkan back-pressure: ia men-throttle penulisan sumber agar indeks tidak pernah usang tanpa batas.
Jadi kapasitas tulis GSI adalah batas keras pada laju tulis base table Anda — walaupun Anda tidak pernah menulis ke GSI secara langsung.
Contoh nyata: tabel orders
Misalkan Anda menjalankan tabel orders. Item dasarnya:
| field | value | note |
|---|---|---|
| PK | "CUST#8841" | partition key |
| SK | "ORD#2026-06-23#A7" | sort key |
| order_state | "PROCESSING" | |
| warehouse | "EU-MAD-2" | |
| total_cents | 4990 |
Penulisan base table sehat. CUST#... berkardinalitas tinggi, jadi penulisan
order tersebar merata di seluruh base partition. Tidak ada hot key, kapasitas
melimpah.
Sekarang Anda menambah GSI untuk menjawab "tunjukkan setiap order pada status tertentu":
| field | value | note |
|---|---|---|
| GSI-PK | order_state | "PENDING" | "PROCESSING" | "SHIPPED" | "CANCELED" |
| GSI-SK | SK |
Empat kemungkinan nilai partition-key. Selama flash sale, hampir setiap order
baru mendarat di order_state = "PENDING". Setiap penulisan itu menghantam
partition GSI yang sama.
Partition itu punya batas throughput per-partition, dan Anda baru saja mengarahkan seluruh badai tulis Anda ke sana.
Base table baik-baik saja. Partition GSI PENDING terbakar. DynamoDB
men-throttle PutItem base table untuk melindungi indeks.
Alur yang menggigit Anda
Berikut jalur back-pressure — penulisan base seimbang, penulisan indeks terpusat:
Throttle merambat mundur: sebuah hot partition GSI menolak penulisan base table yang menyuapinya.
Baca exception-nya, bukan firasat Anda
Tipe exception memberi tahu persis batas mana yang Anda lampaui. ResourceArn
menyebut GSI; operasi yang ter-throttle tetap penulisan tabel.
| Mode | Reason code | Yang habis |
|---|---|---|
| Provisioned | IndexWriteProvisionedThroughputExceeded | Kapasitas tulis provisioned GSI |
| Provisioned | IndexWriteKeyRangeThroughputExceeded | Satu hot partition GSI |
| On-demand | IndexWriteMaxOnDemandThroughputExceeded | Batas maks on-demand GSI yang dikonfigurasi |
| On-demand | IndexWriteAccountLimitExceeded | Batas throughput akun/region |
Sumber: Understanding GSI write throttling and back pressure.
Reason KeyRange adalah penanda untuk kasus hot-partition di atas: kapasitas
GSI keseluruhan bisa tampak baik-baik saja sementara satu key range jenuh.
Cara memperbaikinya
Beri GSI ruang. Penyebab paling sederhana adalah under-provisioning. Sebuah GSI punya kapasitas baca dan tulisnya sendiri, sepenuhnya terpisah dari tabel — lihat GSI vs LSI.
Jika Anda menyediakan tabel dengan murah hati dan meninggalkan GSI tipis, naikkan kapasitas tulis GSI (atau maks on-demand-nya).
Perbaiki partition key. Kapasitas tidak akan menyelamatkan key berkardinalitas rendah — Anda tidak bisa meng-out-provision satu hot partition. Pilih partition key GSI yang menyebar.
Susun: order_state#shard di mana shard adalah suffix acak kecil, atau lipat
tanggalnya (PENDING#2026-06-23). Penulisan tersebar di seluruh partition dan
Anda tetap me-Query sebuah status dengan meng-query shard-nya.
Proyeksikan lebih sedikit atribut. Setiap penulisan GSI menyalin atribut
yang diproyeksikan. Proyeksi KEYS_ONLY atau INCLUDE yang ketat berarti
penulisan indeks lebih kecil dan tekanan lebih sedikit daripada ALL. Jangan
proyeksikan apa yang tak akan pernah Anda baca dari indeks.
Buang GSI jika hanya untuk pelaporan. Jika "orders by state" adalah pertanyaan admin sesekali, bukan jalur panas, sebuah scan periodik dengan filter mungkin mengalahkan indeks yang panas permanen — timbang terhadap Query vs Scan.
Saat Anda me-query indeks itu, Expression
Builder menulis KeyConditionExpression
untuk Anda — misal #s = :state AND begins_with(SK, :prefix) — dengan nama dan
nilai di-escape dengan benar:
KeyConditionExpression "#s = :state"
ExpressionAttributeNames { "#s": "order_state" }
ExpressionAttributeValues { ":state": { "S": "PENDING" } }
Jebakan yang perlu diingat
Naluri relasional — "indeks hanya sedikit memperlambat penulisan" — tidak berlaku. Sebuah GSI DynamoDB adalah dependensi throughput, bukan struktur pasif. Buat ia terlalu kecil atau pilih key yang menggumpal, dan ia akan mem-back-pressure tabel yang dilayaninya.
Pantau ConsumedWriteCapacityUnits dan ThrottledRequests GSI per partition,
bukan hanya milik tabel.
Langkah berikutnya
- GSI vs LSI — mengapa GSI punya kapasitasnya sendiri dan partition key yang berbeda.
- Single-table design — meng-overload satu GSI untuk melayani banyak pola tanpa melipatgandakan hot index.
- Query vs Scan — kapan sebuah indeks tidak sepadan dengan biaya tulisnya.
Coba DynoTable untuk mengamati kapasitas konsumsi GSI dan event throttle terhadap tabel Anda sendiri sebelum sebuah sale membuatnya merah.