DynamoDB 項目大小上限(400 KB)
單一 DynamoDB 項目最多只能容納 400 KB 的資料。若你來自 MongoDB
(16 MB 文件)或幾乎沒有實際上限的關聯式資料列,這個天花板會讓人覺得偏低 —
而且你通常是以慘痛的方式發現它:一個運作了好幾個月的寫入突然
以 ValidationException 失敗,因為某個項目終於長得太大了。
這個限制不是隨意訂的,也不是你可以調高的配額。它是一項建模 上的約束,而會撞到它的項目通常是在告訴你:資料的模型設計錯了。
DynamoDB 的項目大小上限是多少?
DynamoDB 將單一項目限制在 400 KB — 這是無法調高的硬性上限。大小同時計算屬性名稱與值,包含每一個巢狀的 list、map 與 set 元素。項目通常是因為無界成長而撞到上限,例如一個不斷擴張的內嵌 list;解法是建模,把集合拆成獨立的項目,而不是壓縮。
- 每個項目 400 KB,硬性上限。 不可調整,也不是軟性配額。
- 大小 = 屬性名稱 + 值,兩者相加。 冗長的屬性名稱在每一個項目上都會被計入。
- 巢狀結構與 set 同樣會計入。 list、map 以及它們內部的巢狀值全都會累加。
- 常見原因是無界成長 — 在父項目上內嵌一個不斷成長、沒有上限的 list。
- 解法是建模,不是壓縮。 把持續成長的集合拆成自己的項目,置於共用的分割區索引鍵之下。
問題所在:永遠長大的那個項目
假設你要追蹤一支車隊,並決定把每輛車的遙測讀數存成車輛項目上的 一個 list:
PK: VEHICLE#A1 readings: [ {ts, lat, lng, fuel}, {ts, lat, lng, fuel}, ... ]前一兩天都沒問題。但讀數每幾秒就進來一次而且不會停,所以
這個 list 會無界成長。最終,再多一筆讀數就會把項目推過 400 KB,
DynamoDB 會以
ValidationException: Item size has exceeded the maximum allowed size 拒絕該次寫入 — 你再也無法為那輛車
記錄任何遙測資料,因為每次更新都會重寫整個項目。
問題不在大小限制,而在於把一個無界的一對多關聯建模成 內嵌 list。那只有在「多」的那一側有界且數量不多時才行得通。
什麼真正會算進 400 KB
DynamoDB 以下列各項的總和來計算項目的總大小:
- 每一個屬性名稱,以 UTF-8 編碼。一個 20 個字元的名稱重複出現在 數百萬個項目上,既是大小、也是你要付費的儲存空間 — 這正是為什麼 資深的建模者會把屬性名稱取短。
- 每一個屬性值。 字串與二進位按其位元組長度計算;數字按一種 精簡編碼計算;布林值與 null 只有極小的固定成本。
- 巢狀結構。 一個 list 或 map 除了自身的額外負擔,還要加上 其中每一個元素與鍵的大小,一路往下算到底。
並沒有另外的單一屬性上限需要規劃 — 是整個項目去對 400 KB 這條線。AWS 項目大小文件 詳細說明了確切的位元組計算方式。
這個限制為何存在
大型項目搬動起來很昂貴。DynamoDB 的讀取以 4 KB 為單位計量,所以一個 400 KB 的項目做強一致讀取要花 100 RCU — 而且隨著項目變大,讀取、寫入與複寫 全都會變慢、變貴。這個上限 促使你走向 小而精準的項目,遠離 NoSQL 新手出於關聯式習慣而想採用的 「抓一整坨巨大 blob」反模式。
用建模來繞開它
以車隊為例,別再內嵌了。讓每一筆讀數在與車輛相同的分割區中 擁有自己的項目,並以排序索引鍵上的時間戳排序:
PK: VEHICLE#A1 SK: READING#2026-06-27T10:00:05Z lat, lng, fuel
PK: VEHICLE#A1 SK: READING#2026-06-27T10:00:10Z lat, lng, fuel現在沒有任何單一項目會變大,寫入永遠不會超出上限,而對
VEHICLE#A1 的單次 Query 仍能把一輛車的讀數以一個排序好的
項目集合取回。有界的子清單(少數幾個
標籤、一個固定的設定區塊)內嵌沒有問題;無界的則應該變成項目。
在 DynoTable 中檢查項目大小
在你敲定一種結構之前,先秤秤一個具代表性的項目。在 DynoTable 中用 Quick View 打開一個項目,它會在屬性旁顯示該項目的位元組大小 — 讓你在瀏覽 真實資料時就抓到過重的結構,在設計階段而不是在寫入失敗時才發現。
想留在瀏覽器裡?DynamoDB 項目大小計算機 從你貼上的樣本做同樣的事,回報確切的 KB 數以及每次讀取與寫入將花費的 RCU/WCU。

已對 DynamoDB 驗證
大小計算規則說起來容易,卻很容易在細微處出錯,所以我們拿唯一算數的權威來對照:DynamoDB 實際上怎麼計費。
訣竅在於 ConsumedCapacity 回報的是單位而非位元組,而 N 個位元組的寫入要花 ceil(N / 1024) WCU。一般而言粗糙 — 但在邊界上精確。一個刻意做成剛好 1024 位元組的項目必定花 1 WCU,做成 1025 的必定花 2,所以算式裡差一個位元組就會翻轉觀察到的數字。
| 項目 | 我們算出的位元組 | 預測 WCU | 實際 WCU |
|---|---|---|---|
| 剛好 1 KB | 1,024 | 1 | 1 |
| 1 KB + 1 位元組 | 1,025 | 2 | 2 |
| 剛好 2 KB | 2,048 | 2 | 2 |
| 2 KB + 1 位元組 | 2,049 | 3 | 3 |
| 剛好 4 KB | 4,096 | 4 | 4 |
| 混合型別 | 32 | 1 | 1 |
六項全數吻合,而其中承載證據的正是那些邊界配對:1,024 與 1,025 位元組的項目只差一個字元的填充,DynamoDB 卻對它們收取不同費用,恰好落在我們的計算所說的階梯處。
實務上的後果就是那個會花錢的。一個超過一 KB 一個位元組的項目要多花整整一個 WCU,而在 4 KB 處讀取側也出現同樣的懸崖 — 所以把項目從 1,025 位元組修到 1,024 就能讓寫入成本減半,而把它從 1,024 撐到 1,025 則會加倍。屬性名稱會計入總量,這就是為什麼在熱門資料表上縮短鍵名並不是微優化。
陷阱與後續步驟
- 留意會隨流量成長的內嵌 list — 它們是經典的 400 KB 定時炸彈。替它們設上限,或把它們拆出去。
- 縮短高基數項目上的屬性名稱 — 那是免費拿回來的大小與儲存空間。
- 大型值屬於 S3。 把大型 blob(圖片、文件)放在 S3,項目上只保留 它的 key。
- 相關內容:反正規化與 一對多關聯說明何時該 內嵌、何時該拆分。
想一眼看遍整張資料表中真實的項目大小嗎? 下載 DynoTable 直接檢視你的資料。
容量數據已於 2026-07-26 在 us-east-1 對照線上 DynamoDB 服務驗證(pnpm content:verify-item-size)。


