Amazon Athena query cost: pay for less data scanned
Athena charges $5 for every terabyte a SQL query scans, with a 10 MB minimum a query, so its bill is set by how your files are laid out, not by how clever the SQL is. Parquet, compression, partitions and a scan limit cut the same query from $180 to about 12 cents. The rules, a worked example and the settings.
Tecyfy · Published · 7 min read

Amazon Athena charges $5 for every terabyte a SQL query scans in US East (N. Virginia), counted per query, rounded up to the next megabyte, with a 10 MB minimum. So the bill is set by how many bytes each query has to read, and that depends far more on how the files in S3 are laid out than on how the SQL is written.
That is good news: a few changes to the data, made once, make every later query cheaper.
What Athena charges for, and what it does not
| Charged? | |
|---|---|
| A SQL query | Bytes scanned, rounded up to the MB, 10 MB minimum |
| A failed query | No |
CREATE, ALTER, DROP TABLE, adding partitions | No |
| A cancelled query | Yes, for what it scanned before it stopped |
| Storing the data and the results in S3 | Yes, at S3's own rates |
| The Glue Data Catalog | Yes, at Glue's rates |
Bytes are counted before decompression, so compressed files cost less to query than the same data uncompressed. The 10 MB minimum matters only for very small queries: a million queries that each touch a few kilobytes still bill 10 TB, $50.
The worked example: one year of clickstream
A year of web events lands in S3 as JSON, 36 TB of it, with 30 columns. An analyst's usual query counts sessions by page for the last 7 days, reading 3 columns.
| Layout | Data scanned | Cost per query |
|---|---|---|
| JSON as it arrives | 36 TB | $180 |
| JSON, gzip (about 3 times smaller) | 12 TB | $60 |
| Parquet, compressed, reading 3 of 30 columns | 1.2 TB | $6 |
| Parquet, partitioned by day, filtering the last 7 days | 23 GB | $0.12 |
The same question costs 1,500 times less. At 200 queries a day, that is the difference between about $1 million and about $690 a month. The steps are the ones Athena's own pricing example walks through: compression cuts the bytes, a columnar format reads only the columns asked for, and partitions skip the days nobody asked about. Your own compression will differ; 3 times is the figure in Athena's example for gzip text.
Each query scans 23 GB and costs $0.1151, $690 a month at 200 a day. The same query on raw JSON scans 36 TB for $180.
US East list price: $5 per TB scanned, rounded up to the MB, 10 MB minimum a query. Compression is taken as 3 times, the figure in Athena's pricing example; yours will differ. Text files are read whole, so reading fewer columns only helps with Parquet. S3 storage and requests are billed separately.
Convert to Parquet with one query
Athena can rewrite a table itself. A CREATE TABLE AS SELECT (CTAS) writes the results as compressed Parquet, partitioned by a column:
CREATE TABLE clicks_parquet
WITH (
format = 'PARQUET',
write_compression = 'ZSTD',
external_location = 's3://my-bucket/clicks-parquet/',
partitioned_by = ARRAY['dt']
) AS
SELECT session_id, page, user_agent, event_time, dt
FROM clicks_json
WHERE dt >= '2026-10-01';
The partition column goes last in the SELECT. This query is billed like any other, for the JSON it reads once; every query after it reads Parquet. For a large table, convert a range of days per query, or let the job that writes the data write Parquet in the first place, with AWS Glue or Spark.
Keep files large. Many small files slow Athena down, and for small files the overhead of a columnar format outweighs its benefit. Parquet's row groups default to 128 MB, which is a sensible size to aim for per file.
Partition for the query people run most
Partition by the column most queries filter on, nearly always a date. Partition for the common query, not the rare one: if queries look at days, do not partition by hour, because hourly partitions make 24 times as many small files.
Then always filter on it. WHERE dt >= '2026-10-15' reads 7 partitions. WHERE event_time >= timestamp '2026-10-15 00:00' reads them all, because event_time is an ordinary column, unless the table is also partitioned on it.
Partition projection: no partitions to manage
MSCK REPAIR TABLE is slow and only adds partitions. With partition projection, Athena works out the partitions from table properties instead of asking the Glue catalog for them, so new days need no step at all:
ALTER TABLE clicks_parquet SET TBLPROPERTIES (
'projection.enabled' = 'true',
'projection.dt.type' = 'date',
'projection.dt.format' = 'yyyy-MM-dd',
'projection.dt.range' = '2025-01-01,NOW',
'storage.location.template' = 's3://my-bucket/clicks-parquet/dt=${dt}/'
);
With projection on, put a filter on every partition column, or Athena has to list every possible value in S3.
Put a ceiling on every query
A workgroup can cancel any query that scans more than a set amount. Set it in the console under the workgroup's execution controls, or with the CLI:
aws athena update-work-group --work-group analysts \
--configuration-updates BytesScannedCutoffPerQuery=1099511627776
That cancels any query in the analysts workgroup that would scan more than 1 TiB, about $5.50. The cancelled query is still billed for what it read up to the limit, so the limit caps the damage rather than preventing it. Workgroups can also have hourly or daily limits that send an alarm or switch the workgroup off. Give each team its own workgroup and the bill splits by team as well.
Reuse results instead of scanning again
A dashboard that runs the same query every few minutes pays every time. With query result reuse turned on, Athena returns the last result for the same query in the same workgroup without scanning, as long as it is younger than the maximum age you set: 60 minutes by default, 7 days at most. It works for SELECT statements on Hive, Iceberg, Hudi and Delta tables in Glue, not on federated sources.
When paying for capacity is cheaper
Capacity Reservations replace the per-byte charge with a charge for compute: $0.30 per DPU-hour in US East, from 4 DPUs, billed by the minute with a 1-minute minimum, and nothing for bytes scanned. 4 DPUs running all month cost about $876, the same as scanning about 175 TB at $5. Teams that scan more than that every month at a steady pace, and can live with the concurrency 4 DPUs give, should price it out. Most teams that have done the layout work above scan far less.
What to do this week
- Sort last month's queries by data scanned (the Athena console's recent queries, or the
ProcessedBytesCloudWatch metric per workgroup) and look at the top 10. - Convert the tables those queries read to compressed Parquet, partitioned by date.
- Make sure the common queries filter on the partition column.
- Set a per-query limit on every workgroup.
Athena is one of several engines that bill by bytes read. Our BigQuery cost calculator and the guide to BigQuery on-demand vs editions cover the same choice on Google Cloud, and SQL query optimization tips covers indexes and plans for databases that bill by time instead. Partitioning is explained on its own in Data Partitioning and ClusteringData Partitioning and ClusteringTwo ways to lay out a large table so a query reads only the files it needs: partitioning splits it by a column such as the date, clustering keeps similar values in the same files..
Questions
- How much does an Amazon Athena query cost?
- SQL queries cost $5 per terabyte scanned in US East (N. Virginia), counted per query, rounded up to the nearest megabyte, with a 10 MB minimum. DDL statements such as CREATE TABLE or ALTER TABLE ADD PARTITION and failed queries are free; a cancelled query is billed for what it scanned before it stopped. S3 storage and requests are billed separately.
- How do I reduce Athena query costs?
- Store data as Parquet or ORC with compression, partition it by the column most queries filter on (usually a date), select only the columns you need, and filter on the partition column. Then set a per-query data scanned limit on the workgroup so one bad query cannot scan a whole table.
- Does Athena charge for storing data?
- No. Athena charges only for the queries. The data and the query results sit in your own S3 buckets and are billed at S3's rates for storage, requests and transfer, and a Glue Data Catalog is billed at Glue's rates.
- Are failed Athena queries charged?
- No. Failed queries and DDL statements are not charged for data scanned. Cancelled queries are, for the data scanned up to the point they were cancelled, and that includes queries a workgroup's data usage limit cancels.
- When are Athena Capacity Reservations cheaper than per-query billing?
- When queries run all day at a steady level. Capacity Reservations cost $0.30 per DPU-hour with no charge for data scanned, from 4 DPUs and with a 1-minute minimum. 4 DPUs for a whole month cost about $876, the price of scanning about 175 TB per query billing.
Sources
Where each fact comes from
- 1Amazon Athena pricing
- 2Optimize data
- 3Use partition projection with Amazon Athena
- 4Supported types for partition projection
- 5Use CloudWatch and EventBridge to monitor queries and control costs
- 6List of CloudWatch metrics and dimensions for Athena
- 7update-work-group, AWS CLI command reference
- 8Reuse query results in Athena
- 9Create a table from query results (CTAS)