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 want | Use | Cost | Freshness |
|---|---|---|---|
| Ballpark count + size, free | DescribeTable |
none (metadata call) | ~6 h stale |
| Exact total count |
Scan with Select COUNT
|
reads the whole table | live |
| Exact count for one key |
Query with Select COUNT
|
reads the matching items | live |
| Count of a filtered subset |
Scan/Query + filter + COUNT |
reads everything scanned | live |
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 sparse index's item count against the table's is a
nice free health check — it tells you how many items actually carry the index
key.
Tip
TableSizeBytes ÷ ItemCountgives you the average item size — the number
that drives your read/write cost per request. To size a specific item the
way DynamoDB meters it, use the
item size calculator.
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 followsLastEvaluatedKeyand 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.
Warning
An exact count is a full-table
Scanin disguise — the classic cost trap
covered in why Scan is slow and expensive.
Don't put one on a dashboard refresh. If you need a live count continuously,
maintain a counter item with atomic counters
instead of re-counting.
Counting a subset
-
Items under one partition key:
Querywith--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 item collection. -
Items matching a filter: add a
FilterExpression— but remember the count you're billed for isScannedCount, notCount: DynamoDB filters after reading, so "count the archived orders" via a filtered scan pays for every order. A highScannedCountnext to a smallCountis 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. (Or skip the
workaround: DynoTable's SQL Workbench runs
GROUP BY and aggregates client-side.)
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
DescribeTableestimates, labeled as estimates, with the six-hour caveat one hover away. -
Index table — a one-click sampling scan that records the attributes it
finds (including nested paths like
commonData.status), with live progress. The scan is capped, so rare attributes can be missing; the limits are on Table stats. 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.
And for the exact numbers, the built-in AI agent
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?
ItemCount (and TableSizeBytes) refresh "approximately every six hours", so
recent writes and deletes are not 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.

Top comments (0)