Amazon S3 Tablesは、Apache Iceberg形式の表を保存するための専用バケット「テーブルバケット」と、その表の保守をS3側で自動実行する機能をまとめたサービスです。2024年12月3日に一般提供が始まり、東京リージョンでは2025年1月17日から使えます。この記事では、汎用バケットにIcebergを置く構成との違い、東京リージョンの課金項目と1TBあたりの試算、自動メンテナンスの既定値、パーティションの切り方、CLIでの作成からAthenaで読むまでの手順を、2026年9月時点のAWS公式ドキュメントと料金データに基づいて整理します。
まとめ
- S3 Tablesが扱える表形式はApache Icebergだけです。Delta LakeやHudiの表は置けません。
- 東京リージョンのストレージ単価は最初の50TBで0.0288 USD/GB・月で、S3 Standardの0.025 USD/GBより約15%高くなります。これに加えて、オブジェクト監視料とコンパクション処理料がかかります。
- コンパクション、スナップショット管理、参照されないファイルの削除の3つは既定で有効です。既定では120時間(約5日)を超えたスナップショットが期限切れの対象になりますが、最低1つは保持されます。タイムトラベルで参照できる時点は、実際に残っているスナップショットによって決まります。
- Icebergのテーブルプロパティで保持期間を設定したり、タグやブランチを作ったりすると、そのテーブルのスナップショット管理は丸ごと失敗します。
- 2026年3月17日から、Glue Data Catalog経由のアクセスはIAMポリシーだけで制御できるようになりました(東京リージョンも対象)。Lake Formationは任意です。
S3 Tablesの定義と汎用バケットとの違い
S3 Tablesでは、表を置くための新しいバケット種別であるテーブルバケットを作り、その中にIcebergテーブルを作成します。テーブルの作成APIが受け付ける形式の値は ICEBERG の1つだけで、ストレージクラスは STANDARD と INTELLIGENT_TIERING の2種類です(AWS SDKのサービス定義で確認)。S3そのものの仕組みはAmazon S3の解説記事を、テーブル形式とファイル形式の関係はIcebergとParquetの違いを参照してください。
テーブルバケット・名前空間・テーブルの3階層と上限
テーブルは「テーブルバケット → 名前空間 → テーブル」の3階層で整理されます。名前空間は論理的な分類であり、テーブルバケットやテーブルと異なり、独立したAWSリソースではありません。Glue Data Catalogと統合すると、名前空間はデータベースとして見えます。テーブルバケットのARNは arn:aws:s3tables:<リージョン>:<アカウントID>:bucket/<バケット名> の形式です。
| リソース | 既定の上限 | 数える単位 |
|---|---|---|
| テーブルバケット | 10 | アカウント・リージョンごと |
| 名前空間 | 10,000 | テーブルバケットごと |
| テーブル | 10,000 | テーブルバケットごと |
3つともサポートへの申請で引き上げられます。テーブル数の上限は2025年1月30日に10,000へ引き上げられ、1リージョンあたり最大10万テーブル(10バケット×10,000)を既定で持てるようになりました。名前空間名は1〜255文字で、使える文字は英小文字・数字・アンダースコアです(先頭のアンダースコアは不可)。テーブル名と列名に大文字を含めるとGlue Data CatalogとLake Formationがその表を扱えず、Athenaから見えなくなるため、すべて小文字で定義します。
汎用バケットにIcebergを置く構成との比較
Icebergは汎用バケットにも置けます。S3 Tablesを使う理由は、自分で回していた保守ジョブをS3へ任せられる点にあります。
| 項目 | 汎用バケット+Iceberg | S3 Tables |
|---|---|---|
| 置ける表形式 | Iceberg・Delta Lake・Hudiなど | Icebergのみ |
| 小さなファイルの結合 | 自前のジョブで実行 | 自動(既定で有効) |
| 古いスナップショットの削除 | 自前のジョブで実行 | 自動(既定120時間) |
| 参照されないファイルの削除 | 自前のジョブで実行 | 自動(3日後に非現行・その10日後に削除) |
| 公開アクセス・署名付きURL | 使える | 使えない |
| 東京のストレージ単価(最初の50TB) | 0.025 USD/GB・月 | 0.0288 USD/GB・月 |
性能の公称値は、提供開始時の発表(2024年12月3日)では「セルフマネージドのテーブルと比べてクエリスループット最大3倍、1秒あたりのトランザクション数(TPS)最大10倍」でした。2026年9月時点の日本語版製品ページに残っているのは「汎用バケットに保存したIcebergテーブルと比べてTPS最大10倍」だけで、3倍の記述はありません。クエリ速度の見積もりに3倍を使うのは避け、自分のクエリで計測してください。
S3 Tablesの料金(東京リージョン)
単価は、AWS Price List APIの東京リージョン(ap-northeast-1)とバージニア北部(us-east-1)のオファーファイルから2026年9月26日に取得した値です(課金項目の体系はAmazon S3の公式料金ページでも確認できます)。S3全体の料金の考え方はS3の料金を実額で計算する記事にまとめています。
課金項目と単価
| 課金項目 | 東京 | バージニア北部 |
|---|---|---|
| ストレージ(最初の50TB) | 0.0288 USD/GB・月 | 0.0265 USD/GB・月 |
| ストレージ(次の450TB) | 0.0276 USD/GB・月 | 0.0253 USD/GB・月 |
| ストレージ(500TB超) | 0.0265 USD/GB・月 | 0.0242 USD/GB・月 |
| PUT・COPY・POST・LIST(1,000件) | 0.0047 USD | 0.005 USD |
| GETほか(1,000件) | 0.00037 USD | 0.0004 USD |
| オブジェクト監視(1,000個・月) | 0.025 USD | 0.025 USD |
| コンパクション(1,000オブジェクト) | 0.00185 USD | 0.002 USD |
| コンパクション処理量(1GB) | 0.005 USD | 0.005 USD |
| sort・Z-order処理量(1GB) | 0.01 USD | 0.01 USD |
| レプリケーション(1,000更新) | 0.01 USD | 0.01 USD |
東京のリクエスト単価はS3 Standardと同額なので、差が出るのはストレージ単価、オブジェクト監視料、コンパクション料の3つです。これとは別に、AWSの分析サービスと統合するとGlue Data Catalogのリクエスト料・保存料がかかり、AthenaやEMRで読めばそれぞれのクエリ料金も発生します。
1TBの表の月額試算
東京リージョンで、月に1TB(1,024GB)を10MB前後の小さなファイルで書き込み、月内に全量を1回binpackで結合して512MBのファイルにまとめた場合を計算します。以下は平均保存量を1,024GB、平均監視対象数を結合後の2,048個と置いた簡略試算です。結合前ファイル、旧スナップショットが参照するファイル、非現行ファイル、メタデータによる追加保存量・監視対象数は含めません。リクエスト料も除外しますが、単価が同じでもリクエスト数によって総額は変わります。
| 内訳 | S3 Tables | 汎用バケット(S3 Standard) |
|---|---|---|
| ストレージ 1,024GB | 29.49 USD | 25.60 USD |
| 監視(結合後の約2,048個) | 0.05 USD | なし |
| 結合対象 約104,858個 | 0.19 USD | 自前ジョブの計算費 |
| 結合の処理量 1,024GB | 5.12 USD | 自前ジョブの計算費 |
| 合計 | 約34.86 USD | 25.60 USD+自前ジョブ |
差額は1TBあたり月9.26 USDです。自前でSparkの rewriteDataFiles を定期実行している環境なら、その計算費と運用の手間がこの差額より大きいかで判断します。コストを最も大きく動かすのは処理量で、sort・Z-order戦略では1GBあたり0.01 USDと倍になり、同じデータが何度も結合し直されれば処理量は書き込み量を超えます。逆に、最初から大きなファイルで書くバッチ中心の表では結合がほとんど発生せず、差はストレージ単価の約15%に近づきます。2025年6月11日からは、テーブル単位のストレージ・リクエスト・メンテナンス費用をCost ExplorerとCURで確認できます。
Intelligent-Tieringの階層別料金と適用条件
2025年12月2日に、S3 Tables専用のIntelligent-Tieringストレージクラスが追加されました。30日間アクセスのないデータは低頻度アクセス層へ、90日間アクセスのないデータはアーカイブインスタントアクセス層へ自動で移ります。東京の単価は高頻度アクセス層が0.0288 USD/GB、低頻度アクセス層が0.0159 USD/GB、アーカイブインスタントアクセス層が0.0058 USD/GBで、層の間の移動に取り出し料金はかかりません。コンパクションは高頻度アクセス層のファイルだけを処理するため、古いパーティションの再結合費用も抑えられます。
注意点は3つあります。1つ目に、ストレージクラスはテーブル作成時にしか指定できず、作成後は変更できません。テーブルバケットの既定ストレージクラスを変えても、対象はその後に作るテーブルだけです。2つ目に、128KB未満のファイルは階層移動の対象外で、高頻度アクセス層に残ります。3つ目に、低頻度側の層にあるデータへ削除を行うと、生成された削除ファイルは自動コンパクションの対象になりません。更新や削除が頻繁に入る表では、EMRなどで手動のコンパクションを検討します。
自動メンテナンス3種の既定値と無効化
S3 Tablesが自動で行う保守は、テーブル単位のコンパクションとスナップショット管理、テーブルバケット単位の参照されないファイルの削除の3つです。どれも既定で有効で、自動メンテナンスが正常に動作していれば、Icebergの対応する保守処理(rewriteDataFiles・expireSnapshots・deleteOrphanFiles)を自分で動かす必要がなくなります。
| 設定項目 | 設定単位 | 既定値 | 最小値 |
|---|---|---|---|
| コンパクションの目標ファイルサイズ | テーブル | 512MB | 64MB |
| 保持する最小スナップショット数 | テーブル | 1 | 1 |
| スナップショットの最大保持時間 | テーブル | 120時間 | 1時間 |
| 未参照ファイルを非現行にするまで | テーブルバケット | 3日 | 1日 |
| 非現行ファイルを削除するまで | テーブルバケット | 10日 | 1日 |
コンパクションの戦略は auto(既定)・binpack・sort・z-order の4つです。auto はテーブルにソート順が定義されていれば sort、なければ binpack を選びます。sort と z-order を明示するには、Icebergのテーブルプロパティにソート順を定義し、s3tables:GetTableData 権限を与えます。結合はParquet・Avro・ORCのファイルが対象で、既定ではParquetで書き出されます。コンパクション料金を払いたくないテーブルは、PutTableMaintenanceConfiguration で "status":"disabled" を指定すれば止められます。
スナップショット管理が止まる条件
スナップショット管理は、S3 Tablesの設定だけを見て動きます(AWS公式ドキュメント「Maintenance for tables」)。次のどちらかに当てはまると、そのテーブルのスナップショット管理は全体が失敗し、古いスナップショットも削除されません。
- テーブルにユーザー定義のタグまたはブランチがある(保持期間が短くても失敗します)
- Icebergのテーブルプロパティに
history.expire.max-snapshot-age-msまたはhistory.expire.min-snapshots-to-keepが設定されている(値は問いません)
汎用バケットから移したテーブルにこれらのプロパティが残っていると、ストレージが増え続けます。get-table-maintenance-job-status で状態が FAILED になっていないかを確認し、プロパティは ALTER TABLE … UNSET TBLPROPERTIES で外します。タイムトラベルでより長く遡りたい場合は、プロパティではなくS3 Tables側の設定を延ばします。本文のAWS CLI例は、認証情報と必要な権限を設定し、同じシェルで export AWS_DEFAULT_REGION=ap-northeast-1 を実行したうえで使用します。アカウントIDの 111122223333 は実際の値に置き換えてください。次の例は、作成済みのテーブルに対して保持期間を30日(720時間)、最低10世代にする設定です。
aws s3tables put-table-maintenance-configuration \
--table-bucket-arn arn:aws:s3tables:ap-northeast-1:111122223333:bucket/analytics-tables \
--namespace sales \
--name orders \
--type icebergSnapshotManagement \
--value '{"status":"enabled","settings":{"icebergSnapshotManagement":{"minSnapshotsToKeep":10,"maxSnapshotAgeHours":720}}}'
期限切れのスナップショットからしか参照されないファイルは、非現行になった後、指定日数で完全に削除されます。非現行のファイルを確認・復元するにはAWSサポートへの連絡が必要で、削除後は戻せません。
S3 Tablesのパーティション設計
汎用バケット上のHive形式の表をAthenaなどで読み、パーティションを絞り込む場合は、dt=2026-09-26/ のようなプレフィックスでパーティションを切り、クエリでもパーティション列を条件に書く必要がありました。S3 TablesはIcebergのパーティション変換(identity・bucket・truncate・year・month・day・hour)をテーブルのメタデータに定義する方式で、クエリは元の列を条件にするだけでファイルの絞り込みが効きます。次の例は、Iceberg対応のSparkSessionを spark として作成し、接続先のテーブルバケットを s3tablesbucket というカタログ名で設定し、名前空間 sales を作成済みの環境で実行します。
spark.sql("""
CREATE TABLE IF NOT EXISTS s3tablesbucket.sales.orders (
order_id BIGINT,
customer_id BIGINT,
amount DECIMAL(12,2),
ordered_at TIMESTAMP
)
USING iceberg
PARTITIONED BY (days(ordered_at))
""")
パーティションを細かくしすぎると逆効果です。コンパクションはパーティションごとにファイルをまとめるため、1日に数十MBしか入らない表を hours() で切ると、既定の目標512MBに届かない小さなファイルがパーティションの数だけ残り、オブジェクト監視料も増えます。書き込み量が少ない表は days() や months() で粗く切り、顧客IDのように値の種類が多く絞り込みに使う列は、パーティションではなくソート順に指定して sort コンパクションに任せるのが基本です。
テーブル作成からクエリまでの手順
AWS CLIによるテーブルバケット・名前空間・テーブルの作成
CreateTable APIでパーティションとソート順を指定できるようになったのは2026年2月12日なので、AWS CLI v2を最新版に更新してから実行します。リージョンは東京、バケット名は analytics-tables の例です。
aws s3tables create-table-bucket --region ap-northeast-1 --name analytics-tables
aws s3tables create-namespace \
--table-bucket-arn arn:aws:s3tables:ap-northeast-1:111122223333:bucket/analytics-tables \
--namespace sales
aws s3tables create-table --cli-input-json file://orders.json
orders.json ではスキーマと、必要ならパーティション仕様を定義します。パーティション列はスキーマの列IDを sourceId で参照するため、各列に id を明示します。
{
"tableBucketARN": "arn:aws:s3tables:ap-northeast-1:111122223333:bucket/analytics-tables",
"namespace": "sales",
"name": "orders",
"format": "ICEBERG",
"metadata": {
"iceberg": {
"schema": {
"fields": [
{"id": 1, "name": "order_id", "type": "long", "required": true},
{"id": 2, "name": "customer_id", "type": "long"},
{"id": 3, "name": "ordered_at", "type": "timestamp"}
]
},
"partitionSpec": {
"specId": 0,
"fields": [
{"sourceId": 3, "transform": "day", "name": "ordered_day"}
]
}
}
}
}
テーブルバケットは既定でSSE-S3により暗号化されます。KMSキーを使う場合は create-table-bucket に --encryption-configuration を付けます。
Athenaから読むための分析サービス統合
Athena、Redshift、EMR、Quick、Data Firehoseから使うには、テーブルバケットをAWSの分析サービスと統合します。統合するとGlue Data Catalogに s3tablescatalog というカタログが追加され、テーブルバケットはサブカタログ、名前空間はデータベース、テーブルはテーブルとして登録されます。統合はリージョンごとに1回で、以後に作ったバケットも自動で反映されます。S3コンソールでテーブルバケットを作るときに「統合を有効にする」にチェックが入っていれば自動で行われ、CLIで行う場合は glue:CreateCatalog と glue:PassConnection の権限が必要です。
Athenaのクエリエディタでは、カタログに s3tablescatalog/analytics-tables、データベースに名前空間 sales を選びます。Athenaの基本操作はAmazon Athenaの解説を参照してください。
権限の仕組みは2026年3月17日に変わりました。Glue Data CatalogがS3 Tables向けにIAMベースの認可に対応し、ストレージ・カタログ・クエリエンジンの権限を1つのIAMポリシーで定義できます。Glueのユーザーガイドでは、東京リージョンはS3 Tables統合の対応リージョンに含まれ、アクセス制御は「IAMアクセス制御」と「Lake Formationアクセス制御」の2方式です(AWS Glueユーザーガイド「Integrating with Amazon S3 Tables」)。AWS Lake Formationは、細かい単位で権限を管理したいときにいつでも追加で有効にできる位置づけになりました。2025年に書かれた手順記事の多くは「Lake Formationで権限付与が必須」としていますが、これは変更前の手順です。ただし、S3ユーザーガイドのGlue Iceberg RESTエンドポイントの章は2026年9月時点でもLake Formationの付与を前提に書かれているため、どちらの方式で統合したかを確認してから手順を読み分けてください。
SparkやPyIcebergなどAWS外のエンジンからの接続方式
| 方式 | 接続先・配布物 | 向く場面 |
|---|---|---|
| Glue Iceberg RESTエンドポイント | https://glue.<region>.amazonaws.com/iceberg | AWSの推奨・権限を一元管理 |
| S3 Tables Iceberg RESTエンドポイント | https://s3tables.<region>.amazonaws.com/iceberg | 単一バケットの読み書き |
| S3 Tables Catalog for Apache Iceberg | Maven 0.1.8(2025年8月) | Sparkのカスタムカタログ |
AWSのドキュメントは、S3 Tables Iceberg RESTエンドポイントを「パートナーや独自のカタログ実装から使う場合か、単一のテーブルバケットへの基本的な読み書きだけで足りる場合」に限定し、それ以外はGlue Iceberg RESTエンドポイントを勧めています。PyIcebergからGlue経由で接続する設定は次のとおりで、SigV4の署名名が glue、warehouseが「アカウントID:s3tablescatalog/バケット名」になる点が汎用のIcebergカタログと異なります。
from pyiceberg.catalog import load_catalog
catalog = load_catalog(
"s3tablescatalog",
**{
"type": "rest",
"warehouse": "111122223333:s3tablescatalog/analytics-tables",
"uri": "https://glue.ap-northeast-1.amazonaws.com/iceberg",
"rest.sigv4-enabled": "true",
"rest.signing-name": "glue",
"rest.signing-region": "ap-northeast-1",
},
)
print(catalog.list_namespaces())
S3 Tablesを選ばないほうがよいケース
次の条件に当てはまる場合は、汎用バケットにIcebergを置く構成のままにするか、別の仕組みを使います。
- Delta LakeやHudiを使い続ける:テーブル形式は
ICEBERGしか指定できません。形式の比較はオープンテーブルフォーマットの解説を参照してください。 - Icebergのタグ・ブランチで保持を管理している:タグやブランチが1つでもあるとスナップショット管理が失敗します。WAP(Write-Audit-Publish)のようにブランチを使う運用とは相性がよくありません。
- ファイルを外部へ直接配る:公開アクセスのポリシーと署名付きURLは使えず、テーブルバケットとテーブルのポリシーは20KBまでです。
- 自分で作ったテーブルに行の保持期限をかけたい:S3 Tablesのレコード有効期限機能は、S3 Storage LensとSageMaker CatalogのAWSマネージドテーブル向けで、ユーザーが作成したテーブルでは使えません。古い行はクエリエンジンから
DELETEで消します。 - 小さなファイルが発生しないバッチ中心の表:結合がほとんど走らず、スナップショット管理や未参照ファイル削除も既存の仕組みで低コストに運用できている場合は、東京の最初の50TBで約15%高いストレージ単価と監視料に見合う保守負担の削減を得にくい構成です。
2024年12月から2026年9月までの主な変更
| 日付 | 変更内容 |
|---|---|
| 2024-12-03 | 一般提供開始(Glue Data Catalog統合はプレビュー) |
| 2025-01-17 | 東京など5リージョンに拡大 |
| 2025-01-30 | 1バケットあたり10,000テーブルに上限拡大 |
| 2025-06-11 | テーブル単位の費用をCost Explorer・CURで表示 |
| 2025-07-01 | コンパクション料金を値下げ(オブジェクト単価50%減・処理量単価はbinpack 90%減、sort・Z-order 80%減) |
| 2025-12-02 | Intelligent-Tiering・レプリケーションに対応 |
| 2026-02-12 | CreateTable APIでパーティションとソート順を定義可能に |
| 2026-03-17 | Glue Data CatalogでIAMベースの認可に対応 |
| 2026-05-29 | 台北・ニュージーランドリージョンに拡大 |
| 2026-07-28 | Iceberg V3のVariant型に対応 |
| 2026-08-28 | Kinesis Data Streamsのストリーミングテーブルが直接配信 |
レプリケーションは、別リージョンや別アカウントのテーブルバケットに読み取り専用のレプリカを作る機能で、スナップショット履歴も含めて複製されるため、レプリカ側でもタイムトラベルができます。Variant型はJSONのような半構造化データを、事前にスキーマを決めずに書き込むための型で、東京リージョンを含む15リージョンで使えます。Kinesis Data Streamsのストリーミングテーブルは、ストリームのデータをIceberg形式でS3 Tablesへ継続配信する機能で、配信経路を自前で組まずに済みます。
よくある質問
S3 Tablesとは何ですか?
Apache Iceberg形式の表を保存する専用のテーブルバケットと、小さなファイルの結合・古いスナップショットの削除・参照されないファイルの削除を自動で行う機能を組み合わせたS3のサービスです。2024年12月3日に一般提供が始まりました。
S3 Tablesの料金はS3 Standardより高いですか?
東京リージョンのストレージ単価は最初の50TBで0.0288 USD/GB・月で、S3 Standardの0.025 USD/GBより約15%高くなります。さらにオブジェクト監視料(1,000個あたり月0.025 USD)とコンパクション料(処理量1GBあたり0.005 USD、sort・Z-orderは0.01 USD)がかかります。リクエスト単価は同額です。
S3 TablesでDelta LakeやHudiは使えますか?
使えません。テーブル作成時に指定できる形式は ICEBERG だけです。Delta LakeやHudiの表は汎用バケットに置きます。
S3 Tablesのタイムトラベルはどこまで遡れますか?
初期設定では、120時間を超えたスナップショットが期限切れの対象になりますが、最低1つは保持されます。参照できる過去の時点は、残っているスナップショットによって異なります。より長く遡れるようにするには、put-table-maintenance-configuration で maxSnapshotAgeHours を延ばします。Icebergのテーブルプロパティで保持期間を設定すると、スナップショット管理そのものが失敗するため使いません。
S3 Tablesでパーティションは必要ですか?
必須ではありません。日付で絞り込むことが多い表では days() などの変換でパーティションを定義すると読み取り量が減ります。ただし書き込み量が少ない表を細かく切ると小さなファイルが残るため、絞り込みに使う列はソート順での指定も検討します。