10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS LambdaはRustがおすすめ ー と言える時代が到来

10
Last updated at Posted at 2025-12-10

この記事は Qiita Advent Calendar 2025 Rust シリーズ Day 10 の記事です。


いまRustでLambdaを書くのが最高に楽しいです!

2025年11月14日、AWS Lambda の Rust サポートが GA (Generally Available) になりました。これまで「experimental」だった Rust ランタイムが、AWS Support と SLA でバックアップされる正式なサポートになりました。

この記事では、Rust Lambda の開発を劇的に簡単にする cargo-lambda というツールと、実際の CloudWatch データに基づくパフォーマンス比較を紹介します。

GA 🎊

  • lambda_runtime クレートが v1.0.0
  • 全リージョン(GovCloud、中国含む)で利用可能

"Rust is a popular programming language due to its combination of high performance, memory safety, and developer experience"
— AWS Blog

👏


cargo-lambda とは

Rustは rust-analyzer などの開発ツールの充実が魅力の一つでもありますが、Lambda 開発にも cargo-lambda という素晴らしい CLI ツールがあります。David Calavera 氏が開発し、AWS 公式も推奨しています。

cargo-lambda がやってくれること

Lambda で Rust を動かすには、Linux 向けにクロスコンパイルしたバイナリを bootstrap という名前で ZIP 化する必要があります。cargo-lambda ならこれらがコマンドラインから一発実行です。

特徴 説明
Docker 不要 ローカルで直接ビルド・テスト
クロスコンパイル Zig を使って macOS/Windows から Linux ARM64 へ
ローカルエミュレータ cargo lambda watch で即座にテスト
ワンコマンドデプロイ cargo lambda deploy で AWS へ

インストール

Zig に依存しているため事前にインストールしてください。

# macOS (Homebrew)
brew tap cargo-lambda/cargo-lambda
brew install cargo-lambda
# Linux / macOS (curl)
curl -fsSL https://cargo-lambda.info/install.sh | sh
# Python 環境
pip3 install cargo-lambda
# Windows (WinGet)
winget install CargoLambda.CargoLambda
# cargo-binstall (バイナリインストール)
cargo binstall cargo-lambda

ビルドの再現性が保証できないため、cargo install cargo-lambda は非サポートだそうです。


Getting Started

Step 1: プロジェクト作成

# 基本的な Lambda
cargo lambda new my-lambda

# HTTP Lambda (API Gateway / Function URLs 用)
cargo lambda new --http my-http-lambda

Step 2: ローカルテスト

# Lambda エミュレータを起動
cargo lambda watch

# 別ターミナルから呼び出し
cargo lambda invoke --data-ascii '{"key": "value"}'

# HTTP Lambda の場合はブラウザで
# http://localhost:9000/

Step 3: ビルド

# x86_64 向け
cargo lambda build --release

# ARM64 (Graviton) 向け - おすすめ
cargo lambda build --release --arm64

Step 4: デプロイ

# デフォルト IAM ロールで自動作成
cargo lambda deploy

# 既存の IAM ロールを指定
cargo lambda deploy --iam-role arn:aws:iam::123456789012:role/my-role

これだけです。Docker も CloudFormation も SAM も不要です。


実測パフォーマンス比較

私のAWS アカウントで運用している Rust Lambda と Python Lambda の CloudWatch データを紹介します。

テスト対象

Lambda 言語 メモリ 主な依存
A Rust 256MB lambda_http, serde, tracing
B Rust 128MB lambda_http, serde, uuid
C Python 512MB boto3

C は 下の記事 で紹介した AgentCore へのゲートウェイ です。boto3 のみを使用するシンプルな構成です。

コールドスタート実測値

Rust Lambda

A (lambda_http + serde + tracing):
  Init Duration: 26.97 ms
  Init Duration: 28.24 ms
  Init Duration: 28.72 ms
  Init Duration: 33.74 ms
  → 平均: 29ms

B (lambda_http + serde + uuid):
  Init Duration: 24.84 ms
  Init Duration: 27.26 ms
  Init Duration: 27.52 ms
  Init Duration: 37.95 ms
  → 平均: 29ms

Python Lambda

C (boto3 のみ):
  Init Duration: 464.03 ms
  Init Duration: 500.33 ms
  Init Duration: 507.82 ms
  Init Duration: 521.32 ms
  Init Duration: 569.49 ms
  → 平均: 513ms

比較結果

cold_start_comparison.png

指標 Rust Python (boto3)
コールドスタート 29ms 513ms
メモリ使用量 17-18MB 82-85MB

今回の構成では Rust が Python より大幅に速いコールドスタート を観測しました。

この比較は特定の構成での実測値であることを一応断っておきます。Python 側は boto3 の初期化コストが大きく影響していると考えられます。純粋なランタイム比較(Hello World 程度)では、公開ベンチマーク によると Rust 16ms vs Python 79ms(約5倍差)とのことです。


実際のコード例

参考までに

Cargo.toml

[package]
name = "my-lambda"
version = "0.1.0"
edition = "2021"

[dependencies]
lambda_http = "1.0"
lambda_runtime = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1", features = ["macros"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }

# デプロイ設定
[package.metadata.lambda.deploy]
memory = 256
timeout = 30
tracing = "Active"

# バイナリ最適化
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true

main.rs (HTTP Lambda)

use lambda_http::{run, service_fn, Body, Error, Request, Response};
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
struct RequestBody {
    message: String,
}

#[derive(Debug, Serialize)]
struct ResponseBody {
    success: bool,
    echo: String,
}

async fn handler(event: Request) -> Result<Response<Body>, Error> {
    // リクエストボディをパース
    let body: RequestBody = match event.body() {
        Body::Text(text) => serde_json::from_str(text)?,
        _ => return Ok(Response::builder()
            .status(400)
            .body("Invalid body".into())?),
    };

    // レスポンス作成
    let response = ResponseBody {
        success: true,
        echo: body.message,
    };

    Ok(Response::builder()
        .status(200)
        .header("Content-Type", "application/json")
        .body(serde_json::to_string(&response)?.into())?)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .json()
        .init();

    run(service_fn(handler)).await
}

Tips

ARM64 (Graviton) がおすすめ

cargo lambda build --release --arm64
アーキテクチャ コスト パフォーマンス
x86_64 基準 基準
arm64 20% 安い 同等以上

まとめ

GA になった今が始めどきでは!


参考リンク


Qiita Advent Calendar 2025 Rust シリーズ 明日は @dezamisystem さんです!

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?