本記事は TechHarmony Advent Calendar 2025 12/18付の記事です。 |
こんにちは。SCSKの野口です。
今回初めての記事投稿となりますが、私が興味を持っている分野であるAWSサービス関連・ AIエージェント関連に関する記事を投稿していく予定ですので、どうぞよろしくお願いします。
早速本題ですが、2025年10月にAWS Lambda の非同期呼び出しにおける最大ペイロードサイズが 256KB ⇒ 1MB に引き上げられました。
本記事では公式アナウンスの内容を軽く確認し、シンプルなデモで”256KBを超えてもエラーにならない”ことを試してみたいと思います。
Lambdaの非同期呼び出しとは
Lambdaの呼び出し方法には
- 同期呼び出し
- 非同期呼び出し
の2通りの呼び出し方法があります。
同期呼び出しは、リクエストを投げた後にLambda側で処理が行われるのですが、その処理が完了するまでレスポンスが返ってきません。
一方で、非同期呼び出しではリクエストを受け付けた後に処理が完了しているかにかかわらずレスポンスを返します。クライアント側はLambdaからのレスポンスを待つことなく次の処理に移ることができます。
一般的に、非同期処理のメリットは下記が挙げられます。
- 同期処理に比べ、応答時間が短い
- 耐障害性・可用性が向上する
それぞれについて、イメージを共有します。
同期処理に比べ、応答時間が短い
耐障害性・可用性が向上する
非同期処理については下記の資料がとても参考になるので、是非確認してみてください。
公式アナウンスの要点
公式アナウンスが2025年10月24日に行われています。
AWS Lambda が非同期呼び出しの最大ペイロードサイズを 256 KB から 1 MB に増加 – AWS
要点をまとめると、下記となります。
- 上限が1MBに引き上げられた対象は 非同期呼び出し(
InvocationType=Eventや、S3/SNS/EventBridge/Step Functions などのプッシュ型イベント)。 - 非同期呼び出しごとに最初の 256 KB に対して 1 リクエスト分が課金。256 KB を超える個々のペイロードサイズについては、64 KB のチャンクごとに追加で 1 リクエスト分課金(最大 1 MB まで)。
- 一般提供(GA)。商用リージョンおよびAWS GovCloud(US)で利用可能。
すでに東京リージョン(ap-northeast-1)でも1MBでの非同期呼び出しが可能となっているので、今回は東京リージョンでデモを実施します。
デモ:256KBを超えても非同期呼び出しで通るか?
それでは、本当に非同期呼び出しで1MBを超えても問題ないかを確認します。
非同期(`InvocationType=”Event”`)で約 300KB と約 900KB のペイロードサイズを持つリクエストを投げ、関数側では受信バイト数を CloudWatch Logs に出します。
本デモでは AWS CDK(TypeScript)を使用して環境構築しています。
デモ用コード
今回は下記のように言語を分けてデモ用コードを作成しています。
- Lambdaコード:Python
- Labda呼び出しコード:TypeScript
- IaC(CDK):TypeScript
今回はLambdaコード・Lambda呼び出しコードのみ記事に記載し、IaCコードは省略します。
Lambdaコード
import json
import logging
# Configure structured logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def _byte_len(obj):
"""
Calculate the byte size of an object.
Args:
obj: The object to measure (string or dict)
Returns:
int: The byte size of the object in UTF-8 encoding
"""
if isinstance(obj, str):
return len(obj.encode('utf-8'))
elif isinstance(obj, dict):
# Serialize to JSON and calculate byte size
json_str = json.dumps(obj, ensure_ascii=False)
return len(json_str.encode('utf-8'))
else:
# For other types, convert to JSON first
json_str = json.dumps(obj, ensure_ascii=False)
return len(json_str.encode('utf-8'))
def lambda_handler(event, context):
"""
Lambda handler function that measures and logs payload sizes.
Args:
event: The Lambda event payload (string or dict)
context: The Lambda context object
Returns:
dict: Response with ok status and received_bytes count
"""
try:
# Calculate payload size
received_bytes = _byte_len(event)
event_type = type(event).__name__
# Log payload information
logger.info(f"received bytes={received_bytes} type={event_type}")
# Return success response
return {
"ok": True,
"received_bytes": received_bytes
}
except Exception as e:
# Log error with full stack trace
logger.exception(f"Error processing payload: {str(e)}")
# Return error response
return {
"ok": False,
"error": str(e)
}
Lambda呼び出しコード
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
/**
* Generate a test payload of approximately the specified size in KB
*/
export function generatePayload(sizeKB: number): { data: string } {
// Account for JSON overhead: {"data":"..."}
// Approximately 12 bytes for the JSON structure
const jsonOverhead = 12;
const targetBytes = sizeKB * 1024 - jsonOverhead;
// Generate a string of repeated characters
const data = 'A'.repeat(Math.max(0, targetBytes));
return { data };
}
/**
* Calculate the actual byte size of a JSON payload
*/
export function calculatePayloadSize(payload: object): number {
const jsonString = JSON.stringify(payload);
return Buffer.byteLength(jsonString, 'utf-8');
}
/**
* Invoke Lambda function asynchronously
*/
export async function invokeLambda(
functionName: string,
payload: object,
label: string
): Promise<void> {
const client = new LambdaClient({ region: 'ap-northeast-1' });
const payloadBytes = calculatePayloadSize(payload);
const payloadKB = (payloadBytes / 1024).toFixed(2);
console.log(`\n${label}:`);
console.log(` Payload size: ${payloadBytes} bytes (${payloadKB} KB)`);
try {
const command = new InvokeCommand({
FunctionName: functionName,
InvocationType: 'Event', // Asynchronous invocation
Payload: JSON.stringify(payload),
});
const response = await client.send(command);
console.log(` Status code: ${response.StatusCode}`);
if (response.StatusCode === 202) {
console.log(` ✓ Invocation accepted (asynchronous)`);
} else {
console.log(` ⚠ Unexpected status code: ${response.StatusCode}`);
}
} catch (error) {
console.error(` ✗ Error invoking Lambda:`, error);
throw error;
}
}
/**
* Main function to run test invocations
*/
async function main() {
// Get function name from command line or environment
const functionName = process.argv[2] || process.env.LAMBDA_FUNCTION_NAME;
if (!functionName) {
console.error('Error: Lambda function name not provided');
console.error('Usage: npx ts-node services/invoke-lambda.ts <function-name>');
process.exit(1);
}
console.log(`Testing Lambda function: ${functionName}`);
console.log('='.repeat(60));
// Test case 1: 300KB payload
const payload300KB = generatePayload(300);
await invokeLambda(functionName, payload300KB, 'Test 1: 300KB payload');
// Test case 2: 900KB payload
const payload900KB = generatePayload(900);
await invokeLambda(functionName, payload900KB, 'Test 2: 900KB payload');
console.log('\n' + '='.repeat(60));
console.log('All invocations completed successfully!');
console.log('Check CloudWatch Logs to verify payload sizes were logged.');
}
// Run main if this file is executed directly
if (require.main === module) {
main().catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});
}
実行結果
Lambdaをデプロイ後、非同期呼び出しを行った結果です。
300KB・900KBともに呼び出せていることを確認できました!
CloudWatch Logsでも、300KB・900KBのメッセージが受信できていることを確認できました。
この結果から、確かに1MBまで上限が引き上げられていることが分かります。
まとめ
今回は Lamba の非同期呼び出しでペイロードサイズが1MBまで上限が引き上げられたことの確認デモを行いました。
処理可能なペイロードサイズが増えたことで、非同期化できる処理の幅が広がりそうです!
非同期呼び出しはレスポンスタイムの改善、耐障害性・可用性の向上などの観点からしても重要な考えです。
全ての処理を同期的に行うのか、非同期でも問題ない処理を積極的に非同期化するのかを日々の業務でも考えていき、使い分けを行えるようになりたいです。





