← Blog

Claude API Serverless Deployment on AWS Lambda

2026-09-27 · 5 min read · SubToAPI Team

Running Claude API calls inside AWS Lambda works well for request/response workloads like document summarization, classification, or chatbot backends triggered by API Gateway. The main constraints you need to design around are Lambda's execution time limit, the lack of native long-lived HTTP streaming, and how you manage your API key across invocations. This article walks through a working setup and the tradeoffs that matter in production.

The short version: package a minimal HTTP client (no heavy SDK dependencies if you can avoid them), store your API key in Secrets Manager or SSM Parameter Store, set your Lambda timeout above your expected Claude response time, and either buffer the full response or use Lambda response streaming (function URLs support this) if you need token-by-token output. Below is the detail on each piece.

Basic Lambda Function Calling Claude

A minimal Node.js Lambda handler making a non-streaming call looks like this:

const https = require("https");

exports.handler = async (event) => {
  const body = JSON.stringify({
    model: "claude-sonnet-4",
    max_tokens: 1024,
    messages: [{ role: "user", content: event.prompt }]
  });

  const response = await new Promise((resolve, reject) => {
    const req = https.request(
      "https://api.anthropic.com/v1/messages",
      {
        method: "POST",
        headers: {
          "content-type": "application/json",
          "x-api-key": process.env.CLAUDE_API_KEY,
          "anthropic-version": "2023-06-01"
        }
      },
      (res) => {
        let data = "";
        res.on("data", (chunk) => (data += chunk));
        res.on("end", () => resolve(JSON.parse(data)));
      }
    );
    req.on("error", reject);
    req.write(body);
    req.end();
  });

  return { statusCode: 200, body: JSON.stringify(response) };
};

Using the native https module instead of a full SDK keeps your deployment package small and cold starts faster. If you already depend on axios or node-fetch elsewhere in your codebase, it's fine to use them — the SDK isn't the bottleneck, unused dependencies are.

Timeout and Memory Configuration

Claude responses for longer generations (thousands of tokens) can take well past Lambda's default 3-second timeout. Set your function timeout to at least 60–90 seconds for anything beyond short completions, and remember API Gateway has its own 29-second hard limit on REST APIs — if you're going through API Gateway rather than a Lambda function URL, long completions will get cut off regardless of your Lambda timeout.

Practical options:

Memory allocation also affects CPU allocation in Lambda. For pure API-call workloads (no local inference, no heavy JSON parsing of huge payloads), 256–512MB is usually enough. Bump it only if you're doing significant text processing on the response.

Streaming from Lambda

Token-by-token streaming (SSE) is the trickiest part of this setup. Traditional Lambda invocations return a single response — you can't push chunks incrementally through API Gateway's REST API integration. Two options:

  1. Lambda response streaming via function URLs (InvokeMode: RESPONSE_STREAM), which lets you pipe Claude's SSE chunks directly to the client as they arrive.
  2. Buffer and return once complete, which is simpler but means the client waits for the full generation before seeing anything.

If your product needs a responsive streaming UI, function URL streaming is worth the setup complexity. If you're doing backend processing where the final text is all that matters (summarization pipelines, extraction jobs), buffering is simpler and easier to debug — see general patterns for streaming responses if you're comparing approaches across providers.

Secrets and IAM

Never hardcode the API key in your Lambda environment variables as plaintext in your deployment template if you can avoid it — use Secrets Manager or SSM Parameter Store with KMS encryption, and grant the Lambda execution role read-only access to that specific secret:

{
  "Effect": "Allow",
  "Action": "secretsmanager:GetSecretValue",
  "Resource": "arn:aws:secretsmanager:eu-west-1:123456789012:secret:claude-api-key-*"
}

Fetch the secret once at cold start and cache it in module scope so warm invocations don't re-fetch it on every call. This also matters for cost: Secrets Manager charges per API call.

Cold Starts and Provisioned Concurrency

Cold starts add 100–400ms typically for a lightweight Node.js function, which is negligible next to Claude's own response time for anything beyond trivial prompts. Provisioned concurrency is rarely worth the cost here unless you have strict latency SLAs on the Lambda side specifically — the API call itself dominates total latency in almost every case.

Managing Keys Across Environments and Teams

If you're running Claude calls from multiple Lambda functions, multiple AWS accounts, or a mix of internal tools and customer-facing features, tracking usage per function or per team gets messy fast with a single shared API key. This is where a layer like SubToAPI helps: instead of one Anthropic key shared across every Lambda in your account, you issue separate sub_live_... keys per function or per team, each hitting the same https://api.subtoapi.app/v1/messages endpoint with usage tracked independently in one dashboard. Rotating or revoking a key for one Lambda function doesn't affect the others, and you get per-key usage metadata without building that tracking yourself.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 512,
    "messages": [{"role": "user", "content": "Summarize this Lambda log."}]
  }'

The request shape mirrors the standard Messages API, so swapping it into an existing Lambda handler is a one-line change — see the quickstart and Messages docs for the full request format, or tool use docs if your Lambda functions need Claude to call external functions as part of the workflow.

Deployment Checklist

FAQs

Does API Gateway support streaming Claude responses? Not through the standard REST API integration — it buffers the full Lambda response. Use Lambda function URLs with RESPONSE_STREAM mode if you need to stream tokens to the client as they arrive.

What Lambda timeout should I set for Claude API calls? At least 60–90 seconds for typical generation lengths. Short classification or extraction prompts can run fine within 15–30 seconds, but leave headroom for network variance.

Is provisioned concurrency worth it for Claude-calling Lambdas? Usually not. Cold start overhead (100–400ms) is small relative to the API call's own latency, so the added cost of provisioned concurrency rarely pays off unless you have strict end-to-end SLAs.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →