We loaded the same orders into Postgres 17 and DynamoDB and asked seven questions at 100,000, 1 million and 5 million orders. Lookups by key stayed under 2 ms in Postgres at every size and cost half a read unit in DynamoDB. Every question across customers needed a full Scan in DynamoDB (about 40,000 read units per million orders), and took 0.02 to 1.6 seconds in Postgres. The numbers, and what they mean for choosing.
An orders table: order ID, customer (50,000 of them), timestamp over two years, status, region, total, and one to five line items. Average DynamoDB item 327 bytes.
Postgres 17 in Docker on an Apple M4 laptop, default settings, a primary key and one index on (customer, created_at). Timings are medians of repeated runs over one local connection.
DynamoDB modelled the usual way: partition key per customer, sort key by date, and a secondary index by order ID. We measured what each operation consumes, not its speed: DynamoDB Local is an emulator, and AWS quotes single-digit millisecond latency for key lookups on the real service.
100,000 orders
1 million orders
5 million orders
Postgres 17, median time per query (log scale). At 5 million orders the table and indexes (4.2 GB) no longer stayed in memory, which is why times jump more than the row count.
Measured on 200,000 orders (8,030.5 read units for the scan, 63 pages of 1 MB) and scaled linearly; eventually consistent reads at $0.125 per million.
Questions you designed for are cheap and flat in both. Postgres stayed under 2 ms at 5 million orders; DynamoDB stays at half a read unit at any size, which is its real advantage at hundreds of millions of items.
Questions you didn't design for are where they part. Postgres answers them, slowly at first, and an index built in 2 seconds took the unplanned one from 1.2 s to 50 ms at 5 million orders. DynamoDB answers them with a Scan.
A Scan is cheap in dollars at this size (half a cent per million orders) and expensive in everything else: 315 sequential 1 MB pages per million items, throughput other requests also need, and code to aggregate in your application.
Filters don't make scans cheaper. The refund question read every item to return 0.3% of them, and paid for all of it.
Bring your access patterns and the reports someone will ask for next quarter. We'll tell you which fits, in 30 minutes, free.
Once a month: what changed in tech that month and what it means for you, from cloud and AI to security and the tools you build with. Every item links to its source. No sales pitch, unsubscribe in one click.
Book a free 30-minute call about it. Bring your setup and your bill; you'll leave knowing what we'd do first and roughly what it costs, whether or not you hire us.
Or keep reading
When Postgres Outperforms DynamoDB: Five Situations, With Measurements
DynamoDB is excellent at the questions you designed it for. Postgres wins when the questions change: ad-hoc reports, joins, aggregates, filters on any column, and access patterns discovered after launch. Our benchmark: an unplanned query at 5 million orders took 1.2 s in Postgres and 50 ms after a 2-second index build; in DynamoDB it was a full Scan or a new index backfilled across every item.
Read
DynamoDB vs Postgres, Measured in AWS: 53 Workloads From the Same Client
We ran 53 workloads against RDS Postgres 17 and DynamoDB from one Fargate task in the same Availability Zone, at 100,000, 1 million and 5 million orders. Key lookups took 0.35 ms in Postgres and 2.7 ms in DynamoDB; a two-item transaction 1.75 ms against 20 ms; a question nobody designed for, 0.08–2.7 s against a full table scan. The full results, with the method and every caveat.
Read
As of November 4, 2026. Provided as is, for general information, and accurate to the best of our knowledge on the date shown. Not legal, compliance, tax, financial or other professional advice. Prices, limits and vendor services change; check current vendor documentation before relying on anything here. Terms of use.