Sửa lỗi AWS Lambda "Task timed out after 3.00 seconds"

intermediate☁️ AWS2026-03-17| AWS Lambda (mọi runtime: Node.js, Python, Java, Go) — AWS Console / AWS CLI / Serverless Framework

Error Message

Task timed out after 3.00 seconds
#aws#lambda#timeout#function

Lỗi xảy ra

Log Lambda function của bạn hiển thị:

Task timed out after 3.00 seconds

Lambda đã buộc dừng function trước khi nó chạy xong. Timeout mặc định 3 giây hoạt động ổn với một function hello-world đơn giản. Nhưng chỉ cần thêm một lời gọi HTTP đến API bên thứ ba hoặc một truy vấn database dưới tải cao, 3 giây sẽ biến mất nhanh chóng.

Nguyên nhân gốc rễ

  • Timeout mặc định quá ngắn — Lambda mặc định là 3 giây. Một lời gọi API chậm duy nhất là đủ để vượt qua giới hạn đó.
  • Lời gọi mạng ra ngoài — Các request HTTP đến API bên thứ ba, RDS, hoặc DynamoDB có thể mất 1–5 giây khi tải cao, thậm chí lâu hơn.
  • Độ trễ cold start — Các runtime dựa trên JVM (Java, Kotlin) thường tốn thêm 800ms–2s trước khi code của bạn bắt đầu chạy. Các package Python lớn có thể cộng thêm 200–400ms nữa.
  • Vòng lặp vô hạn hoặc chờ đợi bị block — Một vòng lặp polling không bao giờ thoát, hoặc một lệnh time.sleep(10) ẩn đâu đó trong call stack.
  • Mạng VPC — Các function chạy trong VPC khởi động chậm hơn và sẽ bị treo trên các lời gọi ra ngoài nếu không có NAT Gateway được cấu hình.

Bước 1 — Kiểm tra Log trước tiên

Chưa cần đụng vào cấu hình. Mở CloudWatch Logs để xem thời gian đang bị tiêu tốn ở đâu.

# Xem log theo thời gian thực qua AWS CLI
aws logs tail /aws/lambda/your-function-name --follow

# Hoặc lọc các dòng REPORT để xem thời gian thực thi
aws logs filter-log-events \
  --log-group-name /aws/lambda/your-function-name \
  --filter-pattern "REPORT" \
  --query 'events[*].message' \
  --output text

Dòng REPORT cung cấp toàn bộ thông tin bạn cần:

REPORT RequestId: abc-123  Duration: 2987.43 ms  Billed Duration: 2988 ms  Memory Size: 128 MB  Max Memory Used: 67 MB  Init Duration: 412.31 ms

Init Duration trên 400ms cho thấy vấn đề cold start. Duration gần sát giới hạn timeout có nghĩa là bản thân function thực sự chậm — và tăng timeout là giải pháp đúng đắn.

Bước 2 — Tăng Timeout

Tăng timeout trước. Giá trị tối đa là 15 phút (900 giây).

Qua AWS Console

  • Vào Lambda → Function của bạn → Configuration → General configuration
  • Nhấn Edit
  • Đặt Timeout thành một giá trị hợp lý — 30 giây là điểm khởi đầu ổn cho các function thực hiện lời gọi ra ngoài
  • Nhấn Save

Qua AWS CLI

aws lambda update-function-configuration \
  --function-name your-function-name \
  --timeout 30

Qua Serverless Framework (serverless.yml)

functions:
  myFunction:
    handler: handler.main
    timeout: 30  # giây

Qua Terraform

resource "aws_lambda_function" "my_function" {
  function_name = "my-function"
  timeout       = 30
  # ... cấu hình khác
}

Quy tắc kinh nghiệm: đặt timeout bằng 2–3 lần thời gian thực thi tệ nhất dự kiến. Đừng vội đặt thẳng lên 900 — làm vậy sẽ che giấu các vấn đề hiệu năng thực sự.

Bước 3 — Thêm Log đo thời gian để xác định điểm nghẽn

Vẫn timeout ở 30 giây? Thêm instrumentation vào code để log cho bạn biết chính xác bước nào đang ngốn thời gian.

Python

import time
import logging

logger = logging.getLogger()

def handler(event, context):
    t0 = time.time()
    
    result = fetch_from_database()
    logger.info(f"Truy vấn DB mất {time.time() - t0:.2f}s")
    
    t1 = time.time()
    response = call_external_api(result)
    logger.info(f"Lời gọi API mất {time.time() - t1:.2f}s")
    
    return response

Node.js

exports.handler = async (event) => {
  console.time('db-query');
  const result = await fetchFromDatabase();
  console.timeEnd('db-query');

  console.time('api-call');
  const response = await callExternalAPI(result);
  console.timeEnd('api-call');

  return response;
};

Deploy, gọi thử một lần, rồi kiểm tra CloudWatch. Bước chậm sẽ hiện ra ngay lập tức.

Bước 4 — Tối ưu đoạn code chậm

Đặt timeout tường minh cho tất cả HTTP client

HTTP client không có timeout sẽ chờ mãi mãi. Hãy đặt timeout cho mọi lời gọi ra ngoài — không có ngoại lệ.

# Python với requests
import requests
response = requests.get('https://api.example.com/data', timeout=5)  # tối đa 5 giây

# Python với httpx (async)
async with httpx.AsyncClient(timeout=5.0) as client:
    response = await client.get('https://api.example.com/data')
// Node.js với axios
const axios = require('axios');
const response = await axios.get('https://api.example.com/data', {
  timeout: 5000  // 5 giây tính bằng ms
});

Khởi tạo SDK client bên ngoài handler

AWS SDK client được tạo bên trong handler sẽ được khởi tạo lại mỗi lần gọi. Hãy chuyển chúng ra cấp module. Lambda tái sử dụng môi trường thực thi khi warm start, nên bạn chỉ trả chi phí khởi tạo đó đúng một lần.

# Sai — tạo client mới mỗi lần gọi
def handler(event, context):
    dynamodb = boto3.client('dynamodb')
    ...

# Đúng — client được khởi tạo một lần, tái sử dụng khi warm start
import boto3
dynamodb = boto3.client('dynamodb')

def handler(event, context):
    ...

Tăng memory để có thêm CPU

CPU của Lambda tăng tuyến tính theo memory. Tăng từ 128MB lên 512MB cho bạn gấp 4 lần CPU. Với các workload nặng CPU, điều này có thể giảm thời gian thực thi xuống một nửa hoặc hơn.

aws lambda update-function-configuration \
  --function-name your-function-name \
  --memory-size 512

Chạy Lambda Power Tuning để tìm cấu hình memory cân bằng giữa tốc độ và chi phí cho function cụ thể của bạn.

Lambda trong VPC

Không có NAT Gateway, function của bạn đơn giản là không thể kết nối internet. Các lời gọi HTTP ra ngoài sẽ treo cho đến khi Lambda buộc dừng chúng. Kiểm tra route table của subnet — bạn cần một route cho 0.0.0.0/0 trỏ đến NAT Gateway (NAT Instance không đủ).

# Kiểm tra xem function có gắn với VPC không
aws lambda get-function-configuration \
  --function-name your-function-name \
  --query 'VpcConfig'

Bước 5 — Xác nhận đã sửa xong

Gọi trực tiếp function và kiểm tra kết quả trả về:

# Gọi thử đồng bộ
aws lambda invoke \
  --function-name your-function-name \
  --payload '{}' \
  --cli-binary-format raw-in-base64-out \
  output.json

cat output.json

Xem dòng REPORT trong CloudWatch. Duration thấp hơn nhiều so với giới hạn timeout là bạn đã xong:

REPORT RequestId: xyz-456  Duration: 1243.12 ms  Billed Duration: 1244 ms

Không còn Task timed out after 3.00 seconds trong log nữa. Đã sửa xong.

Bài học rút ra

  • 3 giây là mặc định của Lambda, không phải khuyến nghị. Hầu hết các function production cần 15–60 giây.
  • Đặt timeout cho mọi function thực hiện lời gọi ra ngoài — và chọn con số đó một cách có chủ đích, không phải để mặc định.
  • Cold start của Java và Kotlin thường ngốn 1–2 giây trước khi handler của bạn chạy. Nếu điều đó không chấp nhận được, hãy xem xét Provisioned Concurrency hoặc SnapStart (Java 11+).
  • Đặt timeout của HTTP client ngắn hơn timeout của Lambda. Như vậy bạn sẽ nhận được exception có thể xử lý được — thay vì phải chờ Lambda buộc dừng toàn bộ function.

Related Error Notes