Amazon Athenaの請求額が読めないという相談は、たいてい「何バイトが数えられているのか」を掴めていないところで止まっています。テーブルの行数でも結果件数でもなく、S3から読んだファイルのバイト数が課金対象です。だからこそ、同じ集計でもファイル形式とディレクトリ構成を変えるだけで請求額には一桁の差が出るのです。この記事では2026年9月4日時点のAWS公式料金ページとユーザーガイドの実測値をもとに、請求の費目分解、公式単価と無料枠の実数、スキャン量を下げる設計、そして暴走クエリへの歯止めまでを実装の解像度で整理します。Athenaそのものの定義やクエリの書き方はAthenaの仕組みと使い方をまとめた解説に譲り、ここでは費用の実務に絞ります。
まとめ:課金対象はS3から読んだバイト数で、列指向とパーティションで一桁下がる
結論を先に示します。Athenaの請求は「クエリがスキャンしたデータ量」に対する従量課金が主で、AWS公式のAthena料金ページの計算例はスキャン1TBあたり5米ドルで示されています(単価はリージョンによって変わります)。ここに、テーブル定義を保持するGlue Data Catalogと、データそのものを置くS3の費用が別建てで乗ります。
下げ方は一つに集約されます。読むバイト数を減らすことです。AWSのFAQは、圧縮・パーティション分割・列指向形式への変換によってクエリあたり30%から90%の削減が見込めると明記しています。CSVのまま置いたテーブルはWHERE句を書いてもファイル全体を読みますが、Parquetに変換してディレクトリを日付で切っておけば、読むのは対象列の対象日だけになります。
そして歯止めは設計とは別に必要です。ワークグループのスキャン量上限を入れておけば、絞り込みを忘れたクエリは実行中に自動でキャンセルされます。ワークグループの作り方とエンジンバージョンの固定はAthenaをアプリへ組み込む実装の記事にまとめています。この三段(費目の把握・設計での削減・上限での歯止め)が揃えば、費用が読めない状態からは抜けられます。
Athenaの請求はスキャンしたバイト数とGlueとS3の費用に分かれる
最初にやることは、請求書に並ぶSKUを三つに束ねる作業です。クエリのスキャン量、カタログのメタデータ、そしてS3のストレージとリクエスト。この切り分けをしないまま単価だけを眺めても、太っている箇所は見つかりません。
オンデマンドはスキャン量に対する従量課金で失敗クエリは課金されない
既定の課金方式は、クエリごとにスキャンしたデータ量で払うオンデマンドです。公式の計算例は「3TBのスキャンなら 3 × 5USD/TB = 15USD」という形で示されています。ここで数えられるのは、S3から実際に読み出したファイルのバイト数です。列指向形式なら読んだ列のぶんだけ、行指向のCSVやJSONならファイル全体が対象になります。
成功・失敗の扱いには違いがあります。AWS公式のFAQは、失敗したクエリには課金されないと明記する一方で、キャンセルしたクエリについては「キャンセルした時点までにスキャンされたデータ量に対して課金される」と書いています。つまり、暴走に気づいて手で止めても、そこまでの読み出しぶんが請求の対象です。手動での停止は損失を止める手段であって、無料の取り消しではありません。
もう一点、連携データソース(フェデレーテッドクエリ)に対する課金には別の丸めが入ります。公式料金ページの記載は、スキャンされたバイト数をメガバイト単位に切り上げ、クエリごとに最小10MB分を課金するという内容です。小さなクエリを大量に投げる構成では、この最小単位が実効単価を押し上げる方向に働きます。
Glue Data Catalogのオブジェクトとリクエストは月100万件まで無料
Athenaのテーブル定義は、既定でAWS Glue Data Catalogに置かれます。公式料金ページはこれを「標準のデータカタログのレートで課金」と書いているだけなので、実額はGlueの料金ページで確認する必要があります。
そこに書かれている実数は次のとおりです。保存は月間100万オブジェクトまで無料で、超過分は10万オブジェクトあたり1.00米ドル/月。アクセスは月間100万リクエストまで無料で、超過分は100万リクエストあたり1米ドル。ここで言うオブジェクトとは、テーブル・テーブルバージョン・パーティション・パーティションインデックス・統計情報・データベース・カタログを指します。
注意したいのはパーティションがオブジェクトに数えられる点です。1日1パーティションなら年間365個で無料枠の内側ですが、ホーム別・デバイス別・時間別と多次元に切った結果は個数の指数的な増加です。数十万パーティションのテーブルを数本抱えると保存側の無料枠に届き、さらにクエリのたびに走るGetPartitions呼び出しでリクエスト側も積み上がります。この二重の増え方が、後述するパーティション射影を使う理由になります。
S3側ではストレージ料金とGETリクエストの回数が別に積み上がる
Athenaはデータを持ちません。実体はS3のオブジェクトストレージにあり、保存料金・リクエスト料金・転送料金はS3の料金体系に従って別途かかります。クエリ結果の出力先バケットも同じです。
見落としやすいのはリクエスト課金です。スキャン量が同じでも、1MBのファイルが10万個ある構成と1GBのファイルが100個ある構成では、AthenaがS3へ投げるGET回数が3桁違います。小さなファイルが大量にあるテーブルは、スキャン量の請求とは別にS3のリクエスト費用で効いてきます。Athenaのデータ設計に関する公式ガイドがファイルサイズを揃えるよう促しているのは、性能と費用の両面が理由です。
加えて、失敗やキャンセルの直後にはS3側にゴミが残ります。公式ドキュメントは、キャンセルまたは失敗したクエリが部分結果をS3へ書き込んでいる場合があり、Athenaはそれを削除しないと明記しています。マルチパートアップロードの未完了ぶんを止めるライフサイクルポリシーを結果バケットに入れておくのが定石です。
スキャン量を減らす三手は列指向への変換と圧縮とパーティション分割
費目が分かったら、次はスキャン量そのものを削ります。FAQが示す30%から90%という削減幅は、次の三手の組み合わせで実現するものです。効き方の順番は、列指向への変換、パーティション分割、圧縮とファイルサイズ調整、と考えて差し支えありません。
ParquetやORCへ変換してSELECT *をやめると読む列だけが課金される
最初の一手は保存形式です。列指向ストレージ形式の公式解説にあるとおり、ParquetやORCは列ごとにデータをまとめて格納し、さらに列単位の統計情報を持ちます。AthenaはSELECT句とWHERE句から必要な列を判断し、その列のチャンクだけを読みます。
逆に言えば、行指向のCSVやJSONではこの絞り込みが効きません。100GBのCSVから1列だけを取り出すクエリでも、スキャン量は100GBです。そしてどんな形式であってもSELECT *と書いた瞬間に全列が対象になります。列指向へ変換したのに請求が下がらないという相談は、ほぼこの一行が原因です。
CTASで既存のCSVテーブルをParquetのパーティション付きに作り替える
変換にETLツールは要りません。CTAS(CREATE TABLE AS SELECT)を使えば、Athenaのクエリだけで既存テーブルからParquetのパーティション付きテーブルを作れます。
CREATE TABLE analytics.access_log_parquet
WITH (
external_location = 's3://amzn-s3-demo-bucket/access_log_parquet/',
format = 'PARQUET',
write_compression = 'SNAPPY',
partitioned_by = ARRAY['dt']
) AS
SELECT
request_id,
status_code,
bytes_sent,
user_agent,
dt
FROM analytics.access_log_csv
WHERE dt >= '2026-01-01'
実装で踏みやすい落とし穴は三つです。ひとつ、パーティション列を置く位置はSELECT句の末尾です。順序が違うと意図しない列でパーティションが切られます。ふたつ、external_locationに指定するS3の場所は空でなければならず、データが残っているとクエリは失敗します。Athenaが既存データを消すことはありません。
みっつ、CTAS単発で作れるパーティションは100個までという上限があります。数年ぶんの日次パーティションを一気に作ろうとすると、ここで止まります。公式ドキュメントが案内している回避策は、まず直近ぶんをCTASで作り、残りをINSERT INTOで100パーティションずつ足していく方式です。圧縮形式についてはwrite_compressionの使用が推奨されており、Parquetで省略した場合の既定はGZIPになります。
圧縮とファイルサイズの調整でスキャン量とリクエスト量を同時に下げる
圧縮はスキャン量そのものを縮めます。Parquetの列チャンクに対してSNAPPYやZSTDを指定すると、読み出すバイト数が圧縮後のサイズになります。ZSTDを選んだ場合はcompression_levelで1から22までを指定でき、既定は3です。圧縮率を上げれば請求は下がりますが、展開のCPU時間が伸びるため、日次バッチなら高めに、対話クエリなら既定寄りに置くのが扱いやすい設計です。
ファイルサイズの揃え方も同じ工程で片付けます。前述のS3リクエスト課金に加えて、小さすぎるファイルはParquetのブロック単位の読み飛ばしを妨げる要因です。ログを1分ごとに書き出しているような入力は、日次のCTASやINSERT INTOでまとめ直しておくと、スキャン量とリクエスト回数の両方が落ちます。
パーティション射影でGlueへのGetPartitions呼び出しをなくす設定
パーティションを細かく切ると、こんどはメタデータ側が重くなります。パーティション射影は、パーティションの一覧をGlueに問い合わせる代わりに、テーブルプロパティに書いたルールからAthena側がインメモリで計算する仕組みです。GetPartitions呼び出しが消えるため、Glueのリクエスト課金も、新しいパーティションを登録するまで待つ運用も、まとめて不要になります。
date型の射影プロパティを書いて日付パーティションを計算で生成する
時系列データならdate型の射影が第一候補です。既存テーブルに対しては次のようにプロパティを足します。
ALTER TABLE analytics.access_log_parquet SET TBLPROPERTIES (
'projection.enabled' = 'true',
'projection.dt.type' = 'date',
'projection.dt.format' = 'yyyy-MM-dd',
'projection.dt.interval' = '1',
'projection.dt.interval.unit' = 'DAYS',
'projection.dt.range' = '2024-01-01,NOW'
)
射影の型に関する公式リファレンスによれば、rangeにはNOW-3YEARS,NOWのような相対指定も書けます。日付はクエリ実行時にUTCで生成される点に注意してください。日本時間の日付でディレクトリを切っているなら、範囲の端で1日ぶんの取りこぼしが起きます。なおprojection.enabledをtrueにしたのに一部の列の設定を書き忘れると、HIVE_METASTORE_ERRORで欠けている列名を示すエラーが返ります。
storage.location.templateでhive形式以外のパスに合わせる
射影は既定でdt=2026-09-04というhive形式のディレクトリ名を前提にします。既存のログ出力が2026/09/04のような形なら、storage.location.templateでパスの雛形を明示します。
ALTER TABLE analytics.access_log_raw SET TBLPROPERTIES (
'projection.enabled' = 'true',
'projection.year.type' = 'integer',
'projection.year.range' = '2024,2030',
'projection.month.type' = 'integer',
'projection.month.range' = '1,12',
'projection.month.digits' = '2',
'projection.day.type' = 'integer',
'projection.day.range' = '1,31',
'projection.day.digits' = '2',
'storage.location.template' =
's3://amzn-s3-demo-bucket/raw/${year}/${month}/${day}/'
)
テンプレートには全てのパーティション列のプレースホルダを含め、末尾をスラッシュで終える必要があります。列が一つでも欠けたテンプレートは無効です。digitsを指定しているのは、月と日を09のようにゼロ埋めして実際のパス表記に合わせるためです。
型の選び分けもここで決めておきます。integerが扱える範囲はJavaのsigned longまでです。enumは列挙値を並べる形ですが、テーブルのメタデータ全体がgzip圧縮後で約1MBというGlueの制約に収まる必要があるため、公式は数十件までに抑えるよう案内しています。IDのような高カーディナリティの列はinjected型に回し、WHERE句で必ず値を渡す運用にします。ただしinjectedはstring型のみで、WHERE INに並べられる値は1,000個までです。
ワークグループのデータ使用量制御で暴走したクエリを実行中に止める
設計で下げても、絞り込みを書き忘れた1本が全期間を読む事故は起きます。ワークグループのデータ使用量制御は、この事故を実行中に止めるための仕掛けです。設定は二種類あり、性質がまったく違います。
クエリごとのスキャン量上限は10MBから7EBの範囲で超過時に自動停止
ひとつめは、クエリ1本あたりのスキャン量に対する上限です。コンソールで指定できる値の範囲は10MB(最小)から7EB(最大)で、超えたクエリは自動でキャンセルされます。この動作は変更できません。上限はワークグループに1つだけ設定でき、そのワークグループで走る全クエリに適用されます。
CLIから入れる場合はBytesScannedCutoffPerQueryをバイト単位で渡します。APIリファレンス上の最小値は10,000,000バイトです。
aws athena update-work-group \
--work-group analytics-adhoc \
--configuration-updates BytesScannedCutoffPerQuery=10737418240
上の例は10GiB(10,737,418,240バイト)を上限に置いた指定です。解除したいときはRemoveBytesScannedCutoffPerQuery=trueを渡します。運用としては、分析者が手で書く探索用ワークグループには厳しめの上限を、日次バッチ用のワークグループには上限なしか大きめの値を置く、という分け方が扱いやすい形になります。
ワークグループ単位のしきい値はSNS通知で自動キャンセルはされない
ふたつめは、ワークグループ全体で一定期間に読んだ量に対するしきい値です。こちらは時間単位または日単位の集計に対して複数のしきい値を置けますが、到達してもクエリは自動で止まりません。実装はCloudWatchアラームで、動作はAmazon SNSトピックへの通知です。
止めたい場合は通知の先に処理を足します。公式ドキュメントが挙げている手段は、SNSからLambda関数を起動する方法と、ワークグループそのものを無効化して以降のクエリを走らせなくする方法です。二人以上が同時にクエリを投げると、各クエリは個別の上限に触れないのに合計だけがしきい値を超える状況が起きるため、クエリごとの上限とワークグループ単位のしきい値は両方入れておくのが安全側の設計になります。
キャパシティ予約は最小4DPUで固定費へ切り替える判断材料になる
スキャン量課金では読みにくい、という結論になったときの選択肢がキャパシティ予約です。DPU(1DPUで概ね4vCPUと16GBメモリ)を確保して、スキャン量ではなくDPU時間で払う方式に切り替えます。公式料金ページの単価は0.30米ドル/DPU時間、Apache Spark向けは0.35米ドル/DPU時間です。
制約は事前に押さえておく必要があります。1予約あたりの最小は4DPUで、1アカウント1リージョンで最大100予約・合計1,000DPUまで。1つの予約に割り当てられるワークグループは20個までです。予約したキャパシティが埋まっている間、新しいクエリが待ち行列に入る時間は最大10時間です。DDLは1本あたり4DPU固定、DMLは複雑さに応じて4から124DPUが自動で割り当てられます。Apache Spark用に設定したワークグループは対象外で、キャパシティ要求そのものが保証されるわけでもなく、完了までに最大30分かかります。
判断材料としては、スキャン量課金と併用できることを覚えておくと使いやすくなります。同一アカウント内で、予約に紐づけたワークグループだけがDPU課金になり、それ以外は従来どおりスキャン量課金です。まず重要度の高いバッチだけを予約側に移し、実測してから範囲を広げる進め方が取れます。
費用の面から見て採用してよい条件と別の構成へ移すべき場面の線引き
ここまでの単価と制約を踏まえて、Athenaを費用面から採用してよい場面と、別の構成に移したほうがよい場面を条件で言い切ります。判断軸はスキャン量の総量ではなく、「読む頻度」と「1本あたりの応答要件」の二つです。
採用してよいのはS3のデータを低頻度に広く読む分析が中心の場面
採用してよい条件は明確です。すでにS3にデータが溜まっており、クエリの実行が1日あたり数十本から数百本規模で、1本の応答が数秒から数十秒でも支障がない。この条件なら、常時稼働するクラスタを持つ構成に比べて費用は確実に下がります。使っていない時間に費用が発生しないという性質が、そのまま効く場面です。
データレイクの構成を採る現場では、生データの探索と月次の集計がここに当たります。Parquet化とパーティション射影まで入れておけば、テラバイト級のログでも1本あたりのスキャンは数GBに収まり、月額は数十米ドルの水準に落ち着きます。
見送るべきは高い同時実行数と低レイテンシが要件に入るシステム構成
逆に、ダッシュボードの裏側で秒単位の応答を求められる用途や、数十人が同時に叩く用途では、Athenaは苦しくなります。スキャン量課金は同じクエリを繰り返すほど請求が積み上がる構造で、キャッシュ前提の画面表示とは相性がよくありません。同時実行の待ち行列もキャパシティ予約なしでは制御できません。
この要件ならDWHへ寄せるのが妥当です。課金モデルの違いを比べる材料としてはBigQueryの料金構造をまとめた解説が使えます。スキャン量課金と、確保したスロット時間で払う方式の分岐点をどこに置くかという議論は、Athenaでキャパシティ予約に移す判断とほぼ同じ形になります。表形式の管理まで含めて構成を組み替えるなら、レイクハウス構成の実装手順で選定の順番を確認してください。
外部に任せる場合は見積書のどこを読めば費用の歯止めが分かるのか
受託で組んでもらう場合、見積書で確認すべき箇所は三つに絞れます。ひとつ、テーブルの保存形式とパーティション設計が成果物に含まれているか。CSVのまま外部テーブルを張るだけの構成では、運用開始後にスキャン量が想定の何倍にもなります。ふたつ、ワークグループのスキャン量上限とSNS通知が初期構築に入っているか。これは実装工数としては小さく、抜けやすい項目です。
みっつ、パーティションの増え方に対する設計方針が書かれているか。Glueのオブジェクト無料枠と射影の採否は、ここで決まります。分析基盤の層構成まで含めて設計を任せる場合は、収集層から可視化層までのどこに費用が発生するかを層ごとに示してもらうとよいでしょう。当社ではデータ分析基盤構築・MLOps構築支援として、S3とAthenaを土台にした構成の設計から費用の歯止めの実装まで請けています。
よくある質問
Amazon Athenaの料金は事前に見積もれますか?
おおよその見積もりは可能です。対象テーブルのうち実際に読む列のサイズを合計し、パーティションで絞ったあとのバイト数にクエリ本数を掛けます。この数値に公式の単価を当てれば上限側の目安が出ます。実測に切り替えるには、クエリ実行後にコンソールの「スキャンしたデータ」欄か、GetQueryExecutionのDataScannedInBytesを見てください。
失敗したクエリにも料金はかかりますか?
かかりません。AWSのFAQでは、クエリごとの課金方式において失敗したクエリが課金対象外であることは明記済みです。ただしキャンセルしたクエリは別扱いで、キャンセルした時点までにスキャンされたデータ量に対して課金されます。手で止めても、そこまでの読み出しぶんは請求されます。
Parquetに変換するとどのくらい安くなりますか?
AWSのFAQによると、圧縮・パーティション分割・列指向形式への変換で見込める削減幅はクエリあたり30%から90%です。削減幅は元データの列数と、クエリが実際に参照する列の割合で決まります。100列のCSVから3列だけを読む集計なら、削減幅は上限側に寄ります。
パーティションは細かく切るほど安くなりますか?
一定の点を超えると逆に不利です。パーティションはGlue Data Catalogのオブジェクトとして数えられ、月100万オブジェクトの無料枠を消費します。またクエリのたびにGetPartitions呼び出しが走り、リクエスト側の課金とメタデータ検索の待ち時間が増えます。細かく切る場合はパーティション射影を併用してください。
スキャン量課金と固定費はどちらを選ぶべきですか?
実測してから決めるのが確実です。比較対象は、月間のスキャン量に単価を掛けた額と、必要なDPU数×稼働時間×0.30米ドルです。夜間バッチが集中して待ちが発生している構成では、費用が同等でもキャパシティ予約側に移す価値があります。両方を同一アカウントで併用できるため、対象を絞って試せます。
関連記事
- Amazon Athena(アテナ)とは?使い方・クエリの書き方・料金・Redshiftとの違いを解説:前提となる仕組みとクエリの書き方をまとめています。
- BigQueryの料金:オンデマンドとEditionsの分岐点・ストレージ課金・コスト監視:課金モデルの異なるGoogle Cloud側との比較材料です。
- データレイクとは?データウェアハウス・レイクハウスとの違いを実装視点で解説:Athenaが読む側のデータ配置を扱います。
- Amazon S3とは?オブジェクトストレージの仕組み・ストレージクラスと料金・採用判断を実装者目線で解説:別建てで乗るS3側の費用構造です。
- データ分析基盤の構築とは?5層アーキテクチャとBigQuery実装手順を技術視点で解説:層構成と実装手順の全体像です。
- データレイクハウス実装の手順6ステップ|アーキテクチャ選定と移行判断を実務視点で解説:表形式まで含めた構成の組み替え手順です。