Skip to the page
Tecyfy

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

Paper archive shelves with a beam of light picking out 2 boxes beside a meter labelled Athena

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 queryBytes scanned, rounded up to the MB, 10 MB minimum
A failed queryNo
CREATE, ALTER, DROP TABLE, adding partitionsNo
A cancelled queryYes, for what it scanned before it stopped
Storing the data and the results in S3Yes, at S3's own rates
The Glue Data CatalogYes, 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.

LayoutData scannedCost per query
JSON as it arrives36 TB$180
JSON, gzip (about 3 times smaller)12 TB$60
Parquet, compressed, reading 3 of 30 columns1.2 TB$6
Parquet, partitioned by day, filtering the last 7 days23 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.

Try itWhat one Athena query scans
36 TB
30
3
7
200
Raw JSON$180
Your layout$0.1151

1,564 times cheaper than raw JSON

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

  1. Sort last month's queries by data scanned (the Athena console's recent queries, or the ProcessedBytes CloudWatch metric per workgroup) and look at the top 10.
  2. Convert the tables those queries read to compressed Parquet, partitioned by date.
  3. Make sure the common queries filter on the partition column.
  4. 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.