Beginner5 min read

How to Get a DynamoDB Table's Size and Item Count

There's no SELECT COUNT(*) you can cheaply point at a DynamoDB table. DynamoDB gives you two very different answers to "how big is this table?": a free estimate that can be up to six hours stale, and an exact count that costs a full read of the table. Most "why is my item count wrong?" confusion is picking one while expecting the other's behavior.

How do I get the item count and size of a DynamoDB table?

Call DescribeTable: it returns ItemCount and TableSizeBytes for free, but "DynamoDB updates this value approximately every six hours. Recent changes might not be reflected in this value" (AWS API reference). For an exact number, run a Scan with --select COUNT — it returns only the count, but reads (and bills) every item. A GUI like DynoTable shows the estimates on every table and can compute exact counts on demand.

You wantUseCostFreshness
Ballpark count + size, freeDescribeTablenone (metadata call)~6 h stale
Exact total countScan with Select COUNTreads the whole tablelive
Exact count for one keyQuery with Select COUNTreads the matching itemslive
Count of a filtered subsetScan/Query + filter + COUNTreads everything scannedlive

Method 1: DescribeTable (free, ~6 h stale)

DescribeTable is a metadata lookup — it reads no items, so it consumes no read capacity, and it carries the two numbers you're after:

aws dynamodb describe-table --table-name Orders \
  --query 'Table.[ItemCount, TableSizeBytes]'

Both come with the same caveat, verbatim from the API reference: "DynamoDB updates this value approximately every six hours. Recent changes might not be reflected in this value." So a table you just bulk-loaded can report ItemCount: 0 for hours — the number isn't wrong, it's a snapshot.

The same response also carries per-index figures: every GSI and LSI reports its own ItemCount and IndexSizeBytes on the same six-hour cadence. Comparing a 's item count against the table's is a nice free health check — it tells you how many items actually carry the index key.

Method 2: exact count with Scan + Select COUNT

When "approximately, as of this morning" isn't good enough, count for real:

aws dynamodb scan --table-name Orders --select COUNT

Facts to know before you run it, all from the Scan API reference:

  • COUNT "returns the number of matching items, rather than the matching items themselves" — less network traffic, but "this uses the same quantity of read capacity units as getting the items". An exact count of a 100 GB table is a 100 GB read on your bill.
  • A single request still stops at 1 MB of data scanned; the response's Count "only return[s] the count of items specific to a single scan request". The CLI follows LastEvaluatedKey and sums the pages for you; in SDK code you loop and add — see pagination.
  • On a big table, split the work with a parallel scan (--segment / --total-segments) and sum the per-segment counts.

Counting a subset

  • Items under one partition key: Query with --select COUNT — reads only that key's items, so it's as cheap as the data is small. This is the right way to count an .
  • Items matching a filter: add a FilterExpression — but remember the count you're billed for is ScannedCount, not Count: DynamoDB filters after reading, so "count the archived orders" via a filtered scan pays for every order. A high ScannedCount next to a small Count is the signature of a filter that wants to be a GSI — see filtering strategies.

For richer questions — counts per status, sums, averages — DynamoDB has no GROUP BY at all; the workarounds live in count, sum & aggregate.

Table size and item count in DynoTable

DynoTable puts both answers where you're already looking. Every open table has a Stats button (the bar-chart icon) in the tab toolbar; the panel shows:

  • Primary key and secondary indexes — the table's shape at a glance.
  • Items · Size · Avg item — DynamoDB's own DescribeTable estimates, labeled as estimates, with the six-hour caveat one hover away.
  • Index table — a one-click sampling scan that discovers every attribute your items actually carry (including nested paths like commonData.status), with live progress. It powers field autocomplete and an inferred TypeScript / Zod / JSON Schema export, and it incurs normal DynamoDB read costs — the app says so up front.
The Table stats panel in DynoTable: keys and indexes, the Items / Size / Avg item estimate row, and the indexed-field list.
The Table stats panel in DynoTable: keys and indexes, the Items / Size / Avg item estimate row, and the indexed-field list.

And for the exact numbers, the built-in AI assistant computes counts, sums, and per-group breakdowns over the entire table on request — it reads every matching item rather than sampling a page, and it asks before running anything that costs read capacity.

FAQ

Why is my DynamoDB item count wrong? It's not wrong — it's stale. ItemCount (and TableSizeBytes) refresh "approximately every six hours", so recent writes and deletes aren't reflected yet. The console's table overview shows the same DescribeTable numbers, with the same lag.

How do I count rows in DynamoDB exactly? aws dynamodb scan --table-name X --select COUNT — the CLI pages through the whole table and sums the per-page counts. It's exact but bills the same read capacity as fetching every item.

Is DescribeTable free? It doesn't consume read capacity — it's a metadata call, not a data read, so polling it won't touch your table's throughput.

How do I find the size of one item? DynamoDB meters by item size (rounded up per 1 KB written / 4 KB read). Paste an item into the item size calculator to see its billed size, and see the 400 KB item limit for the ceiling.

Does item count affect my bill? Storage is billed by TableSizeBytes, and requests by item size × request count — not by item count directly. Put your table's numbers into the pricing calculator to see the monthly picture across on-demand and provisioned modes.

Want the table's shape, estimates, and indexed fields one click away? Download DynoTable and open the Stats panel on any table.

Updated