All cheat sheets
Databasescheat sheet

Athena Partition Projection

Instead of asking S3 which partitions exist before every query, Partition Projection lets Athena calculate the paths from a pattern you declare — near-instant query startup on tables with thousands of partitions, zero LIST metadata calls.

Last reviewed: July 14, 2026

TL;DR: By default Athena discovers partitions by listing S3 (or the Glue Catalog) before a query runs — fine at 50 partitions, painful at 50,000. Partition Projection (2020) flips it: you declare the pattern in TBLPROPERTIES and Athena calculates exactly the partition paths a query needs — zero LIST calls, near-instant startup, and new partitions (like today's date) appear automatically with no MSCK REPAIR TABLE or crawler runs. It's a metadata optimization, not a scan-cost one; the big win is usually latency.

The numbers

  • S3 LIST is $0.005 per 1,000 calls. A pattern listing 365 daily partitions hourly ≈ 263,000 LIST calls/mo ≈ $1.30/mo per pattern — small alone, real across dozens of queries and millions of partitions.
  • The dominant win is query startup: a table with ~4,380 hourly partitions goes from "noticeable lag" listing all of them to "instant" when Athena projects only the 24 hours a query wants.
  • Projection types: date (year/month/day/hour — the home run), enum (known regions/categories), integer (clean ID or year-bucket ranges), or injected values passed at query time.

Do this

  1. Add projection properties to the table DDL — declare it once and Athena generates paths from the WHERE clause:
    TBLPROPERTIES (
      "projection.enabled" = "true",
      "projection.dt.type" = "date",
      "projection.dt.range" = "2020-01-01,NOW",
      "projection.dt.format" = "yyyy-MM-dd"
    )
    
  2. Match the type to the data: date for time-series, enum for a fixed set of regions/categories, integer for clean numeric ranges.
  3. Always filter partition columns in the WHERE clause so the win compounds — Athena projects only the needed partitions and scans no data outside them:
    SELECT * FROM logs WHERE dt BETWEEN DATE '2024-11-01' AND DATE '2024-11-07'
    
  4. Manage the DDL in code (Terraform/CDK/dbt) so the projection definition is reviewable in PRs, not clicked once into the console and forgotten.
  5. Verify in the query execution details that "Data scanned" and execution time drop.

Gotchas

  • Schema drift is on you — a new region or renamed path scheme won't be discovered; you update TBLPROPERTIES manually. Add it to your "when we rev the schema" checklist.
  • Patterns must be clean — mixed formats, gaps, or one-off subdirectories make projection messy or impossible; random UUID prefixes have nothing to project against (keep Glue discovery there).
  • Debugging is harder — an empty result set could mean missing data or a wrong projection config; you lose the explicit Glue Catalog listing.

Skip this if

  • The table is small (~20–30 partitions) — listing them is free and the DDL isn't worth it.
  • The partition layout is irregular or the schema is still churning frequently — a projection that drifts out of sync is worse than none; stick with Glue discovery until it settles.
  • Your Athena bill is about bytes scanned, not partition discovery — reach for columnar formats (Parquet/ORC) and Athena Query Result Reuse, which compound with projection.

Run this audit with your AI assistant

Paste this into Claude, ChatGPT, or any agent that can run the AWS CLI with read-only credentials. It audits your account for exactly the waste this sheet describes — and changes nothing.

You are auditing an AWS account's Athena/Glue tables for Partition
Projection opportunities. Use the AWS CLI with READ-ONLY credentials.
Do not create, modify, or delete anything — report findings and
recommended (unapplied) fixes only.

1. Inventory tables: aws glue get-databases, then get-tables — for each
   table capture partition keys, storage location, and whether
   projection.enabled is already set in table Parameters.
2. Partition count: aws glue get-partitions --database-name X
   --table-name Y | length — flag tables with hundreds+ of partitions
   and a CLEAN, predictable partition scheme (date/time, enum of
   regions/categories, integer ranges). These are projection candidates.
3. Query pattern: from Athena query history (aws athena
   list-query-executions + get-query-execution) identify high-frequency
   queries that filter on partition keys — those benefit most.
4. Disqualifiers to flag: random/UUID prefixes, mixed or irregular path
   formats, rapidly-evolving schemas (projection drift risk), and tiny
   tables (<~30 partitions, not worth the DDL).

Report a table: table | partition keys | partition count | scheme type
(date/enum/integer/irregular) | projection candidate? | suggested
TBLPROPERTIES (for review, do NOT apply). Change nothing.
Works with any assistant that can run shell commands.

Want the guided version?

The Athena Partition Projection walkthrough covers this topic interactively — it asks about your setup, branches to what’s relevant, and quizzes you on the tricky parts. Free and anonymous.

Start the walkthrough