- AWS
Task timed out afterの直し方|Lambdaタイムアウト原因別
Task timed out after 3.00 seconds は、Lambda 関数が「タイムアウト」の設定時間を使い切ったときのメッセージです。 関数を作ったときの既定値は 3 秒で、最大 900 秒(15分)まで延ばせます。
ただし、時間を延ばすだけでは直らないことが多いエラーです。 多くは「何かを待ち続けている」ことが原因で、待つ相手によって直し方が違います。
| 原因 | 見分けるヒント | 直し方 |
|---|---|---|
| VPC 内から外(インターネット・AWS の API)へ出られない | VPC に入れた直後から毎回。外部への呼び出しで止まる | NAT ゲートウェイか VPC エンドポイントを用意する |
| 外部 API・DB の応答待ち | ときどき起きる。止まる行が呼び出しの行 | SDK・HTTP のタイムアウトを関数より短く設定する |
| メモリ(=CPU)が小さく、処理が遅い | REPORT 行の Duration がいつも上限近く |
メモリを増やす(CPU も比例して増える) |
| 初期化(import・接続)が遅い | INIT_REPORT … Status: timeout、Init Duration が大きい |
初期化を軽くする、タイムアウト・メモリを増やす |
| API Gateway の統合タイムアウト | 呼び出し側は 504 Endpoint request timed out、Lambda のログに Task timed out が無い |
REST は 29 秒が既定。非同期にする |
| SQS の可視性タイムアウトとの関係 | 同じメッセージが何度も処理される | 可視性タイムアウトを関数のタイムアウトの 6 倍以上に |
確認環境:Python 3.11・boto3 1.43.111・requests 2.34.2(Linux)。外へ出られない状態は、iptables で通信を捨てる宛先を作って再現し、接続できてから応答しない状態は、何も返さないサーバーで再現しました。context.get_remaining_time_in_millis() で打ち切るコードは、AWS が公開しているランタイムクライアント awslambdaric 4.2.0 を手元で動かして確かめました。Lambda・API Gateway・SQS の上限値と既定値は、AWS のドキュメントで確認しています(確認日 2026年10月12日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Task timed out afterの直し方|Lambdaタイムアウト原因別」
まずログを読む:Task timed out と REPORT 行
CloudWatch Logs のロググループ /aws/lambda/関数名 に、次のように出ます(AWS のドキュメントの例)。
2024-04-11T17:22:20.857Z abe12jlc-640a-8157-0249-9be825c2y110 Task timed out after 3.01 seconds
REPORT RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Duration: 3016.78 ms Billed Duration: 3101 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 84.00 ms Status: timeout
REPORT 行は、1回の呼び出しごとに出る「結果のまとめ」です。 項目の意味と、タイムアウトの切り分けでの見方です。
| 項目 | 意味(ドキュメントより) | 切り分けでの見方 |
|---|---|---|
Duration |
ハンドラが処理にかけた時間 | タイムアウトの設定値とほぼ同じなら、時間切れ |
Billed Duration |
課金された時間 | — |
Memory Size |
設定したメモリ | 128 MB は既定値で最小 |
Max Memory Used |
使ったメモリの最大 | Memory Size に近いなら、メモリ不足も疑う |
Init Duration |
最初の呼び出しで、ハンドラの外のコードを動かした時間 | 数秒あるなら初期化が遅い |
Status: timeout |
タイムアウトで終わった | この行が出たら時間切れが確定 |
Duration がタイムアウトの設定値に張り付き、Max Memory Used が小さいときは、CPU を使っていない=「何かを待っている」状態です。 計算が重いのか、待っているのかを、まずここで分けます。
AWS CLI で、タイムアウトの行だけを見る例です。
aws logs tail /aws/lambda/my-function --since 1h --filter-pattern "Task timed out"
CloudWatch Logs Insights では、REPORT 行の値を集計できます。
filter @type = "REPORT"
| stats count() as calls, max(@duration) as maxMs, avg(@duration) as avgMs,
max(@maxMemoryUsed / 1000 / 1000) as maxMemMB, max(@initDuration) as maxInitMs
by bin(1h)
ログの検索全般は、関連記事「CloudWatch LogsのAWS CLI tail・検索・クエリ例」で扱っています。
どこで止まっているかを出す
止まっている行が分からないときは、呼び出しの前後でログを出し、残り時間も一緒に書きます。
import json
def log(step, context):
print(json.dumps({"step": step, "left_ms": context.get_remaining_time_in_millis()}))
def lambda_handler(event, context):
log("start", context)
item = table.get_item(Key={"id": event["id"]}) # DynamoDB
log("after dynamodb", context)
res = http.get("https://api.example.com/x", timeout=(3.05, 10))
log("after external api", context)
return {"ok": True}
最後に出た step の次の行が、止まっている場所です。
原因① VPC 内から外へ出られない
Lambda を VPC に入れると、そのままではインターネットにも、S3 や DynamoDB などの AWS の API にも出られなくなります。 ドキュメントには「パブリックサブネットに接続しても、インターネットにはアクセスできない」とあり、外に出られないときの例として Task timed out after 3.01 seconds が載っています。
接続先から「拒否」が返るわけではなく、パケットが捨てられるので、エラーにならずに待ち続けます。 これがタイムアウトになる理由です。
| 呼びたい相手 | 必要なもの |
|---|---|
| インターネット(外部 API) | プライベートサブネット+NAT ゲートウェイ(NAT はパブリックサブネットに置く) |
| S3・DynamoDB | ゲートウェイ型の VPC エンドポイント(料金なし)か NAT |
| Secrets Manager・SQS・SNS など | インターフェース型の VPC エンドポイントか NAT |
| VPC 内の RDS など | セキュリティグループで、Lambda からのポートを許可する |
ドキュメントの構成は、Lambda をプライベートサブネットに置き、0.0.0.0/0 の行き先を NAT ゲートウェイにする形です。VPC に入れる必要がない関数なら、VPC から外すのが一番簡単な直し方です。
VPC・サブネット・ルートの作り方は、関連記事「AWS CLIでVPCを作成する手順|サブネットからIGWまで一式」で扱っています。
届かない宛先で、何秒待つかを実測した
iptables で、パケットを捨てる宛先(198.51.100.7)を作り、VPC から外へ出られない状態を再現しました。タイムアウトを指定しないと、boto3 は約5分、requests は約2分待ちました。
| クライアント・設定 | 結果 | かかった時間 |
|---|---|---|
| boto3(既定:接続 60 秒・legacy で計5回) | ConnectTimeoutError |
309.06 秒 |
requests(timeout なし) |
ConnectTimeout |
133.93 秒(OS の SYN 再送の上限) |
Python の socket.create_connection(指定なし) |
TimeoutError: [Errno 110] |
133.71 秒 |
requests(timeout=(3.05, 10)) |
ConnectTimeout |
3.06 秒 |
boto3 Config(connect_timeout=2, retries={"total_max_attempts": 1}) |
ConnectTimeoutError |
2.02 秒 |
boto3 Config(connect_timeout=2, retries={"mode": "standard"})(計3回) |
ConnectTimeoutError |
6.98〜8.82 秒 |
boto3 Config(connect_timeout=2)(legacy で計5回) |
ConnectTimeoutError |
18.15〜20.74 秒 |
boto3 の既定のまま VPC から S3 を呼ぶと、関数のタイムアウトを3秒から延ばしても、300 秒までは延ばしても足りません。 時間がばらつくのは、再試行の間の待ち時間(バックオフ)にランダムな幅があるためです。
手元の Linux の net.ipv4.tcp_syn_retries は 6 でした。requests でタイムアウトを指定しないと、この OS の設定で決まる時間まで待ちます。
原因② 外部 API・DB の応答待ち
接続はできたのに、相手が応答を返さない状態です。何も返さないサーバーを手元に立てて測りました。
| クライアント・設定 | 結果 | かかった時間 |
|---|---|---|
| boto3(既定:読み取り 60 秒・計5回) | ReadTimeoutError |
314.18 秒 |
boto3 Config(read_timeout=3, retries={"total_max_attempts": 1}) |
ReadTimeoutError |
3.01 秒 |
boto3 Config(read_timeout=3, retries={"mode": "standard"})(計3回) |
ReadTimeoutError |
10.76 秒 |
requests(timeout=(3.05, 5)) |
ReadTimeout |
5.04 秒 |
requests(timeout なし) |
120 秒たっても戻らなかった | — |
requests は、timeout を指定しないと、応答が来るまで待ち続けます。 requests のドキュメントにも、本番のコードでは timeout を付けるよう書かれています。
boto3(botocore)のタイムアウト設定
Config の項目 |
既定値 | 意味 |
|---|---|---|
connect_timeout |
60 秒 | 接続できるまで待つ時間 |
read_timeout |
60 秒 | 接続後、データが届くまで待つ時間 |
retries の mode |
legacy |
standard・adaptive も選べる |
retries の total_max_attempts |
legacy は 5、standard は 3 | 最初の1回を含む回数 |
max_pool_connections |
10 | 接続を使い回す数 |
最悪の待ち時間は、おおよそ「(接続+読み取りのタイムアウト)× 回数+再試行の間の待ち」です。 これが関数のタイムアウトより短くなるように決めます。
import boto3
from botocore.config import Config
# 関数のタイムアウトが 10 秒の例:最悪でも (2 + 3) × 2回 + 待ち で 10 秒を切るように
CFG = Config(
connect_timeout=2,
read_timeout=3,
retries={"total_max_attempts": 2, "mode": "standard"},
)
s3 = boto3.client("s3", config=CFG) # クライアントはハンドラの外で1回作る
dynamodb = boto3.resource("dynamodb", config=CFG)
boto3 のドキュメントでは、max_attempts は最初の1回を含まず、total_max_attempts は含みます。total_max_attempts を使うよう勧められています。再試行される例外の一覧は、関連記事「boto3のエラーハンドリング|ClientErrorのコード取得とリトライ設定」で扱っています。
requests のタイムアウト設定
import requests
# (接続のタイムアウト, 読み取りのタイムアウト)
res = requests.get("https://api.example.com/items", timeout=(3.05, 10))
timeout=10 のように1つの数字だと、接続と読み取りの両方に 10 秒が使われます。 読み取りのタイムアウトは「データが途切れている時間」の上限で、ダウンロード全体の時間の上限ではありません。
requests の再試行やエラー処理は、関連記事「Pythonのrequestsの使い方|タイムアウト・エラー処理・再試行まで」で扱っています。値の決め方は、関連記事「タイムアウト設計の値の決め方|接続・読み取りの違いと多段の計算例」で扱っています。
DB(RDS など)の場合
DB のドライバにも接続のタイムアウトがあります。例えば PyMySQL は connect_timeout、psycopg は connect_timeout(接続文字列)で指定します。接続はハンドラの外で作って使い回すと、呼び出しのたびの接続待ちが減ります。 同時実行が増えると DB の接続数が足りなくなることがあり、ドキュメントでは RDS Proxy が案内されています。
時間切れの前に処理を打ち切るコード
context.get_remaining_time_in_millis() は、タイムアウトまでの残りミリ秒を返します。 残りが少なくなったら、自分で処理を止めて結果を返せば、Task timed out にならずに済みます。
次のコードは、SQS から受け取ったメッセージを1件ずつ処理し、残り1秒を切ったら、残りのメッセージを「失敗」として SQS に戻します(SQS のイベントソースで ReportBatchItemFailures を有効にした場合の返し方)。
import json
import time
SAFETY_MS = 1_000 # 時間切れの何ミリ秒前に打ち切るか
def process(record):
time.sleep(0.4) # 1件あたりの処理(外部APIやDBの代わり)
def lambda_handler(event, context):
records = event["Records"]
failures = []
for i, record in enumerate(records):
left = context.get_remaining_time_in_millis()
if left < SAFETY_MS:
# 残りは処理せず、失敗として SQS に戻す(ReportBatchItemFailures)
failures = [{"itemIdentifier": r["messageId"]} for r in records[i:]]
print(json.dumps({"msg": "stop before timeout", "done": i, "left_ms": left}))
break
process(record)
return {"batchItemFailures": failures}
ランタイムクライアント awslambdaric で、持ち時間を 3 秒にして 10 件を渡しました。5 件を処理したところで残りが 980 ミリ秒になり、2.02 秒で結果を返しました。
{"msg": "stop before timeout", "done": 5, "left_ms": 980}
{"batchItemFailures": [{"itemIdentifier": "m6"}, {"itemIdentifier": "m7"}, {"itemIdentifier": "m8"}, {"itemIdentifier": "m9"}, {"itemIdentifier": "m10"}]}
SDK のタイムアウトと組み合わせる
1回の呼び出しが長く止まると、ループの途中で残り時間を確かめても間に合いません。SDK のタイムアウトを短くしておくことと、残り時間で止めることは、両方そろって効きます。
import json
import boto3
from botocore.config import Config
from botocore.exceptions import ConnectTimeoutError, ReadTimeoutError, EndpointConnectionError
CFG = Config(connect_timeout=2, read_timeout=3, retries={"total_max_attempts": 2, "mode": "standard"})
s3 = boto3.client("s3", config=CFG)
def lambda_handler(event, context):
print(json.dumps({"start_left_ms": context.get_remaining_time_in_millis()}))
try:
s3.list_buckets()
return {"ok": True}
except (ConnectTimeoutError, ReadTimeoutError, EndpointConnectionError) as e:
print(json.dumps({"error": type(e).__name__, "left_ms": context.get_remaining_time_in_millis()}))
raise
S3 の宛先を届かないアドレスに向けて、持ち時間 15 秒で動かした結果です。
| 書き方 | 結果 |
|---|---|
上の Config あり |
4.62 秒で ConnectTimeoutError を返した(残り 10,387 ミリ秒) |
Config なし(既定) |
45 秒たっても戻らなかった(実際の Lambda なら Task timed out) |
Task timed out は「どこで止まったか」が出ませんが、自分のコードで例外を出せば、エラーの種類と行がログに残ります。 原因の特定が速くなります。
ハンドラの書き方や、ランタイムクライアントでのローカルテストは、関連記事「AWS Lambda Python入門|3.14対応handler例とローカルテスト」で扱っています。
原因③ メモリが小さく、処理が遅い
Lambda の CPU は、メモリの設定に比例して割り当てられます。 ドキュメントでは、メモリは 128 MB〜10,240 MB(1 MB 単位)、既定は 128 MB、1,769 MB で 1 vCPU 相当とされています。
画像処理・圧縮・大きな JSON の解析など、CPU を使う処理では、メモリを増やすと Duration が短くなります。Max Memory Used が小さくても、CPU のためにメモリを増やす意味があります。
aws lambda update-function-configuration --function-name my-function \
--memory-size 1024 --timeout 30
原因④ 初期化(INIT)が遅い
ハンドラの外のコード(import・クライアントの作成・設定の読み込み)は「Init フェーズ」で動きます。 ドキュメントでは、Init フェーズは 10 秒までで、超えると、最初の呼び出しのときに、関数のタイムアウトの中で Init をやり直すとされています(suppressed init)。
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: timeout
タイムアウトが 3 秒前後と短いと、やり直しの Init だけで時間を使い切り、Task timed out after 3.00 seconds になることがあります。ドキュメントの対策は、タイムアウトを延ばす・メモリを増やす・初期化のコードを軽くする、の3つです。
| 初期化が遅くなる例 | 対策 |
|---|---|
| 大きなライブラリ(pandas など)の import | 使う関数の中で import する/レイヤーを見直す |
| ハンドラの外で外部に接続し、VPC から出られない | 原因①と同じ。初期化の段階で止まる |
| 設定・シークレットを毎回 API で取る | 1回取ったら、グローバル変数に入れて使い回す |
原因⑤ API Gateway の統合タイムアウト
API Gateway から Lambda を呼ぶと、Lambda のタイムアウトとは別に、API Gateway の待ち時間の上限があります。 これを超えると、呼び出し側には 504 Endpoint request timed out が返ります。
| 種類 | 統合タイムアウト(ドキュメントの値) | 引き上げ |
|---|---|---|
| REST API(リージョン・プライベート) | 50 ミリ秒〜29 秒 | 可能(Service Quotas。リージョンのスロットリングの上限が下がる場合がある) |
| REST API(エッジ最適化) | 50 ミリ秒〜29 秒 | 不可 |
| HTTP API | 最大 30 秒 | 不可 |
Lambda のタイムアウトを 60 秒にしても、REST API の既定では 29 秒で 504 になります。 長い処理は、API では受け付けだけをして(SQS に入れる・Step Functions を起動する)、結果は別に取りに行く形にします。
| 呼び出し側に見えるもの | Lambda のログ | 意味 |
|---|---|---|
504 Endpoint request timed out |
Task timed out が無い |
API Gateway が先に時間切れ |
| 502 など | Task timed out がある |
Lambda が先に時間切れ |
原因⑥ SQS の可視性タイムアウトとの関係
SQS から Lambda を動かすとき、メッセージは処理中「見えない」状態になり、その時間が可視性タイムアウトです。 関数が終わる前に可視性タイムアウトが切れると、同じメッセージがまた配られ、二重に処理されます。
ドキュメントの決まりと推奨です。
| 項目 | 内容 |
|---|---|
| 必須 | 関数のタイムアウト ≦ キューの可視性タイムアウト。超えるとイベントソースマッピングの作成・更新でエラー |
| 推奨 | 可視性タイムアウトを、関数のタイムアウトの 6 倍以上(バッチウィンドウを使うなら、その秒数も足す) |
| 例 | 関数 30 秒・バッチウィンドウ 0 秒 → 可視性タイムアウト 180 秒以上 |
aws sqs set-queue-attributes --queue-url "$QUEUE_URL" \
--attributes VisibilityTimeout=180
関数がタイムアウトすると、そのバッチのメッセージは可視性タイムアウトのあとに再び配られます。 何度もタイムアウトするなら、デッドレターキュー(DLQ)に送る回数(maxReceiveCount)も決めておきます。上の「打ち切るコード」で、処理できなかった分だけを戻すと、処理済みの分は二重に動きません。
可視性タイムアウトの仕組みは、関連記事「Amazon SQSの使い方|送受信・削除と可視性タイムアウト、FIFO」で扱っています。
タイムアウトの上限値・既定値の早見表
| 項目 | 値(ドキュメント) |
|---|---|
| Lambda のタイムアウト | 既定 3 秒、1 秒単位で最大 900 秒(15分) |
| Lambda の Init フェーズ | 10 秒(プロビジョニングされた同時実行・SnapStart などは別) |
| Lambda のメモリ | 128 MB(既定)〜10,240 MB |
| API Gateway REST API の統合タイムアウト | 50 ミリ秒〜29 秒(リージョン・プライベートは引き上げ可) |
| API Gateway HTTP API の統合タイムアウト | 30 秒(引き上げ不可) |
| SQS の可視性タイムアウト(推奨) | 関数のタイムアウトの 6 倍以上 |
| boto3 の接続・読み取りのタイムアウト | 各 60 秒 |
| boto3 の試行回数 | legacy(既定)5 回、standard 3 回(最初の1回を含む) |
タイムアウトの変更は、次のコマンドです(ドキュメントの例)。
aws lambda update-function-configuration --function-name my-function --timeout 120
よくある質問
Q. タイムアウトを 900 秒にしておけば安全ですか。 A. 待ち続けている原因があると、900 秒まで課金されたうえでタイムアウトします。ドキュメントでも、タイムアウトを平均の実行時間に近い値にするとタイムアウトしやすい、とされています。目安は「普段の最大の実行時間+余裕」で、外部呼び出しには SDK 側のタイムアウトを付けます。
Q. ローカルでは速いのに、Lambda だけタイムアウトします。
A. ローカルは CPU が多く、ネットワークにも出られます。Lambda では、128 MB だと CPU が少なく(原因③)、VPC に入れると外に出られません(原因①)。REPORT 行の Duration と Max Memory Used を見て分けます。
Q. タイムアウトした呼び出しは再試行されますか。 A. 非同期呼び出し(S3 のイベント通知など)は、Lambda が再試行します。ドキュメントでは、既定で最大 2 回の再試行です。同じイベントが2回以上処理されても困らない作り(冪等性)にしておきます。
Q. タイムアウトのときに /tmp のファイルは消えますか。
A. ドキュメントでは、タイムアウトなどで実行環境がリセットされても、/tmp は次の Init の前に消されないとされています。途中まで書いたファイルが残る前提で作ります。
関連する Lambda のエラーとして、読み込みの段階で失敗するものは、関連記事「Lambda Unable to import moduleの直し方|Python」で扱っています。
まとめ
Task timed out afterは設定時間の使い切り。既定 3 秒・最大 900 秒。延ばす前に「何を待っているか」を見る- REPORT 行で、
Durationが上限に張り付きMax Memory Usedが小さいなら「待ち」 - VPC から外へ出られないと、boto3 の既定では 約 309 秒待った。NAT か VPC エンドポイント
- boto3 は
Config(connect_timeout, read_timeout, retries)、requests はtimeout=(接続, 読み取り)を関数のタイムアウトより短く context.get_remaining_time_in_millis()で、時間切れの前に自分で止めて結果を返す- API Gateway の REST は 29 秒、HTTP API は 30 秒。SQS の可視性タイムアウトは関数の 6 倍以上
参考・出典
確認日はいずれも 2026年10月12日です。
- AWS Lambda デベロッパーガイド「Configure Lambda function timeout」:https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html
- AWS Lambda デベロッパーガイド「Configure Lambda function memory」:https://docs.aws.amazon.com/lambda/latest/dg/configuration-memory.html
- AWS Lambda デベロッパーガイド「Understanding the Lambda execution environment lifecycle」:https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html
- AWS Lambda デベロッパーガイド「Troubleshoot invocation issues in Lambda」:https://docs.aws.amazon.com/lambda/latest/dg/troubleshooting-invocation.html
- AWS Lambda デベロッパーガイド「Enable internet access for VPC-connected Lambda functions」:https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc-internet.html
- AWS Lambda デベロッパーガイド「Log and monitor Python Lambda functions」(REPORT 行の項目):https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html
- AWS Lambda デベロッパーガイド「Creating and configuring an Amazon SQS event source mapping」:https://docs.aws.amazon.com/lambda/latest/dg/services-sqs-configure.html
- Amazon API Gateway デベロッパーガイド「Quotas for configuring and running a REST API」:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-execution-service-limits-table.html
- Amazon API Gateway デベロッパーガイド「Quotas for HTTP APIs」:https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-quotas.html
- Boto3 ドキュメント「Retries」:https://docs.aws.amazon.com/boto3/latest/guide/retries.html
- awslambdaric(AWS Lambda Runtime Interface Client for Python)4.2.0:https://pypi.org/project/awslambdaric/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Task timed out afterの直し方|Lambdaタイムアウト原因別」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。