Lambda の S3 Files でダイレクトリードを設定できるようになったので効果を測ってみた
はじめに
2026年9月11日、AWS Lambda の S3 Files マウントで読み取り経路を指定できる DirectS3Read がサポートされました。
東京リージョンを含む商用リージョンで利用でき、追加費用はかかりません。
これまで、メモリ 512MB 以上の関数では S3 バケットからの直接読み取りが既定で有効でした。今回のアップデートで、メモリサイズに依存せず、利用者側で有効・無効を選択できるようになりました。
本記事では、メモリ 256MB と 3072MB の関数で、既定と逆の設定にしたときの読み取り性能の変化を確認しました。
検証内容
メモリ 256MB の関数では 100MB のファイルを、メモリ 3072MB の関数では 500MB のファイルを使い、それぞれ ENABLED と DISABLED で読み比べました。どちらのファイルも 1MB を超えるため、ENABLED では直接読みの対象になります。読み方はファイルを1本ずつ順に読む形のみで、並列読みは試していません。
検証環境
| 項目 | 値 |
|---|---|
| リージョン | ap-northeast-1 |
| ランタイム | Python 3.12 |
| メモリ | 256MB、3072MB |
| 読み取り元 | S3 Files のアクセスポイントを /mnt/s3files にマウント |
設定方法
読み取り経路は、関数のファイルシステム設定に含まれる S3FilesConfig で指定します。メモリ 256MB の関数に ENABLED を指定して作成したところ、エラーにならず、応答にも ENABLED が含まれていました。次は create-function の応答を --query '{N:FunctionName,M:MemorySize,FS:FileSystemConfigs}' で絞った結果です。
{
"N": "s3files-directread-test6",
"M": 256,
"FS": [
{
"Arn": "arn:aws:s3files:ap-northeast-1:123456789012:file-system/fs-xxxxxxxxxxxxxxxxx/access-point/fsap-xxxxxxxxxxxxxxxxx",
"LocalMountPath": "/mnt/s3files",
"S3FilesConfig": {
"DirectS3Read": "ENABLED"
}
}
]
}
既定で直接読みの対象になる関数について、What's New では次のように説明されています。
By default, Lambda supports direct reads from your S3 bucket only for functions configured with 512 MB of memory or higher.
512MB 未満の既定は本記事の DISABLED 側、512MB 以上の既定は ENABLED 側と同じ経路です。直接読みの対象となるファイルサイズについては、次のように説明されています。
When you enable direct read, your function reads files 1 MB or larger directly from your S3 bucket for maximum throughput, and smaller files are served through the high-performance storage. When you disable it, all reads are served through the high-performance storage for the lowest latency.
有効にしても 1MB 未満のファイルは高性能ストレージ経由で読まれます。そのため、読むファイルが 1MB 未満に収まる関数では、どちらを指定しても経路は変わりません。
次の折りたたみは、測定に使った関数コードと作成コマンドです。
関数コードと作成コマンド
読み取りにかかった時間とスループットを返すハンドラです。呼び出し時に chunk_mb として 128 を渡しているため、100MB や 500MB のファイルでも最初の read() で全量が返り、一括読みになります。
import time
import os
MOUNT = '/mnt/s3files'
def read_chunked(path, chunk_bytes):
total = 0
with open(path, 'rb') as f:
while True:
b = f.read(chunk_bytes)
if not b:
break
total += len(b)
return total
def lambda_handler(event, context):
name = event.get('file', '500m_1.bin')
chunk_mb = int(event.get('chunk_mb', 8))
path = os.path.join(MOUNT, name)
start = time.perf_counter()
total = read_chunked(path, chunk_mb * 1024 * 1024)
elapsed = time.perf_counter() - start
size_mb = total / 1024 / 1024
return {
'file': name,
'size_mb': round(size_mb, 3),
'chunk_mb': chunk_mb,
'elapsed_sec': round(elapsed, 4),
'throughput_mbps': round(size_mb / elapsed, 2) if elapsed > 0 else 0,
'memory_mb': int(context.memory_limit_in_mb),
}
上記のコードを lambda_function.py として ZIP ファイル fn.zip にまとめ、その ZIP を指定して関数を作成しました。
aws lambda create-function --function-name s3files-directread-test6 \
--runtime python3.12 \
--role arn:aws:iam::123456789012:role/example-role \
--handler lambda_function.lambda_handler \
--zip-file fileb://fn.zip \
--memory-size 256 --timeout 300 \
--vpc-config "SubnetIds=subnet-xxxxxxxxxxxxxxxxx1,subnet-xxxxxxxxxxxxxxxxx2,subnet-xxxxxxxxxxxxxxxxx3,SecurityGroupIds=sg-xxxxxxxxxxxxxxxxx" \
--file-system-configs "Arn=$AP_ARN,LocalMountPath=/mnt/s3files,S3FilesConfig={DirectS3Read=ENABLED}"
既存の関数に対して設定を更新し、更新後の値を取得して反映を確認しました。
aws lambda update-function-configuration --function-name s3files-directread-test6 \
--file-system-configs "Arn=$AP_ARN,LocalMountPath=/mnt/s3files,S3FilesConfig={DirectS3Read=DISABLED}"
aws lambda wait function-updated-v2 --function-name s3files-directread-test6
aws lambda get-function-configuration --function-name s3files-directread-test6 \
--query 'FileSystemConfigs[0].S3FilesConfig.DirectS3Read' --output text
設定を更新した直後の1回目は、後述する 256MB の4ブロックすべてで、同じブロックの中央値より遅くなりました。1ブロック目では1回目が 6.21 秒、中央値が 3.81 秒でした。そのため、各ブロックの1回目はウォームアップとして集計から除きました。
メモリ 256MB
100MB のファイルを読みました。100MB は 256MB のメモリに収まるため、チャンクに分けず一括で読んでいます。高性能ストレージ側に残ったファイルを読む回が混ざらないよう、毎回未読のファイルを使いました。ブロック順序の影響を打ち消すため、ENABLED → DISABLED → DISABLED → ENABLED の4ブロック(各ブロック5回)で測定しました。
| 設定 | ブロック別中央値 | 合算中央値(n=10) | スループット | レンジ |
|---|---|---|---|---|
| ENABLED | 3.812 / 3.871 秒 | 3.839 秒 | 26.06 MB/s | 3.711–3.962 秒 |
| DISABLED | 2.619 / 2.728 秒 | 2.677 秒 | 37.36 MB/s | 2.580–2.747 秒 |
DISABLED が中央値で 43.4% 速い結果でした。DISABLED の最も遅い回(2.747 秒)が ENABLED の最も速い回(3.711 秒)を下回っており、20回を通じて分布が重なっていません。メモリ 256MB では、直接読みを有効にすると遅くなりました。
100MB を読んだ生レスポンス(ENABLED / DISABLED)
各ブロックの1回目(ウォームアップ)は除いてあります。以下は集計対象の5回です。
--- ブロック A1: 100MB 一括読み × ENABLED (256MB / 毎回未読ファイル) ---
設定確認: DirectS3Read=ENABLED
A1-1 file=100m_2.bin: {"file": "100m_2.bin", "size_mb": 100.0, "chunk_mb": 128, "elapsed_sec": 3.8709, "throughput_mbps": 25.83, "memory_mb": 256}
A1-2 file=100m_3.bin: {"elapsed_sec": 3.7113, "throughput_mbps": 26.94, "memory_mb": 256}
A1-3 file=100m_4.bin: {"elapsed_sec": 3.8121, "throughput_mbps": 26.23, "memory_mb": 256}
A1-4 file=100m_5.bin: {"elapsed_sec": 3.8356, "throughput_mbps": 26.07, "memory_mb": 256}
A1-5 file=100m_6.bin: {"elapsed_sec": 3.8085, "throughput_mbps": 26.26, "memory_mb": 256}
--- ブロック A2: 100MB 一括読み × DISABLED (256MB / 毎回未読ファイル) ---
設定確認: DirectS3Read=DISABLED
A2-1 file=100m_8.bin: {"elapsed_sec": 2.5796, "throughput_mbps": 38.77, "memory_mb": 256}
A2-2 file=100m_9.bin: {"elapsed_sec": 2.7359, "throughput_mbps": 36.55, "memory_mb": 256}
A2-3 file=100m_10.bin: {"elapsed_sec": 2.6188, "throughput_mbps": 38.19, "memory_mb": 256}
A2-4 file=100m_11.bin: {"elapsed_sec": 2.6571, "throughput_mbps": 37.63, "memory_mb": 256}
A2-5 file=100m_12.bin: {"elapsed_sec": 2.5802, "throughput_mbps": 38.76, "memory_mb": 256}
メモリ 3072MB
従来から既定で直接読みが有効になる 512MB 以上の関数でも試しました。500MB のファイル10本をローテーションして一括で読みました。測定は ENABLED、DISABLED の順に行い、各設定でウォームアップ1回のあと、5回測りました。DISABLED の最後の2回は、ENABLED で読んだファイルの再読になっています。
| 設定 | elapsed 中央値 | スループット中央値 |
|---|---|---|
| ENABLED | 12.10 秒 | 41.33 MB/s |
| DISABLED | 13.37 秒 | 37.40 MB/s |
こちらは ENABLED が 10.5% 速く、256MB とは逆の結果になりました。ただし各設定 n=5 で、順序を入れ替えた再測定も行っていないため、256MB の測定ほど明確な差とはいえません。
どちらのメモリでも、速かったのは既定で選ばれる側でした。256MB の既定は高性能ストレージ経由、3072MB の既定は直接読みです。
まとめ
今回のアップデートで、S3 Files の読み取り経路を関数ごとに指定できるようになりました。512MB 未満の関数でも直接読みを明示できます。ただし今回の条件では、速かったのはどちらのメモリでも既定の側で、既定を変えるメリットは確認できませんでした。並列読みなど読み取り方が異なれば結果が変わる可能性はあります。
逆向きの使い方もあります。無効にするとすべての読み取りが高性能ストレージ経由になり、レイテンシが最小になると説明されています。512MB 以上の関数で 1MB 以上のファイルを読む場合でも、スループットよりレイテンシを優先したいなら、あえて無効にする選択も可能になりました。
S3 Files の読み取り性能を調整する際は、まずメモリサイズを決めたうえで、実際のワークロードで読み取り経路を変える効果も確認することをおすすめします。









