コンテンツにスキップ

AWS S3・CloudFrontのファイルアップロード上限まとめ|マルチパート・署名付きURL

カテゴリ:クラウド・AWS

AWS を使ったファイルアップロード機能を構築する際、S3・CloudFront・API Gateway・Lambda それぞれに異なるサイズ制限があり、どの層がボトルネックになるかを把握しておくことは非常に重要です。本記事では、各サービスの上限値を整理し、大容量ファイルを扱うためのマルチパートアップロードと署名付き URL の使い方、PHP での実装例まで解説します。

Amazon S3 のアップロード上限

S3 へのオブジェクトアップロードには、方式によって上限サイズが異なります。

アップロード方式 最大サイズ 備考
PUT Object(単体) 5 GB 1リクエストでアップロードできる上限
Multipart Upload 5 TB 1オブジェクトの最大サイズ
1パートあたり 最小 5 MB〜最大 5 GB 最後のパートのみ 5 MB 未満可
パート数 最大 10,000 パート マルチパート時の上限

AWS は 100 MB 以上のファイルにはマルチパートアップロードを推奨しており、ネットワーク障害時の再送効率や並列転送によるスループット向上の観点からも、大容量ファイルには積極的に使うべきです。

マルチパートアップロードが必要なケース

マルチパートアップロードは、1つのオブジェクトを複数のパートに分割してそれぞれを独立したリクエストで送信し、最後に結合する方式です。以下のようなケースで有効です。

  • 100 MB 以上のファイル:AWS が推奨するマルチパート切替ラインです。
  • ネットワーク不安定な環境:途中でエラーが発生しても失敗したパートだけ再送できます。
  • スループット最大化:複数パートを並列でアップロードすることで転送速度を向上できます。
  • アップロード一時停止・再開:Upload ID を保存しておけばセッションをまたいで再開できます。

マルチパートアップロードの流れは大きく3ステップです。

  1. 開始(CreateMultipartUpload): Upload ID を取得する
  2. パート送信(UploadPart): 各パートをアップロードし、ETag を記録する
  3. 完了(CompleteMultipartUpload): パート番号と ETag の一覧を送信してオブジェクトを確定する

途中でキャンセルする場合は AbortMultipartUpload を呼ばないと、未完了のパートがストレージ料金として課金され続けます。S3 バケットのライフサイクルポリシーで「未完了のマルチパートアップロードを N 日後に削除」を設定しておくことを強く推奨します。

Presigned URL の有効期限とサイズ

署名付き URL(Presigned URL)を使うと、S3 へのアクセス権限を持たないクライアント(ブラウザ・モバイルアプリなど)から直接 S3 へファイルをアップロードできます。サーバーを中継しないため、大容量ファイルでも効率的です。

項目 制限・仕様
最大有効期限(IAMユーザー発行) 7 日間(604,800 秒)
最大有効期限(IAMロール発行) ロールのセッション時間内(最大12時間)
アップロード可能なファイルサイズ 単体 PUT の場合は最大 5 GB
マルチパートへの対応 各パートに個別の Presigned URL を発行

Presigned URL はバックエンドで生成してクライアントに返し、クライアントはその URL に対して直接 PUT リクエストを送ります。URL には署名が含まれているため、期限内に正しいファイルをアップロードする場合のみ成功します。

CloudFront の body size 制限

CloudFront を経由してオリジン(S3 や EC2 など)にリクエストを転送する場合、リクエストボディのサイズに制限があります。

設定 デフォルト値 最大値
リクエストボディサイズ(デフォルト) 1 MB ディストリビューション設定で変更可
Lambda@Edge 経由の場合 1 MB 1 MB(変更不可)
CloudFront Functions の場合 リクエストボディへのアクセス不可

CloudFront ディストリビューションの設定で「Allow requests with body」を有効にし、上限を引き上げることができますが、Lambda@Edge では 1 MB の上限が変更できないことに注意してください。大容量ファイルのアップロードには CloudFront を経由させず、Presigned URL でクライアントから S3 に直接アップロードするアーキテクチャを採用することを推奨します。

API Gateway の Payload 制限

API Gateway(REST API / HTTP API いずれも)にはペイロードサイズの上限があります。

API タイプ 最大ペイロードサイズ 備考
REST API 10 MB バイナリサポートを有効にした場合も同様
HTTP API 10 MB
WebSocket API 128 KB(メッセージ)/ 32 KB(フレーム)

API Gateway の 10 MB 制限は AWS のサービスクォータに分類されており、緩和申請はできません。10 MB を超えるファイルを API Gateway 経由でアップロードするのは設計上の誤りと考え、Presigned URL パターンへの移行を検討してください。

Lambda 経由のファイル制限

Lambda 関数でファイルを受け取る場合、API Gateway から渡されるイベントペイロードに上限があります。また Lambda 自体にも以下の制限があります。

制限項目
同期呼び出し(Request)ペイロード 6 MB
同期呼び出し(Response)ペイロード 6 MB
非同期呼び出しペイロード 256 KB
/tmp ディレクトリの容量 デフォルト 512 MB(最大 10 GB)
最大実行時間 15 分

Lambda でファイルを処理する場合、一時ファイルは /tmp に書き込みます。デフォルトは 512 MB ですが、Lambda 設定でエフェメラルストレージを最大 10 GB まで拡張できます(追加料金あり)。

PHP での S3 マルチパートアップロードコード例

AWS SDK for PHP(v3)を使ったマルチパートアップロードの実装例です。SDK の MultipartUploader クラスを使うと、チャンク分割・再試行・完了処理を自動で処理してくれます。

use Aws\S3\S3Client;
use Aws\S3\MultipartUploader;
use Aws\Exception\MultipartUploadException;

$s3 = new S3Client([
    'region'  => 'ap-northeast-1',
    'version' => 'latest',
]);

$uploader = new MultipartUploader($s3, '/path/to/large-file.mp4', [
    'bucket'          => 'your-bucket-name',
    'key'             => 'uploads/' . basename('/path/to/large-file.mp4'),
    'before_initiate' => function (\Aws\Command $command) {
        // アップロード開始前のフック
    },
    'before_upload'   => function (\Aws\Command $command) {
        // 各パートアップロード前のフック(プログレス表示など)
    },
    'concurrency'     => 5,    // 並列アップロード数
    'part_size'       => 10 * 1024 * 1024, // 1パート = 10 MiB
]);

try {
    $result = $uploader->upload();
    echo 'アップロード完了: ' . $result['ObjectURL'];
} catch (MultipartUploadException $e) {
    // 失敗したパートから再開する例
    $uploader = new MultipartUploader($s3, '/path/to/large-file.mp4', [
        'state' => $e->getState(),
    ]);
    $result = $uploader->upload();
}

Presigned URL を発行して、クライアントから直接 S3 にアップロードさせる方法はこちらです。

use Aws\S3\S3Client;

$s3 = new S3Client([
    'region'  => 'ap-northeast-1',
    'version' => 'latest',
]);

// 署名付きURLを生成(有効期限: 15分)
$cmd = $s3->getCommand('PutObject', [
    'Bucket'       => 'your-bucket-name',
    'Key'          => 'uploads/' . uniqid('', true) . '.jpg',
    'ContentType'  => 'image/jpeg',
]);

$request = $s3->createPresignedRequest($cmd, '+15 minutes');
$presignedUrl = (string) $request->getUri();

// このURLをクライアントに返す
// クライアントはこのURLに PUT リクエストでファイルを直接送信する
echo json_encode(['upload_url' => $presignedUrl]);

アーキテクチャ選択のガイドライン

  • 〜10 MB:API Gateway → Lambda → S3 でシンプルに実装可能
  • 10 MB〜100 MB:Presigned URL でクライアントから S3 に直接アップロードを推奨
  • 100 MB〜5 GB:Presigned URL + マルチパートアップロードで安定した転送を実現
  • 5 GB 超:マルチパートアップロード必須(PUT 単体では不可)

DevLab のしきい値ファイルを使ったテスト手順

実際に S3 のアップロード設定を検証するには、正確なサイズのテストファイルが必要です。DevLab の境界値テスト用ファイルを使うと、特定のサイズ前後の動作を効率よく確認できます。

  1. DevLab の 境界値テスト用ファイル一覧 からテストしたいサイズのファイルをダウンロードします。
  2. マルチパート切替ラインを検証する場合は PNG テスト画像 の大サイズ版も活用できます。
  3. ダウンロードしたファイルを aws s3 cp コマンドまたは SDK の PutObject / MultipartUploader でアップロードし、上限前後のファイルでの成功・失敗を確認します。

この記事で使えるテストファイル

よくある質問

S3の1回のPUTリクエストでアップロードできる最大サイズは?

単一のPUT操作では最大5GBまでです。それ以上はマルチパートアップロードを使い、最大5TBまで対応できます。

S3の署名付きURL(Presigned URL)の有効期限は?

デフォルトは15分で、最大7日間(604800秒)まで設定可能です。IAMユーザーの認証情報で生成した場合の上限です。

CloudFrontを経由するとアップロードサイズ制限はどうなる?

CloudFrontのリクエストbodyサイズ上限はデフォルトでGETが0、POST/PUTが最大20MBです。大容量ファイルはS3に直接アップロードする設計が推奨されます。

📚 関連記事

PNG vs WebP vs AVIF|画像フォーマットの選び方と変換方法

PNG / JPEG / WebP / AVIF の特徴・用途・ブラウザ対応状況を比較。picture 要素での出し分け、DevLab の画像フォーマット変換ツールの使い方も解説。

2026-04-18

Whois でドメイン情報を調べる方法|有効期限・ネームサーバー・登録者

Whois でわかること (登録者・有効期限・レジストラ・NS)、GDPR によるプライバシー保護の影響、ドメイン管理の実務的な使い方を解説。

2026-04-18

HTTP ステータスコード完全ガイド|よくあるエラーの原因と対処法

開発者が頻出する HTTP ステータスコード (200/301/302/400/401/403/404/413/422/429/500/502/503/504) の意味・原因・対処法を解説。301 vs 302 の SEO 影響、400 vs 422 の使い分けも。

2026-04-18

cURL コマンドを JavaScript fetch・Python requests に変換する方法|DevTools 連携

Chrome DevTools の Copy as cURL を fetch / axios / Python requests / PHP cURL / Go net/http に変換する手順を解説。主要 cURL オプション (-X / -H / -d / -F / -u / -b / -L) の変換パターン、認証トークンの扱い、注意点まで。

2026-04-16

Cookie のセキュリティフラグ完全ガイド|Secure / HttpOnly / SameSite / __Host-

Cookie のセキュリティ属性 Secure / HttpOnly / SameSite (Strict/Lax/None) / __Host- __Secure- プレフィックス / 4096 バイト制限を解説。CSRF / XSS / セッションハイジャック対策と、Laravel / Express の実装例。

2026-04-16

JWT のセキュリティベストプラクティス|alg none 攻撃 / 有効期限 / 署名検証

JWT (JSON Web Token) の代表的な脆弱性 6 種類 (alg none 攻撃 / 鍵混同 / 無期限トークン / payload への機密情報 / 失効不可 / 弱いシークレット) と対策。リフレッシュトークンパターン、失効リスト、HttpOnly Cookie 格納まで。

2026-04-16