<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">

<channel>
	<title>AWS Compute Blog</title>
	<atom:link href="https://aws.amazon.com/blogs/compute/feed/" rel="self" type="application/rss+xml"/>
	<link>https://aws.amazon.com/blogs/compute/</link>
	<description/>
	<lastBuildDate>Mon, 14 Sep 2026 16:47:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Validating multi-agent decisions with Step Functions and Bedrock AgentCore</title>
		<link>https://aws.amazon.com/blogs/compute/validating-multi-agent-decisions-with-step-functions-and-bedrock-agentcore/</link>
		
		<dc:creator><![CDATA[Ben Freiberg]]></dc:creator>
		<pubDate>Mon, 14 Sep 2026 16:47:23 +0000</pubDate>
				<category><![CDATA[Amazon Bedrock AgentCore]]></category>
		<category><![CDATA[AWS Step Functions]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">299c667ab403e16b2aa8de1f963d80e5dcac9274</guid>

					<description>Orchestrating specialized Amazon Bedrock AgentCore agents with AWS Step Functions gives you the reasoning power of generative AI with the guardrails of deterministic validation. Agents propose options, and deterministic code validates them before any action is taken, demonstrated here with an airline rebooking workflow.</description>
										<content:encoded>&lt;p&gt;For an airline operations team, a single flight cancellation sets off a chain reaction. Hundreds of passengers need new itineraries within minutes, and no two cases are alike. They have different loyalty tiers, sit on different fare rules, and have downstream connections that may not wait. Passengers have varying cabin and seat preferences and might fall under different regulatory entitlements depending on where they booked and where they are flying.&lt;/p&gt; 
&lt;p&gt;Most airlines handle this with a layered system: rule-based automation covers the simple, one-hop rebooks, and everything else flows to a manual queue staffed by service agents. That works when disruptions are isolated. When they are not, the queue overwhelms, waiting times spike, and passengers booked alternatives themselves that create downstream knock-on disruptions.&lt;/p&gt; 
&lt;p&gt;This is exactly where AI agents become compelling. An agent can reason across seat availability, fare rules, loyalty entitlements, and connection timing the way an experienced desk agent would, but at machine speed and across hundreds of cases in parallel. Multi-agent collaboration typically lets a supervisor agent route work to collaborator sub-agents, with the model itself deciding which sub-agent runs and in what order. But an unconstrained agent might optimize for the passenger’s preference while ignoring a codeshare restriction, rebook onto a flight that meets minimum connection time on paper but not at that specific airport, or calculate compensation under the wrong regulatory regime because it misread the ticket’s point of sale.&lt;/p&gt; 
&lt;p&gt;Orchestrating specialized &lt;a href="https://aws.amazon.com/bedrock/agentcore/" target="_blank" rel="noopener"&gt;Amazon Bedrock AgentCore&lt;/a&gt; agents with &lt;a href="https://aws.amazon.com/step-functions/" target="_blank" rel="noopener"&gt;AWS Step Functions&lt;/a&gt; gives you the reasoning power of generative AI with the guardrails of deterministic validation. Step Functions adds native fan-out across thousands of passengers, a callback pattern that pauses a case for human review at zero compute cost, and a durable execution history that serves as your audit trail. The principle is that agents propose, and deterministic code validates. The pattern is demonstrated here for airline rebooking, but it applies anywhere automated decisions can have real financial or regulatory consequences.&lt;/p&gt; 
&lt;h2 id="solution-overview"&gt;Solution overview&lt;/h2&gt; 
&lt;p&gt;The design is a Step Functions state machine where deterministic steps that map to the business processes wrap each agent’s non-deterministic behavior. The following diagram shows the end-to-end flow. At a high level, the workflow proceeds through these stages:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;The workflow starts when a flight-cancellation event arrives, for example through an &lt;a href="https://aws.amazon.com/eventbridge/" target="_blank" rel="noopener"&gt;Amazon EventBridge&lt;/a&gt; integration.&lt;/li&gt; 
 &lt;li&gt;An enrichment step pulls additional data such as the passenger manifest, current bookings, loyalty status, and stored preferences.&lt;/li&gt; 
 &lt;li&gt;The workflow fans out to run agents in parallel for each affected passenger.&lt;/li&gt; 
 &lt;li&gt;Two agents then run for each passenger: a find-alternatives agent proposes the top three rebooking options, and a compensation agent determines entitlement based on route, delay duration, and cause.&lt;/li&gt; 
 &lt;li&gt;A deterministic validation step runs after each agent, confirming flights are actually bookable and entitlement rules are followed before either result is used.&lt;/li&gt; 
 &lt;li&gt;The workflow checks whether the case can be auto-confirmed, or needs human review.&lt;/li&gt; 
 &lt;li&gt;Bookings are confirmed, compensation issues, and confirmations are sent. Unresolved cases go to human agents.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The key principle: no agent Task state writes to the reservation system or issues a payment. Only deterministic Task states do that, and only after a deterministic validation step has passed.&lt;/p&gt; 
&lt;h2 id="integrating-agentcore-harness-with-step-functions"&gt;Integrating AgentCore harness with Step Functions&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/harness.html" target="_blank" rel="noopener"&gt;AgentCore harness&lt;/a&gt; is a managed agent loop. You specify a model, system prompt, and tools, and the harness runs the reasoning cycle (model calls, tool execution, memory management, and response generation) end-to-end in a single API call. It handles the intra-agent orchestration so that Step Functions can focus on inter-agent orchestration: fan-out, sequencing, validation gates, and exception routing. Step Functions provides a native optimized integration for AgentCore harness, which calls &lt;code&gt;InvokeHarness&lt;/code&gt; against a target &lt;code&gt;HarnessArn&lt;/code&gt;. The optimized integration gives you an extended per-Task timeout of 15 minutes (900 seconds), so agents have enough time to reason through complex proposals. The trade-off is that the agent call is request-response only. There is no &lt;code&gt;.sync&lt;/code&gt; and no &lt;code&gt;.waitForTaskToken&lt;/code&gt; on the agent step, and only the final assistant message is returned to the state machine.&lt;/p&gt; 
&lt;p&gt;The following Amazon States Language snippet shows the optimized harness invocation inside a Distributed Map. For the full definition, see the sample on &lt;a href="https://serverlessland.com/patterns/sfn-bedrockagentcore-harness-cdk" target="_blank" rel="noopener"&gt;Serverless Land&lt;/a&gt;.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Comment": "Illustrative - per-passenger rebooking fan-out",
  "StartAt": "RebookPassengers",
  "States": {
    "RebookPassengers": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": { "Mode": "DISTRIBUTED", "ExecutionType": "STANDARD" },
        "StartAt": "FindAlternatives",
        "States": {
          "FindAlternatives": {
            "Type": "Task",
            "Resource": "arn:aws:states:::bedrockagentcore:invokeHarness",
            "Parameters": {
              "HarnessArn": "&amp;lt;HARNESS_ARN&amp;gt;",
              "RuntimeSessionId.$": "$.passenger.sessionId",
              "Messages": [{ "Role": "user", "Content": [{ "Text.$": "States.JsonToString($.passenger)" }] }]
            },
            "TimeoutSeconds": 900,
            "ResultPath": "$.proposal",
            "Next": "ValidateRebooking"
          },
          "ValidateRebooking": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "End": true }
        }
      },
      "MaxConcurrency": 1000,
      "End": true
    }
  }
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Note: the service name is spelled &lt;code&gt;bedrockagentcore&lt;/code&gt; (no hyphen) in the Step Functions resource string, but &lt;code&gt;bedrock-agentcore&lt;/code&gt; (with a hyphen) in the AgentCore ARN.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;MaxConcurrency&lt;/code&gt; is set to 1000 to bound fan-out and protect downstream booking and inventory systems. If you omit it or set it to 0, you get the default behavior, which runs up to 10,000 parallel child executions. The agent Task flows directly into a deterministic validation Task.&lt;/p&gt; 
&lt;h2 id="how-it-differs-from-managed-multi-agent-collaboration"&gt;How it differs from managed multi-agent collaboration&lt;/h2&gt; 
&lt;p&gt;Multi-agent collaboration typically means that a supervisor agent decides which sub-agent runs and which tools it calls. Step Functions moves those decisions out of the agent layer entirely.&lt;/p&gt; 
&lt;p&gt;This design puts orchestration, fan-out, validation, routing, retries, and the audit trail into Step Functions instead. Routing is a deterministic state you define and can test in isolation, not a model classification you hope will be consistent. You get a per-state execution history (every transition recorded with input and output), whereas agent-layer traces require opt-in and provide reasoning rationale rather than a durable, always-on event log.&lt;/p&gt; 
&lt;h2 id="design-walkthrough-of-the-reference-app"&gt;Design walkthrough of the reference app&lt;/h2&gt; 
&lt;p&gt;The following image shows the Step Functions state machine implemented by the sample application.&lt;/p&gt; 
&lt;div style="width: 764px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/27/ComputeBlog-2680-1.png" alt="Step Functions state machine showing the rebooking workflow: trigger, enrich, a Distributed Map fan-out with agent and deterministic validation stages, choice routing to human review, and execute stages" width="754"&gt;
 &lt;p class="wp-caption-text"&gt;Figure 1: The Step Functions state machine for the airline rebooking workflow&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Stage 1, Trigger.&lt;/strong&gt; An Amazon EventBridge rule starts the workflow on a flight-cancellation event.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 2, Enrich.&lt;/strong&gt; A deterministic Task pulls the passenger manifest, bookings, loyalty status, and preferences into the execution state.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 3, Map fan-out.&lt;/strong&gt; A Distributed Map iterates affected passengers in parallel. The choice of Map type matters at scale. An inline Map runs up to 40 concurrent iterations, which is the documented threshold for choosing Distributed mode. A Distributed Map runs up to 10,000 parallel child executions by default, the right tool when a hub event affects thousands of passengers.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 4, Agent 1 find alternatives.&lt;/strong&gt; An AgentCore Task proposes the top three options, reasoning over the passenger’s preferences and constraints.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 5, Deterministic validation of the rebooking proposal.&lt;/strong&gt; An &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; Task confirms each proposed flight is bookable by checking live availability, fare rules, and route validity, and it rejects hallucinated options. An agent might confidently propose a flight that does not exist. This stage is where that proposal is caught before it can become a ticket.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 6a, Agent 2 draft compensation.&lt;/strong&gt; A second AgentCore Task drafts personalized, customer-facing notification text only. It does not compute entitlement and it does not move money.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 6b, Deterministic entitlement check.&lt;/strong&gt; A Lambda Task computes and validates the entitlement against rule tables before any compensation issues. Consumer-protection frameworks such as EU Regulation 261/2004 (EU261) and US Department of Transportation refund rules are referenced here illustratively, to show why deterministic, auditable computation matters. The specific bands, triggers, and amounts are configuration you own and validate against current legal guidance, not something an agent should infer.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 7, Choice routing and human-in-the-loop.&lt;/strong&gt; A Choice state auto-confirms rebookings for some passengers and routes the rest to a human. For the cases that need review, the workflow waits on a separate &lt;code&gt;.waitForTaskToken&lt;/code&gt; Task, backed by Lambda, &lt;a href="https://aws.amazon.com/sns/" target="_blank" rel="noopener"&gt;Amazon Simple Notification Service (Amazon SNS)&lt;/a&gt;, or &lt;a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener"&gt;Amazon Simple Queue Service (Amazon SQS)&lt;/a&gt;, with a 4-hour timeout. The wait happens on this separate callback Task, never on the agent step.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Comment": "Illustrative - route and wait on a human, not on the agent",
  "RouteDecision": {
    "Type": "Choice",
    "Choices": [
      {
        "Variable": "$.passenger.autoConfirmEligible",
        "BooleanEquals": true,
        "Next": "ExecuteBooking"
      }
    ],
    "Default": "AwaitHumanApproval"
  },
  "AwaitHumanApproval": {
    "Type": "Task",
    "Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
    "Parameters": {
      "QueueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/approvals",
      "MessageBody": {
        "taskToken.$": "$$.Task.Token",
        "passengerId.$": "$.passenger.id",
        "options.$": "$.proposal.validatedOptions"
      }
    },
    "TimeoutSeconds": 14400,
    "Next": "ExecuteBooking"
  }
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Stage 8, Execute.&lt;/strong&gt; Deterministic Task states confirm the booking, issue compensation, and send confirmation. Each execution Task derives an idempotency token from the passenger ID combined with the decision ID (the child execution name, or a hash of the validated option set) and passes it to the booking and payment APIs, so a retry or redrive is a no-op instead of a duplicate booking or a second payment.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stage 9, Aggregate and exception routing.&lt;/strong&gt; The workflow summarizes outcomes and routes any unresolved cases to human agents.&lt;/p&gt; 
&lt;p&gt;The validation step itself is ordinary deterministic code. A simplified rebooking validator in Python looks like the following.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;# Illustrative - reject any option the agent proposed that is not bookable
def handler(event, context):
    passenger = event["passenger"]
    proposed = event["proposal"]["options"]

    validated = []
    for option in proposed:
        flight = lookup_flight(option["flightId"])
        if flight is None:
            continue  # hallucinated or stale flight, reject
        if flight["seatsAvailable"] &amp;lt; 1:
            continue  # no inventory, reject
        if not fare_rules_allow(passenger["fareClass"], flight):
            continue  # fare rule violation, reject
        if not route_is_valid(passenger["origin"], passenger["destination"], flight):
            continue  # invalid route, reject
        validated.append(option)

    return {
        "passengerId": passenger["id"],
        "validatedOptions": validated,
        "autoConfirmEligible": passenger["loyaltyTier"] == "top" and len(validated) &amp;gt; 0,
    }&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h2 id="best-practices-and-guardrails"&gt;Best practices and guardrails&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Reject hallucinations through validations.&lt;/strong&gt; No agent proposal is applied without a deterministic validation step passing first. This minimizes the impact of hallucinations, prompt injections, or bugs on your workflow.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Keep a complete audit trail.&lt;/strong&gt; Step Functions execution history records every state transition, input, and output, and pairing that with durable persistence gives you a per-decision record. You can show exactly which proposal was made, which validation passed or failed, and who approved the exception.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Surface only true exceptions to humans.&lt;/strong&gt; Humans handle only what validation or the agent cannot resolve. Auto-confirmation handles the clear cases, and people spend their attention on the genuinely ambiguous ones.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Hold executions open cheaply.&lt;/strong&gt; The &lt;code&gt;.waitForTaskToken&lt;/code&gt; callback holds the execution open with no compute charges while the execution is paused. For example, you can cost-efficiently park thousands of pending approvals overnight. Refer to the &lt;a href="https://aws.amazon.com/step-functions/pricing/" target="_blank" rel="noopener"&gt;AWS Step Functions pricing page&lt;/a&gt; for current details.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Make execution idempotent.&lt;/strong&gt; Guard reservation execution and compensation issuance against retries and double-sends, as shown in Stage 8. Derive the idempotency token from the passenger ID and decision ID, and pass it to your booking and payment APIs so that a replay is a no-op.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Respect cost and timeouts.&lt;/strong&gt; Keep each per-agent Task timeout within the 15-minute quota, bound your Map concurrency to protect downstream systems, and track the token usage returned in the agent response so you can attribute and forecast cost.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Handle errors deliberately.&lt;/strong&gt; Apply &lt;code&gt;Retry&lt;/code&gt; and &lt;code&gt;Catch&lt;/code&gt; on the agent Tasks for conditions such as &lt;code&gt;BedrockAgentCore.ThrottlingException&lt;/code&gt; and &lt;code&gt;BedrockAgentCore.ResourceNotFoundException&lt;/code&gt;, and on the Lambda validation Tasks for their own failure modes. A &lt;code&gt;Catch&lt;/code&gt; on an agent Task can route a stuck passenger straight to the human queue rather than failing the whole child execution.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Confirm availability and Region support.&lt;/strong&gt; Check the current availability status and supported AWS Regions for AgentCore and the Step Functions integration at the &lt;a href="https://builder.aws.com/build/capabilities/explore?tab=service-feature" target="_blank" rel="noopener"&gt;AWS Capabilities by Region&lt;/a&gt; on Builder Center.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;A flight-cancellation event is a challenging test of automated decision-making, because the output can have immediate financial impact. The way to use AI agents safely in that setting is to let them do what they are good at, proposing options and drafting language, while never letting a proposal become an action until deterministic code has approved it. In this design, orchestration, fan-out, validation, routing, and retries are implemented in Step Functions rather than inside an agent’s reasoning. Agents do not make changes directly, and their output is only applied after deterministic validation. You get a per-decision record for review, and you hold exceptions open on a callback that adds no compute or storage cost while it waits.&lt;/p&gt; 
&lt;p&gt;To get started, deploy the &lt;a href="https://serverlessland.com/patterns/sfn-bedrockagentcore-harness-cdk" target="_blank" rel="noopener"&gt;reference pattern from Serverless Land&lt;/a&gt; and adapt the validation layer to your own workflow.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Customize Amazon API Gateway destinations for execution logs</title>
		<link>https://aws.amazon.com/blogs/compute/customize-amazon-api-gateway-destinations-for-execution-logs/</link>
		
		<dc:creator><![CDATA[Giedrius Praspaliauskas]]></dc:creator>
		<pubDate>Wed, 09 Sep 2026 22:35:42 +0000</pubDate>
				<category><![CDATA[Amazon API Gateway]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Intermediate (200)]]></category>
		<guid isPermaLink="false">11804c9f98508b1bc1561231cc420556cf309fb2</guid>

					<description>Amazon API Gateway execution logs help you trace request processing step by step through your REST API stages. They capture authorization results, integration latency, mapping template output, and error details that are otherwise invisible at the API surface. When a production request fails in a way the access log cannot explain, the execution log is […]</description>
										<content:encoded>&lt;p&gt;&lt;a href="https://aws.amazon.com/api-gateway/" target="_blank" rel="noopener"&gt;Amazon API Gateway&lt;/a&gt; execution logs help you trace request processing step by step through your REST API stages. They capture authorization results, integration latency, mapping template output, and error details that are otherwise invisible at the API surface. When a production request fails in a way the access log cannot explain, the execution log is usually where you find the explanation.&lt;/p&gt; 
&lt;p&gt;Until now, execution logs had two constraints. Every log event was truncated at 1 KB, so a request carrying a moderately sized JSON body would exceed that limit and the remainder was dropped. Logs could only go to the auto-managed log group that API Gateway creates for you (&lt;code&gt;API-Gateway-Execution-Logs_{rest-api-id}/{stage_name}&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;With &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt; Logs delivery for REST API execution logs, you can now route execution logs to Amazon CloudWatch Logs, &lt;a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener"&gt;Amazon Simple Storage Service (Amazon S3)&lt;/a&gt;, or &lt;a href="https://aws.amazon.com/firehose/" target="_blank" rel="noopener"&gt;Amazon Data Firehose&lt;/a&gt;. Log events can be up to 1 MB per entry, and you benefit from &lt;a href="https://aws.amazon.com/cloudwatch/pricing/" target="_blank" rel="noopener"&gt;vended logs pricing&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;In this post, you learn how CloudWatch Logs delivery works with API Gateway execution logs, how to configure it, and what patterns work best for common observability scenarios.&lt;/p&gt; 
&lt;h2 id="understanding-api-gateway-execution-logs"&gt;Understanding API Gateway execution logs&lt;/h2&gt; 
&lt;p&gt;API Gateway produces two categories of logs: access logs and execution logs. Access logs record a summary line per request, similar to an HTTP server access log. You configure the format and destination yourself.&lt;/p&gt; 
&lt;p&gt;Execution logs are different. They capture the internal processing of each request as it moves through the API Gateway pipeline: authorizer evaluation, request validation, integration dispatch, response mapping, and error handling. These logs exist so you can answer questions such as “why did my authorizer reject this token?” or “what did the mapping template produce before it reached my backend integration?”&lt;/p&gt; 
&lt;p&gt;API Gateway manages execution log creation automatically. When you set &lt;code&gt;loggingLevel&lt;/code&gt; to &lt;code&gt;INFO&lt;/code&gt; or &lt;code&gt;ERROR&lt;/code&gt; in your stage’s method settings, the service writes execution log events to a CloudWatch Logs log group it manages on your behalf. You do not choose the log group name or configure retention directly on it.&lt;/p&gt; 
&lt;p&gt;The auto-managed model works for many customers but may create friction for teams with specific observability requirements. Compliance frameworks that require logs in S3 with a particular prefix structure need an extra subscription filter and delivery mechanism. Sending execution logs into a security information and event management (SIEM) tool through a Firehose stream requires a forwarding layer.&lt;/p&gt; 
&lt;h2 id="configurable-log-delivery-with-cloudwatch-logs"&gt;Configurable log delivery with CloudWatch Logs&lt;/h2&gt; 
&lt;p&gt;CloudWatch Logs delivery separates log routing from log content. Two concepts control the behavior:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;DeliverySource&lt;/strong&gt; is scoped to your API Gateway stage ARN. It defines where logs go. You create a delivery source, then attach one or more delivery destinations (CloudWatch Logs log group, S3 bucket, or Firehose stream).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;MethodSettings&lt;/strong&gt; controls what gets logged. The &lt;code&gt;loggingLevel&lt;/code&gt; setting (&lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;ERROR&lt;/code&gt;, or &lt;code&gt;OFF&lt;/code&gt;) and &lt;code&gt;dataTraceEnabled&lt;/code&gt; flag still determine which log events API Gateway produces. These settings work the same way regardless of whether you use the auto-managed log group or CloudWatch Logs delivery.&lt;/p&gt; 
&lt;p&gt;When you create a delivery using the CloudWatch Logs APIs, CloudWatch Logs activates your log delivery on your API Gateway stage. When you delete the delivery, CloudWatch Logs disables it accordingly. You do not need to flip any flags on the API Gateway side, and the execution logs automatically resume flowing to the auto-managed log group.&lt;/p&gt; 
&lt;p&gt;Your existing method settings keep their meaning. The &lt;code&gt;loggingLevel&lt;/code&gt; and &lt;code&gt;dataTraceEnabled&lt;/code&gt; values continue to control log content. If &lt;code&gt;loggingLevel&lt;/code&gt; is already &lt;code&gt;INFO&lt;/code&gt; or &lt;code&gt;ERROR&lt;/code&gt;, creating a delivery redirects those logs to your chosen destination with no further configuration.&lt;/p&gt; 
&lt;p&gt;The following diagram shows how the pieces fit together.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/14/ComputeBlog-2656-1.png" alt="Diagram showing one API Gateway stage delivery source fanning out to CloudWatch Logs, Amazon S3, and Firehose destinations." width="800"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 1 — A single delivery source scoped to an API Gateway stage feeds one or more deliveries, each of which writes to a delivery destination backed by CloudWatch Logs, Amazon S3, or Amazon Data Firehose&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;The following table summarizes what changes when log delivery is active.&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Standard execution logging&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Log delivery&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Destination&lt;/td&gt; 
   &lt;td&gt;Auto-managed CloudWatch Logs log group&lt;/td&gt; 
   &lt;td&gt;CloudWatch Logs, Amazon S3, or Firehose&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Multi-destination&lt;/td&gt; 
   &lt;td&gt;No&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Pricing&lt;/td&gt; 
   &lt;td&gt;Standard CloudWatch Logs ingestion&lt;/td&gt; 
   &lt;td&gt;Vended logs pricing&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Log event size&lt;/td&gt; 
   &lt;td&gt;Truncated at 1 KB&lt;/td&gt; 
   &lt;td&gt;Up to 1 MB&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Setup&lt;/td&gt; 
   &lt;td&gt;Set &lt;code&gt;loggingLevel&lt;/code&gt; in MethodSettings&lt;/td&gt; 
   &lt;td&gt;Create delivery through CloudWatch Logs APIs&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Teardown&lt;/td&gt; 
   &lt;td&gt;Set &lt;code&gt;loggingLevel&lt;/code&gt; to &lt;code&gt;OFF&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Delete delivery&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3 id="what-stays-the-same"&gt;What stays the same&lt;/h3&gt; 
&lt;p&gt;Only execution log routing changes. Access logs continue to flow through &lt;code&gt;accessLogSettings&lt;/code&gt; to whatever log group you configure, and unrelated stage features such as AWS X-Ray tracing, detailed CloudWatch metrics, throttling, and caching behave exactly as they did before.&lt;/p&gt; 
&lt;h2 id="configuration-and-integration-options"&gt;Configuration and integration options&lt;/h2&gt; 
&lt;p&gt;Before you create a delivery, confirm the following requirements:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The API Gateway REST API is deployed to a stage.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;loggingLevel&lt;/code&gt; is set to &lt;code&gt;INFO&lt;/code&gt; or &lt;code&gt;ERROR&lt;/code&gt; in MethodSettings.&lt;/li&gt; 
 &lt;li&gt;The account-level CloudWatch Logs IAM role is configured. For setup steps, see &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html" target="_blank" rel="noopener"&gt;Set up CloudWatch logging for REST APIs in API Gateway&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;For cross-account delivery, the destination has an appropriate resource policy attached through &lt;code&gt;PutDeliveryDestinationPolicy&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="sending-logs-to-a-custom-cloudwatch-logs-log-group"&gt;Sending logs to a custom CloudWatch Logs log group&lt;/h3&gt; 
&lt;p&gt;The most common starting point is redirecting execution logs to a log group you own. You get direct control over retention policies, metric filters, and subscription filters. The following steps use the AWS Command Line Interface (AWS CLI) with the fictitious REST API ID &lt;code&gt;abc123&lt;/code&gt;, stage &lt;code&gt;prod&lt;/code&gt;, Region &lt;code&gt;us-east-1&lt;/code&gt;, and account &lt;code&gt;111122223333&lt;/code&gt;.&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;Create a delivery source referencing your stage ARN. The log type for REST API execution logs is &lt;code&gt;EXECUTION_LOGS&lt;/code&gt;: 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs put-delivery-source \
    --name my-apigw-execution-logs \
    --resource-arn arn:aws:apigateway:us-east-1:111122223333:/restapis/abc123/stages/prod \
    --log-type EXECUTION_LOGS&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt;Create a delivery destination pointing to your custom (existing) log group, then create the delivery that connects them: 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs put-delivery-destination \
    --name my-execution-log-destination \
    --delivery-destination-configuration \
        destinationResourceArn=arn:aws:logs:us-east-1:111122223333:log-group:/my-api/execution-logs&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs create-delivery \
    --delivery-source-name my-apigw-execution-logs \
    --delivery-destination-arn arn:aws:logs:us-east-1:111122223333:delivery-destination:my-execution-log-destination&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt;Verify that the delivery is active by listing deliveries for the source: 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs describe-deliveries&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The response includes the delivery ID, source, and destination ARN after delivery is established. Execution logs flow to &lt;code&gt;/my-api/execution-logs&lt;/code&gt; instead of the auto-managed group.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Log delivery adds structured fields (&lt;code&gt;resource_arn&lt;/code&gt;, &lt;code&gt;event_timestamp&lt;/code&gt;, &lt;code&gt;api_id&lt;/code&gt;, &lt;code&gt;stage&lt;/code&gt;, &lt;code&gt;resource_path&lt;/code&gt;, &lt;code&gt;http_method&lt;/code&gt;, and &lt;code&gt;payload&lt;/code&gt;) to each event, so a new delivery emits more than your previous logs. To keep the traditional execution log format with nothing extra, set output format and record fields while creating delivery destination and creating delivery:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs put-delivery-destination \
    --output-format "plain" ...

aws logs create-delivery \
    --record-fields "payload" \
    --field-delimiter "" ...&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="routing-logs-to-amazon-s3"&gt;Routing logs to Amazon S3&lt;/h3&gt; 
&lt;p&gt;S3 works well for long-term retention at lower cost, or for feeding logs into analytics tools such as &lt;a href="https://aws.amazon.com/athena/" target="_blank" rel="noopener"&gt;Amazon Athena&lt;/a&gt;. The bucket must be in the same region as your API. Create a delivery destination pointing to your bucket:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs put-delivery-destination \
    --name s3-archive-destination \
    --delivery-destination-configuration \
        destinationResourceArn=arn:aws:s3:::amzn-s3-demo-apigw-logs&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Then create a delivery using the same source name. CloudWatch Logs delivers the events to your bucket, where you can query them with Athena or catalog them with &lt;a href="https://aws.amazon.com/glue/" target="_blank" rel="noopener"&gt;AWS Glue&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="streaming-to-amazon-data-firehose"&gt;Streaming to Amazon Data Firehose&lt;/h3&gt; 
&lt;p&gt;For real-time analytics pipelines or third-party SIEM integration, Firehose delivery sends execution log events directly to your stream. The setup is identical: create a delivery destination with your Firehose stream ARN, then create a delivery. With direct Firehose delivery, you no longer need to maintain CloudWatch Logs subscription filters and &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; forwarders to route execution logs to external analytics systems.&lt;/p&gt; 
&lt;h3 id="multi-destination-delivery-and-per-destination-shaping"&gt;Multi-destination delivery and per-destination shaping&lt;/h3&gt; 
&lt;p&gt;A single delivery source supports multiple destinations. You can route the same execution logs to CloudWatch Logs for real-time alerting, S3 for long-term compliance retention, and Firehose for your SIEM, all from one stage. Create additional deliveries using the same delivery source with different destination ARNs.&lt;/p&gt; 
&lt;p&gt;Each destination receives identical log events. To shape what reaches each destination, apply a CloudWatch Logs subscription filter on the CloudWatch Logs destination. For example, you can forward only &lt;code&gt;ERROR&lt;/code&gt;-level events to a Lambda function that pushes alerts to a SIEM, while the same delivery source writes the full event stream to S3 for compliance.&lt;/p&gt; 
&lt;h3 id="management-console-experience"&gt;Management console experience&lt;/h3&gt; 
&lt;p&gt;You can also add a log delivery destination in the management console after you enable logging for the stage.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/14/ComputeBlog-2656-2.png" alt="API Gateway console showing the option to add a log delivery destination after logging is enabled for the stage." width="800"&gt;&lt;/p&gt; 
&lt;p&gt;You can specify multiple destinations, both in the current or in a different account:&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/14/ComputeBlog-2656-3.png" alt="API Gateway console showing multiple delivery destinations configured, including cross-account options." width="800"&gt;&lt;/p&gt; 
&lt;h3 id="keeping-existing-monitoring-intact"&gt;Keeping existing monitoring intact&lt;/h3&gt; 
&lt;p&gt;If you have dashboards or alarms on the auto-managed log group, use that same log group as one of your delivery destinations. Your existing monitoring keeps working, and you gain the ability to send logs to additional destinations such as S3 or Firehose in parallel.&lt;/p&gt; 
&lt;h2 id="best-practices"&gt;Best practices&lt;/h2&gt; 
&lt;p&gt;Update dashboards and alarms before enabling log delivery. When you activate log delivery, the auto-managed log group stops receiving logs. Any CloudWatch alarms, dashboards, or Contributor Insights rules pointing to &lt;code&gt;API-Gateway-Execution-Logs_{rest-api-id}/{stage_name}&lt;/code&gt; stop working. Migrate these references to your new log group before creating the delivery.&lt;/p&gt; 
&lt;p&gt;Keep &lt;code&gt;loggingLevel&lt;/code&gt; at &lt;code&gt;INFO&lt;/code&gt; or &lt;code&gt;ERROR&lt;/code&gt;. Log delivery controls routing, not content. If &lt;code&gt;loggingLevel&lt;/code&gt; is &lt;code&gt;OFF&lt;/code&gt;, no execution log events are produced regardless of whether a delivery exists. Verify your method settings before troubleshooting missing logs.&lt;/p&gt; 
&lt;p&gt;Treat the 1 MB log event capacity as a security decision, not only a debugging convenience. With &lt;code&gt;dataTraceEnabled&lt;/code&gt; set to true, execution logs include complete request and response payloads up to 1 MB. Those payloads might contain personally identifiable information (PII) or other sensitive data. Confirm your log destinations have appropriate access controls, encryption, and retention policies. Mask or filter sensitive fields in mapping templates upstream of logging and enable data tracing selectively per method or only in non-production stages.&lt;/p&gt; 
&lt;p&gt;Start with a single destination, then expand. Validate that your log group or bucket receives events correctly before adding Firehose or additional destinations.&lt;/p&gt; 
&lt;p&gt;Log delivery is best-effort. In rare cases, some log events might not be delivered. For audit-critical workloads, build retention and reconciliation that account for occasional missing events rather than treating execution logs as the system of record.&lt;/p&gt; 
&lt;h2 id="cleaning-up"&gt;Cleaning up&lt;/h2&gt; 
&lt;p&gt;To avoid ongoing charges from the resources you created while following this post, delete the delivery and then remove the destinations and any example S3 bucket or Data Firehose delivery stream you no longer need. Deleting the delivery returns the stage to standard auto-managed logging.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws logs delete-delivery --id &amp;lt;delivery-id&amp;gt;&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;When the delivery is deleted, CloudWatch Logs disables log delivery on the API Gateway stage automatically. The delivery source and delivery destination remain as independent objects. Delete them with &lt;code&gt;delete-delivery-source&lt;/code&gt; and &lt;code&gt;delete-delivery-destination&lt;/code&gt; if you do not plan to reuse them.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;CloudWatch Logs delivery for API Gateway REST API execution logs helps address the 1 KB event truncation and single managed destination constraints. You can now route full execution logs to CloudWatch Logs, Amazon S3, or Amazon Data Firehose, use multiple destinations from a single stage, and pay vended logs pricing.&lt;/p&gt; 
&lt;p&gt;The feature works alongside existing method settings. No changes to your current logging configuration are required beyond creating the delivery itself.&lt;/p&gt; 
&lt;p&gt;To get started, refer to &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-execution-logs-delivery.html" target="_blank" rel="noopener"&gt;Route execution logs with Amazon CloudWatch Logs delivery&lt;/a&gt; in the API Gateway documentation. For more about CloudWatch Logs delivery configuration, see &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html" target="_blank" rel="noopener"&gt;Enable logging from AWS services&lt;/a&gt;. For pricing details, review the &lt;a href="https://aws.amazon.com/cloudwatch/pricing/" target="_blank" rel="noopener"&gt;Amazon CloudWatch pricing page&lt;/a&gt;. Try it on a test stage and share your experience in the comments.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Architecting SASE solutions using AWS Local Zones</title>
		<link>https://aws.amazon.com/blogs/compute/architecting-sase-solutions-using-aws-local-zones/</link>
		
		<dc:creator><![CDATA[Lakshmi VP]]></dc:creator>
		<pubDate>Wed, 09 Sep 2026 20:36:09 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[AWS Local Zones]]></category>
		<category><![CDATA[Best Practices]]></category>
		<guid isPermaLink="false">02c8c6840ad8d0b9f7270e4215277d9d55dca65d</guid>

					<description>Organizations with geographically distributed workforces face a trade-off between security and low-latency access. This post explores how to use AWS Local Zones and Secure Access Service Edge (SASE) solutions to deploy virtual security appliances closer to end users, covering key design principles, capacity planning, and traffic routing.</description>
										<content:encoded>&lt;p&gt;Organizations with geographically distributed workforces face a critical challenge: providing secure, low-latency access to applications without routing all traffic through centralized data centers. Traditional hub-and-spoke network architectures create latency bottlenecks and degrade user experience, forcing a trade-off between security and performance.&lt;/p&gt; 
&lt;p&gt;This post explores how you can use &lt;a href="https://aws.amazon.com/about-aws/global-infrastructure/localzones/" target="_blank" rel="noopener"&gt;AWS Local Zones&lt;/a&gt; and Secure Access Service Edge (SASE) solutions to eliminate that trade-off. You will learn key design principles, implementation strategies, and technical considerations for deploying SASE solutions at the edge. We’ve seen that understanding your user locations and traffic volumes up front helps you make effective design decisions.&lt;/p&gt; 
&lt;h2 id="key-challenges-for-deploying-sase-solutions"&gt;Key challenges for deploying SASE solutions&lt;/h2&gt; 
&lt;p&gt;SASE solutions require virtual security appliances such as firewalls, secure web gateways, and zero trust network access (ZTNA) connectors. You deploy these appliances close to end users so that traffic inspection does not add latency to the user experience. With AWS Local Zones, you can deploy these &lt;a href="https://aws.amazon.com/marketplace/solutions/security" target="_blank" rel="noopener"&gt;virtual security appliances from AWS Marketplace&lt;/a&gt; closer to end users.&lt;/p&gt; 
&lt;p&gt;When you architect SASE solutions using Local Zones, you need to address several key technical challenges. &lt;strong&gt;Latency requirements:&lt;/strong&gt; When end users are far away from an AWS Region, applications requiring security inspection experience significant latency overhead that affects overall performance and user experience. &lt;strong&gt;Geographic coverage&lt;/strong&gt;: In some cases, workforces are spread across distributed locations far from an AWS Region. You need solutions that deliver consistent service quality and security capabilities to users across your covered locations.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Hybrid connectivity&lt;/strong&gt;: Many applications maintain dependencies on on-premises data centers in areas far away from an AWS Region. Design traffic routing carefully to avoid unnecessary network paths and reduce traffic hairpinning or network flapping. &lt;strong&gt;Security consistency&lt;/strong&gt;: Implement uniform security controls across all distributed locations while maintaining performance. This requires consideration of service placement and routing architecture.&lt;/p&gt; 
&lt;p&gt;Before looking at the SASE-specific design, it helps to understand what Local Zones provide. The following diagram shows how Local Zones extend AWS infrastructure from the Region out to metropolitan areas closer to end users.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/09/compute-2397-figure-1.png" alt="High-level AWS infrastructure diagram showing how Local Zones bring compute closer to users" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;Figure 1: High-level AWS infrastructure diagram showing how Local Zones bring compute closer to users&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;As the diagram shows, Local Zones place compute closer to end users. This especially benefits those far from an AWS Region.&lt;/p&gt; 
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt; 
&lt;p&gt;To follow the guidance in this post, you should be familiar with:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;AWS Local Zones and how they extend AWS infrastructure to metro areas.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/ec2/" target="_blank" rel="noopener"&gt;Amazon Elastic Compute Cloud&lt;/a&gt; (Amazon EC2), &lt;a href="https://aws.amazon.com/vpc/" target="_blank" rel="noopener"&gt;Amazon Virtual Private Cloud&lt;/a&gt; (Amazon VPC), and core AWS networking concepts.&lt;/li&gt; 
 &lt;li&gt;SASE architecture concepts and virtual security appliance deployment models.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="architecture-considerations"&gt;Architecture considerations&lt;/h2&gt; 
&lt;p&gt;When you design SASE solutions with Local Zones, you can follow several key best practices across infrastructure, control plane, and traffic management.&lt;/p&gt; 
&lt;h3 id="infrastructure-deployment"&gt;Infrastructure deployment&lt;/h3&gt; 
&lt;p&gt;At the infrastructure level, focus on deploying virtual security appliances to optimize coverage and performance. Start by selecting and configuring Amazon EC2 instances optimized for maximum network throughput. Choose instance families that provide the compute and networking capabilities required for traffic inspection workloads, with enhanced networking enabled for high packets-per-second performance.&lt;/p&gt; 
&lt;p&gt;Design a scalable cluster management strategy that adapts to varying workload demands while maintaining consistent security posture. As you deploy these clusters, establish proper multi-tenant isolation to maintain security boundaries between different organizational units, keeping user resources separate from management infrastructure.&lt;/p&gt; 
&lt;h3 id="control-plane-architecture"&gt;Control plane architecture&lt;/h3&gt; 
&lt;p&gt;The SASE control plane requires particular attention in distributed deployments. Deploy control components in an AWS Region to manage security appliances across all Local Zone locations. This provides a single point of policy distribution and configuration management. From this centralized vantage point, you can implement policy management that maintains consistency in security enforcement across all locations.&lt;/p&gt; 
&lt;p&gt;Visibility matters as much as policy enforcement. Implement standardized telemetry collection mechanisms, such as &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt; metrics and logs, across all locations so you can maintain observability and resolve issues proactively. As your deployment grows, automate configuration deployment using infrastructure as code (IaC) tools such as &lt;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener"&gt;AWS CloudFormation&lt;/a&gt; or Terraform. This keeps deployment consistent across all edge locations and reduces manual errors when operating at scale.&lt;/p&gt; 
&lt;h3 id="traffic-management"&gt;Traffic management&lt;/h3&gt; 
&lt;p&gt;Traffic management completes the architecture of a well-designed SASE solution. Use &lt;a href="https://aws.amazon.com/route53/" target="_blank" rel="noopener"&gt;Amazon Route 53&lt;/a&gt; with geoproximity routing and health checks to direct users to the nearest security inspection point, minimizing inspection latency. If an appliance fails, Route 53 automatically reroutes traffic to the next-nearest Local Zone. For critical deployments, maintain standby capacity in the parent Region as a fallback.&lt;/p&gt; 
&lt;p&gt;Deploy VPN endpoints in Local Zones closest to your user populations to reduce connection latency for remote users while maintaining high availability through health-checked failover across multiple locations. Plan your Internet Service Provider (ISP) connectivity for redundancy and performance requirements across different geographical locations, and implement geographic load-balancing mechanisms to distribute traffic efficiently across available resources.&lt;/p&gt; 
&lt;p&gt;You also need to consider the egress path, which is how traffic exits after inspection. For internet-bound traffic, use the Local Zone’s direct internet egress to avoid routing back through the parent Region. For traffic destined to applications in an AWS Region, traffic traverses the AWS private network between the Local Zone and its parent Region. Validate egress paths using VPC Flow Logs and traceroute to confirm traffic is not taking unintended hops.&lt;/p&gt; 
&lt;p&gt;The following diagram shows how the Local Zones architecture applies to a SASE use case, routing user traffic to a nearby Local Zone for inspection.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/08/ComputeBlog-2397-2.png" alt="Remote users and branch offices routing traffic to virtual network firewalls in the nearest Local Zone, with control nodes in the parent AWS Region" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;Figure 2: Enterprise SASE deployment using virtual network firewalls across Local Zones to secure remote user and branch office access&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;As the diagram shows, remote users and branch offices connect to virtual network firewalls running in the Local Zone closest to them. Each Local Zone performs local traffic inspection that reduces latency for the SASE use case. The control nodes in the parent AWS Region manage policy and configuration across all locations.&lt;/p&gt; 
&lt;h3 id="reference-implementation-approach"&gt;Reference implementation approach&lt;/h3&gt; 
&lt;p&gt;This section outlines the key phases for implementing a SASE solution across AWS Local Zones, from initial planning through validation.&lt;/p&gt; 
&lt;h4 id="phase-1-plan-your-deployment"&gt;Phase 1: Plan your deployment&lt;/h4&gt; 
&lt;p&gt;Begin by mapping your user locations and latency expectations to identify which Local Zones are closest to your user populations, and determine which applications require local security inspection. With this map in hand, calculate capacity needs per location based on expected traffic volumes and security inspection requirements. Then define the specific inspection capabilities you need at each location, whether that is firewall, secure web gateway, ZTNA, or a combination.&lt;/p&gt; 
&lt;p&gt;One key design decision at this stage is whether to route all user traffic through the Local Zone appliance (full tunnel) or only corporate-bound traffic (split tunnel). Full tunnel provides complete traffic visibility but requires higher instance throughput. You can validate your choice by using &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html" target="_blank" rel="noopener"&gt;VPC Flow Logs&lt;/a&gt; and CloudWatch network metrics to measure actual traffic volume per user during a pilot deployment.&lt;/p&gt; 
&lt;h4 id="phase-2-configure-networking-infrastructure"&gt;Phase 2: Configure networking infrastructure&lt;/h4&gt; 
&lt;p&gt;With your plan in place, enable the target Local Zones in your AWS account and create a VPC that extends into your chosen Local Zones by creating subnets in each one. Configure route tables to direct traffic through your virtual security appliances.&lt;/p&gt; 
&lt;p&gt;Security at the network layer is critical. Set up security groups that permit the required traffic flows for your SASE inspection chain. Add inbound rules for user VPN connections (for example, UDP 4500/500 for IPsec), outbound rules to target applications, and management access from the parent Region. Add network ACLs as an additional layer of defense at the subnet level to restrict traffic to expected protocols and port ranges.&lt;/p&gt; 
&lt;h4 id="phase-3-deploy-virtual-security-appliances"&gt;Phase 3: Deploy virtual security appliances&lt;/h4&gt; 
&lt;p&gt;Launch your chosen virtual security appliance from AWS Marketplace in each target Local Zone. Use M6i or M6g instances, or newer instances optimized for network throughput. For example, m6i.xlarge provides up to 12.5 Gbps network bandwidth. Deploy scalable clusters of 2–20 instances depending on location traffic volume, and configure elastic network interfaces for traffic inspection with separate inbound and outbound interfaces.&lt;/p&gt; 
&lt;p&gt;Enable enhanced networking and verify that the instance supports the throughput required for your expected traffic volume. This validation step is critical before moving to production, because undersized instances can become bottlenecks that negate the latency benefits of Local Zone placement.&lt;/p&gt; 
&lt;h4 id="phase-4-configure-the-control-plane"&gt;Phase 4: Configure the control plane&lt;/h4&gt; 
&lt;p&gt;Deploy your centralized SASE management components in the parent AWS Region and establish connectivity between the regional management infrastructure and your Local Zone appliances. Push security policies from the central management console to all distributed appliances to maintain consistent enforcement.&lt;/p&gt; 
&lt;p&gt;For observability, configure centralized logging and telemetry collection using Amazon CloudWatch. Enable VPC Flow Logs on Local Zone subnets to capture traffic metadata for compliance auditing and security analysis. Use this data for troubleshooting and demonstrating regulatory compliance.&lt;/p&gt; 
&lt;h4 id="phase-5-set-up-traffic-routing"&gt;Phase 5: Set up traffic routing&lt;/h4&gt; 
&lt;p&gt;Configure Amazon Route 53 with geoproximity routing policies to direct users to the nearest Local Zone. Set up health checks that automatically fail over if a Local Zone appliance becomes unhealthy. Deploy VPN endpoints in each Local Zone for remote user connectivity.&lt;/p&gt; 
&lt;p&gt;After your routing is configured, test end-to-end connectivity and verify that traffic routes through the nearest security inspection point. This confirms that your geoproximity policies work as intended and that users receive the expected latency benefits.&lt;/p&gt; 
&lt;h4 id="phase-6-validate-and-optimize"&gt;Phase 6: Validate and optimize&lt;/h4&gt; 
&lt;p&gt;With your deployment live, verify latency improvements by comparing round-trip times to the parent AWS Region and to the Local Zones. Monitor appliance utilization metrics (CPU, network throughput, and concurrent sessions) in Amazon CloudWatch, and adjust cluster sizes at each location based on observed traffic patterns. Validate that security policies are applied consistently across all locations.&lt;/p&gt; 
&lt;p&gt;Configure CloudWatch alarms to trigger scaling actions. For example, scale out when average CPU exceeds 70% or network throughput exceeds 80% of instance capacity over a 5-minute period. Use CloudWatch anomaly detection to identify unusual traffic patterns that might indicate a misconfigured routing policy or a security event.&lt;/p&gt; 
&lt;h2 id="capacity-planning"&gt;Capacity planning&lt;/h2&gt; 
&lt;p&gt;Local Zones provide the same elasticity as AWS Regions to scale your virtual security appliances based on demand. To optimize your deployment:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use &lt;a href="https://aws.amazon.com/ec2/autoscaling/" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling&lt;/a&gt; to automatically adjust the number of appliance instances based on traffic patterns and utilization metrics.&lt;/li&gt; 
 &lt;li&gt;Create &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-reservations.html" target="_blank" rel="noopener"&gt;On-Demand Capacity Reservations&lt;/a&gt; to support applications that must provide guaranteed availability at all times.&lt;/li&gt; 
 &lt;li&gt;Design your architecture to work across multiple instance families, giving you flexibility to use the most suitable compute resources available at each location.&lt;/li&gt; 
 &lt;li&gt;For cost optimization, consider using &lt;a href="https://aws.amazon.com/savingsplans/compute-pricing/" target="_blank" rel="noopener"&gt;Compute and EC2 Instance Savings Plans&lt;/a&gt; for steady-state appliance instances that run continuously, while relying on On-Demand pricing for burst capacity during peak traffic periods.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Before production deployment, validate that your chosen virtual appliance functions correctly in the target Local Zone and test network dependencies to confirm expected performance.&lt;/p&gt; 
&lt;h2 id="clean-up"&gt;Clean up&lt;/h2&gt; 
&lt;p&gt;If you deploy resources following this guidance and no longer need them after your testing, terminate EC2 instances, release Elastic IP addresses, delete Capacity Reservations, and remove associated networking resources (subnets, route tables, security groups, Route 53 policies) to avoid ongoing charges.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;This post explored how you can deploy SASE solutions on AWS Local Zones. Local Zones bring three key benefits to SASE architectures. They reduce security inspection latency by placing appliances closer to users, apply consistent security enforcement across geographically distributed locations, and eliminate the need to backhaul traffic to centralized data centers. Organizations continue to expand their operations to more geographic locations. The combination of AWS Local Zones and SASE solutions from partners such as Palo Alto Networks provides a scalable approach for delivering secure connectivity to users anywhere.&lt;/p&gt; 
&lt;h3 id="learn-more"&gt;Learn more&lt;/h3&gt; 
&lt;p&gt;For instructions to opt in to a Local Zone and launch your Amazon EC2 instance, see the &lt;a href="https://docs.aws.amazon.com/local-zones/latest/ug/getting-started.html" target="_blank" rel="noopener"&gt;AWS Local Zones Getting started&lt;/a&gt; page. To learn where AWS Local Zones are available globally, check out the &lt;a href="https://aws.amazon.com/about-aws/global-infrastructure/localzones/locations/" target="_blank" rel="noopener"&gt;AWS Local Zones locations&lt;/a&gt; page.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Announcing 90-minute function timeout on AWS Lambda Managed Instances</title>
		<link>https://aws.amazon.com/blogs/compute/announcing-90-minute-function-timeout-on-aws-lambda-managed-instances/</link>
		
		<dc:creator><![CDATA[Tarun Rai Madan]]></dc:creator>
		<pubDate>Wed, 09 Sep 2026 19:08:14 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Foundational (100)]]></category>
		<guid isPermaLink="false">4cf63fdfce0783e4e432dbac88fece3b77e1837a</guid>

					<description>AWS Lambda now supports a 90-minute function timeout for asynchronous and event source mapping (ESM) invocations on Lambda Managed Instances, a 6x increase from the previous 15-minute limit. Data processing, media transcoding, AI inference, and batch workloads can now run on Lambda without re-architecting.</description>
										<content:encoded>&lt;p&gt;AWS Lambda now supports a 90-minute function timeout for &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html" target="_blank" rel="noopener"&gt;asynchronous&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html" target="_blank" rel="noopener"&gt;event source mapping (ESM)&lt;/a&gt; invocations on AWS Lambda Managed Instances (LMI), a capability of AWS Lambda. This is a 6x increase from the previous 15-minute limit. Customers running data processing, media transcoding, financial calculations, AI inference, and batch workloads can now use Lambda functions for jobs that require longer continuous execution, without re-architecting their applications. This also applies to invocations within &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener"&gt;Lambda durable functions&lt;/a&gt;, which use checkpoints to track progress and automatically recover from failures through replay, skipping completed work. When invoked asynchronously, a multi-step durable execution can run for up to 1 year.&lt;/p&gt; 
&lt;h2 id="evolution-of-function-timeout-on-lambda"&gt;Evolution of function timeout on Lambda&lt;/h2&gt; 
&lt;p&gt;Lambda’s function timeout has increased over time, from 5 minutes at launch in 2014 to 15 minutes in 2018. As customers sought to use the simplicity of Lambda for data-intensive workloads, the 15-minute timeout limit forced architectural tradeoffs for applications where customers needed longer continuous execution time. Several patterns emerged:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Media processing&lt;/strong&gt;: Speech-to-text transcription and video transcoding that routinely need longer than 15 minutes of continuous execution.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Financial calculations&lt;/strong&gt;: Monte Carlo simulations, bond pricing, and portfolio risk analysis that are memory-intensive and often require longer than 15 minutes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Data processing and ETL pipelines&lt;/strong&gt;: Batch jobs processing multi-gigabyte datasets or aggregating data from external sources that exceed 15 minutes during peak volumes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;AI inference&lt;/strong&gt;: Model testing and inference jobs (for example, reasoning tasks) that fit Lambda’s memory and CPU profile but exceed its timeout.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Web scraping and file transfer&lt;/strong&gt;: Crawling external sites or pulling large file sets from vendors that exceed 15 minutes when sources respond slowly.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;In each case, customers preferred Lambda’s simplicity but had to re-architect when jobs hit the 15-minute limit.&lt;/p&gt; 
&lt;p&gt;Fast forward to 2026, Lambda supports two form factors: functions (event-driven, 15-minute timeout), and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-microvms-guide.html" target="_blank" rel="noopener"&gt;MicroVMs&lt;/a&gt; for user or AI-generated just-in-time code (HTTP-driven, 8-hour duration). To allow customers to benefit from the simplicity of serverless compute with the flexibility and pricing model of EC2 for steady-state workloads, we extended the on-demand capacity mode of Lambda to add &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html" target="_blank" rel="noopener"&gt;Lambda Managed Instances&lt;/a&gt; (LMI). With Lambda Managed Instances, you can process multiple concurrent requests per instance, access specialized compute configurations, and drive cost efficiency through EC2 pricing advantages, without managing infrastructure.&lt;/p&gt; 
&lt;p&gt;We also support &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener"&gt;Lambda durable functions&lt;/a&gt; (powered by the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-sdk.html" target="_blank" rel="noopener"&gt;durable execution SDK&lt;/a&gt;) on both on-demand and LMI capacity modes. Durable functions provide application-level checkpointing and workflow-as-code: your code saves execution state using &lt;code&gt;step()&lt;/code&gt; and &lt;code&gt;wait()&lt;/code&gt; operations, and gracefully recovers from infrastructure failures by resuming from the last checkpoint rather than restarting from scratch. While a durable execution (the complete lifecycle of a durable function) can run for up to a year, each invocation was still limited to 15 minutes.&lt;/p&gt; 
&lt;p&gt;As customers onboard more workloads to serverless compute to benefit from its simplicity, they need longer continuous execution for data-intensive use cases like AI inference, media transcoding, scientific modeling, and financial calculations that do not fit Lambda’s 15-minute duration constraints. Today, we are extending the function timeout on Lambda Managed Instances to 90 minutes for asynchronous and ESM invocations. This includes invocations within a durable function, where a multi-step application can continue to run for up to 1 year when invoked asynchronously.&lt;/p&gt; 
&lt;h2 id="activating-90-minute-function-timeout"&gt;Activating 90-minute function timeout&lt;/h2&gt; 
&lt;p&gt;You can now configure any Lambda function running on a Managed Instance with a timeout of up to 90 minutes (5,400 seconds) for async and ESM invocations. Synchronous invocations retain the existing 15-minute maximum. The function executes exactly as before: same runtime, same handler, same IAM execution role, same virtual private cloud (VPC) configuration. The only difference is that your function now supports longer continuous execution. Your initialization code (&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances-execution-environment.html" target="_blank" rel="noopener"&gt;Init phase&lt;/a&gt;) is still limited to 15 minutes on Lambda Managed Instances.&lt;/p&gt; 
&lt;p&gt;To set the timeout, update your function configuration using the AWS CLI:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda update-function-configuration \
    --function-name my-data-processor \
    --timeout 5400 \
    --region us-east-1&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Or in AWS CloudFormation / AWS Serverless Application Model (AWS SAM):&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;MyFunction:
  Type: AWS::Serverless::Function
  Properties:
    FunctionName: my-data-processor
    Runtime: python3.12
    Handler: app.handler
    Timeout: 5400
    MemorySize: 10240&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;You do not need to change any code. You can also update the timeout from the Lambda console under Configuration &amp;gt; General Configuration (&lt;strong&gt;Figure 1&lt;/strong&gt;), or configure it through natural language prompts in your AI coding assistants (like Claude Code or Kiro) by installing the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/agent-setup-guide.html" target="_blank" rel="noopener"&gt;Agent Toolkit for AWS&lt;/a&gt;.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/03/ComputeBlog-2727-1.png" alt="Lambda console General configuration page showing the function timeout field set to 90 minutes" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;Figure 1: Configuring Lambda function timeout&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;The change takes effect on subsequent invocations after the function timeout is updated. For event source mappings, allow a few minutes for the new configuration to propagate. Your existing observability setup continues to work as expected: Amazon CloudWatch metrics, AWS CloudTrail, and AWS X-Ray capture the full invocation lifecycle without any changes. For details, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-monitoring.html" target="_blank" rel="noopener"&gt;monitoring Lambda functions&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-monitoring.html" target="_blank" rel="noopener"&gt;monitoring durable functions&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;There is no additional charge for using the 90-minute timeout. Standard &lt;a href="https://aws.amazon.com/lambda/pricing/" target="_blank" rel="noopener"&gt;Lambda Managed Instances pricing&lt;/a&gt; applies.&lt;/p&gt; 
&lt;h2 id="minute-timeout-and-durable-functions"&gt;90-minute timeout and durable functions&lt;/h2&gt; 
&lt;p&gt;The 90-minute function timeout and durable functions are complementary. The &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html" target="_blank" rel="noopener"&gt;function timeout&lt;/a&gt; (&lt;code&gt;--timeout&lt;/code&gt;) controls how long each individual invocation can run, while the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-configuration.html" target="_blank" rel="noopener"&gt;durable execution timeout&lt;/a&gt; (&lt;code&gt;ExecutionTimeout&lt;/code&gt; in &lt;code&gt;--durable-config&lt;/code&gt;) controls the total elapsed time from execution start to completion. Durable functions use checkpoints to track progress and automatically recover from failures through replay, re-executing from the beginning while skipping completed work. With today’s launch, each asynchronous invocation in a durable function running on a Managed Instance can now execute for up to 90 minutes continuously, while the corresponding durable execution can run for up to 1 year. For synchronous and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-invoking-esm.html" target="_blank" rel="noopener"&gt;event source mapping invocations&lt;/a&gt;, both the invocation and the corresponding durable execution are limited to 90 minutes.&lt;/p&gt; 
&lt;p&gt;For idempotent jobs (for example, an ETL pipeline step triggered by SQS), the extended timeout alone might be sufficient. If the host fails, the message returns to the queue and a fresh invocation starts. For jobs where re-execution is expensive (for example, a 40-minute inference run already 30 minutes in), combine both. Enable durable functions to checkpoint periodically, so a failure at minute 35 resumes from the last checkpoint rather than restarting from zero.&lt;/p&gt; 
&lt;h2 id="invocation-behavior-asynchronous-event-source-mappings-and-synchronous"&gt;Invocation behavior: asynchronous, event source mappings, and synchronous&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Asynchronous invocations (up to 90 minutes)&lt;/strong&gt;: If the function fails or times out, Lambda applies your configured retry policy (up to two retries by default) and routes failed events to your dead-letter queue or on-failure destination.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Event source mappings (up to 90 minutes)&lt;/strong&gt;: For SQS, configure your queue’s visibility timeout to be &lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-lambda-function-trigger.html" target="_blank" rel="noopener"&gt;at least six times&lt;/a&gt; the function timeout. This gives Lambda enough time to retry if a function is throttled while processing a previous batch. Lambda validates this at event source mapping creation time, but does not prevent subsequent changes to queue or function settings that might create a mismatch.&lt;/p&gt; 
&lt;p&gt;For Amazon Kinesis and Amazon DynamoDB Streams, configure the &lt;a href="https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumBatchingWindowInSeconds" target="_blank" rel="noopener"&gt;maximum batching window&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor" target="_blank" rel="noopener"&gt;parallelization factor&lt;/a&gt; to account for longer processing times per batch.&lt;/p&gt; 
&lt;p&gt;If your batch contains multiple records and you want to avoid re-processing the entire batch when one record fails, enable &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-batchfailurereporting.html" target="_blank" rel="noopener"&gt;partial batch failure reporting&lt;/a&gt;. This is available for SQS, Kinesis, DynamoDB Streams, Amazon Managed Streaming for Apache Kafka (Amazon MSK), and self-managed Apache Kafka event source mappings. With partial batch failures enabled, only the failed records are retried, not the entire batch.&lt;/p&gt; 
&lt;p&gt;Note that invocations for &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html" target="_blank" rel="noopener"&gt;Amazon MQ ESM&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/with-documentdb.html" target="_blank" rel="noopener"&gt;Amazon DocumentDB (with MongoDB compatibility) ESM&lt;/a&gt; remain limited to 15 minutes.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Synchronous invocations (15 minutes maximum)&lt;/strong&gt;: &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-sync.html" target="_blank" rel="noopener"&gt;Synchronous invocations&lt;/a&gt; retain the existing 15-minute maximum timeout. If you set your function timeout to greater than 15 minutes and invoke it synchronously, Lambda continues to apply the 15-minute timeout. The &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/lambda/get-function-configuration.html" target="_blank" rel="noopener"&gt;GetFunctionConfiguration API&lt;/a&gt; reports the configured timeout value.&lt;/p&gt; 
&lt;p&gt;To see which event sources invoke Lambda functions synchronously or asynchronously, refer to &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html" target="_blank" rel="noopener"&gt;Lambda documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="considerations-and-best-practices"&gt;Considerations and best practices&lt;/h2&gt; 
&lt;p&gt;Because your functions now support longer continuous execution, consider these best practices for components that might be ephemeral in nature, such as network connections and credentials.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Networking&lt;/strong&gt;: Make sure idle connection timeouts on downstream services (RDS, Amazon ElastiCache, external APIs) accommodate the full function duration. If your function routes traffic through a NAT Gateway, send keep-alive packets to prevent idle connections from being dropped (350-second idle timeout). Respect DNS TTL values for external hostname resolution. The AWS SDK handles this automatically, but custom HTTP clients might cache DNS records beyond their TTL.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Credentials&lt;/strong&gt;: If your function acquires temporary credentials or tokens, verify they remain valid for the full execution duration or refresh them in the background.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Idempotency&lt;/strong&gt;: Lambda does not guarantee exactly-once processing. With longer-running functions, the window for retries and duplicate deliveries increases. You can use &lt;a href="https://docs.aws.amazon.com/powertools/python/latest/utilities/idempotency/" target="_blank" rel="noopener"&gt;Powertools for AWS Lambda&lt;/a&gt; to implement idempotency in your function code so that operations like payments or database writes produce the same result even if executed more than once. If you use Lambda durable functions, steps have at-least-once execution semantics by default. The SDK skips completed steps during replay, but steps that fail before checkpointing may re-execute. You can use &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-idempotency.html" target="_blank" rel="noopener"&gt;execution names&lt;/a&gt; as idempotency keys for durable functions.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;The 90-minute function timeout on Lambda Managed Instances addresses one of the most common customer needs for building data-intensive applications on AWS Lambda. Data processing, media transcoding, AI inference, and financial computation workloads that exceed 15 minutes can now run on Lambda without code changes or architectural workarounds. We look forward to hearing from you if you need a longer timeout for synchronous invocations, or for the on-demand capacity mode, on our &lt;a href="https://github.com/aws/aws-lambda-roadmap" target="_blank" rel="noopener"&gt;AWS Lambda Roadmap GitHub page&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;To get started, update your function’s timeout configuration and deploy. For a step-by-step walkthrough, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html" target="_blank" rel="noopener"&gt;Getting started with Lambda Managed Instances&lt;/a&gt;. For sample code demonstrating long-running functions with durable checkpointing, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-examples.html" target="_blank" rel="noopener"&gt;durable functions examples&lt;/a&gt;. To learn more about AWS Lambda, visit &lt;a href="https://aws.amazon.com/lambda" target="_blank" rel="noopener"&gt;aws.amazon.com/lambda&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Bring your own client certificate for backend mTLS in Amazon API Gateway</title>
		<link>https://aws.amazon.com/blogs/compute/bring-your-own-client-certificate-for-backend-mtls-in-amazon-api-gateway/</link>
		
		<dc:creator><![CDATA[Biswanath Mukherjee]]></dc:creator>
		<pubDate>Tue, 08 Sep 2026 21:46:39 +0000</pubDate>
				<category><![CDATA[Amazon API Gateway]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Intermediate (200)]]></category>
		<guid isPermaLink="false">aefa41ad59da632a3771c6831f7d2b0ebe00b502</guid>

					<description>Enterprises that use Amazon API Gateway often want to bring their own client certificate for backend mutual TLS (mTLS) authentication. With API Gateway, you can now use a third-party or AWS Private CA-issued client certificate for the outbound mTLS handshake. In this post, you build a REST API with an outbound mTLS connection to an Amazon ECS backend.</description>
										<content:encoded>&lt;p&gt;Enterprises that use &lt;a href="https://aws.amazon.com/api-gateway/" target="_blank" rel="noopener"&gt;Amazon API Gateway&lt;/a&gt; in front of internal or partner backends often want to bring their own client certificate for backend mutual TLS (mTLS) authentication. During mTLS, the backend presents its own server certificate and also requests the caller to present a client certificate to validate it against a trusted certificate authority (CA). Until now, you could use only an API Gateway-generated, self-signed SSL certificate for the outbound connection, because there was no CA behind it for the backend to trust. Backends that enforce a specific corporate or partner CA reject that self-signed certificate, and the mutual TLS handshake fails. Bringing your own CA-signed certificate is necessary for scenarios such as migrating APIs off legacy gateways or meeting your internal PKI mandates that require certificates from an approved CA.&lt;/p&gt; 
&lt;p&gt;With API Gateway, you can now bring your own client certificate for backend mutual TLS (mTLS) authentication. You can either use a third-party certificate or a certificate issued by &lt;a href="https://aws.amazon.com/private-ca/" target="_blank" rel="noopener"&gt;AWS Private Certificate Authority&lt;/a&gt;. If you’re using a third-party certificate, you must &lt;a href="https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html" target="_blank" rel="noopener"&gt;import&lt;/a&gt; the certificate in &lt;a href="https://aws.amazon.com/certificate-manager/" target="_blank" rel="noopener"&gt;AWS Certificate Manager (ACM)&lt;/a&gt;. Then you &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-acm-client-certificates.html" target="_blank" rel="noopener"&gt;configure the ACM certificate ARN in your REST API stage&lt;/a&gt;. API Gateway presents that certificate during the backend mTLS handshake.&lt;/p&gt; 
&lt;h1&gt;Solution overview&lt;/h1&gt; 
&lt;p&gt;In this post, you build a REST API with an outbound mTLS connection using this newly launched API Gateway feature. This solution demonstrates an outbound mTLS connection between Amazon API Gateway and a backend application running on &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html" target="_blank" rel="noopener"&gt;Amazon Elastic Container Service (Amazon ECS)&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The following diagram shows the solution architecture.&lt;/p&gt; 
&lt;figure&gt; 
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/08/ComputeBlog-2657-1.png" alt="Architecture diagram showing API Gateway presenting an ACM client certificate to a Network Load Balancer that forwards traffic to an NGINX sidecar and validator app on Amazon ECS Fargate, with certificates issued by AWS Private CA through ACM" width="800"&gt;
 &lt;figcaption aria-hidden="true"&gt;
  Architecture diagram showing API Gateway presenting an ACM client certificate to a Network Load Balancer that forwards traffic to an NGINX sidecar and validator app on Amazon ECS Fargate, with certificates issued by AWS Private CA through ACM
 &lt;/figcaption&gt;
&lt;/figure&gt; 
&lt;p&gt;The solution uses:&lt;/p&gt; 
&lt;ol type="a"&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://aws.amazon.com/private-ca/" target="_blank" rel="noopener"&gt;AWS Private Certificate Authority&lt;/a&gt; with a root-subordinate CA hierarchy to issue both the client and server certificates through &lt;a href="https://aws.amazon.com/certificate-manager/" target="_blank" rel="noopener"&gt;AWS Certificate Manager (ACM)&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://aws.amazon.com/api-gateway/" target="_blank" rel="noopener"&gt;Amazon API Gateway&lt;/a&gt; REST API stage configured with the ACM client certificate ARN (ClientCertificateId), so that the API Gateway presents the certificate during the outbound TLS handshake.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://aws.amazon.com/ecs/" target="_blank" rel="noopener"&gt;Amazon ECS&lt;/a&gt; on &lt;a href="https://aws.amazon.com/fargate/" target="_blank" rel="noopener"&gt;AWS Fargate&lt;/a&gt; running an NGINX sidecar that holds the server certificate and validates the incoming client certificate against a CA bundle (root and subordinate chain).&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;A request goes through the following steps:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt; &lt;p&gt;Client application invokes the REST API exposed by API Gateway. The API Gateway stage is configured with an ACM client certificate ARN.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;API Gateway opens an outbound connection to the &lt;a href="https://aws.amazon.com/elasticloadbalancing/network-load-balancer/" target="_blank" rel="noopener"&gt;Network Load Balancer&lt;/a&gt; (NLB) to begin the TLS handshake. The API Gateway presents an ACM client certificate configured at the stage level when the backend requests one.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The NLB listens for the incoming TCP request on port 443 and forwards the call to Amazon ECS Fargate. The NLB acts as a passthrough and does not terminate the TLS connection.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The NGINX sidecar container running on Amazon ECS performs the inbound mTLS handshake:&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;NGINX presents the backend server certificate and verifies the client certificate against a mounted CA bundle (root and subordinate chain).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;After verification, NGINX forwards the request and parsed certificate details to the validator app container over local HTTP.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The validator app re-checks the certificate validity window, matches the common name against an allowlist, and returns a structured JSON response.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The NGINX sidecar is not mandatory for this flow. It demonstrates separation of concerns: NGINX handles the mTLS handshake, and the validator app contains the business logic.&lt;/p&gt; 
&lt;h1&gt;Prerequisites for demo&lt;/h1&gt; 
&lt;p&gt;To follow along, you need the following:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://portal.aws.amazon.com/gp/aws/developer/registration/index.html" target="_blank" rel="noopener"&gt;Create an AWS account&lt;/a&gt; if you do not already have one.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Access to an AWS account through the AWS Management Console and the &lt;a href="https://aws.amazon.com/cli" target="_blank" rel="noopener"&gt;AWS Command Line Interface (AWS CLI)&lt;/a&gt;. The &lt;a href="https://aws.amazon.com/iam" target="_blank" rel="noopener"&gt;AWS Identity and Access Management (IAM)&lt;/a&gt; principal you use must have permissions to make the necessary AWS service calls and manage the resources in this post. Follow the &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html" target="_blank" rel="noopener"&gt;principle of least privilege&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" target="_blank" rel="noopener"&gt;Git installed&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM) CLI installed&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://www.docker.com/" target="_blank" rel="noopener"&gt;Docker&lt;/a&gt; installed and running, to build and push the two container images.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Python 3.14 installed.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;jq command line tools installed.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Environment setup&lt;/h1&gt; 
&lt;p&gt;Run the following commands to set up the demo environment:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt; &lt;p&gt;Create a new folder and clone the GitHub repository:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;git clone https://github.com/aws-samples/sample-api-backend-mtls
cd sample-api-backend-mtls&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Set the environment variables after replacing the placeholders:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=&amp;lt;Your AWS Region, for example, us-east-1&amp;gt;
STACK_NAME=&amp;lt;Your stack name e.g. outbound-mtls-backend&amp;gt;&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Build the container images&lt;/h1&gt; 
&lt;p&gt;Run the following commands to create container images of NGINX sidecar container and the validator app containers:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt; &lt;p&gt;Create two Amazon Elastic Container Registry (Amazon ECR) repositories, one for NGINX and another for validator app containers respectively:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;NGINX_REPO_URI=$(aws ecr create-repository \
  --repository-name $STACK_NAME-nginx-sidecar \
  --image-tag-mutability IMMUTABLE \
  --image-scanning-configuration scanOnPush=true \
  --region "$REGION" \
  --query "repository.repositoryUri" --output text)

VALIDATOR_REPO_URI=$(aws ecr create-repository \
  --repository-name $STACK_NAME-validator-app \
  --image-tag-mutability IMMUTABLE \
  --image-scanning-configuration scanOnPush=true \
  --region "$REGION" \
  --query "repository.repositoryUri" --output text)

aws ecr get-login-password --region "$REGION" \
  | docker login --username AWS --password-stdin "${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Build and push the NGINX and validator app containers:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;docker build --platform linux/amd64 -t $STACK_NAME-nginx-sidecar nginx/
docker tag $STACK_NAME-nginx-sidecar:latest "${NGINX_REPO_URI}:latest"
docker push "${NGINX_REPO_URI}:latest"
docker build --platform linux/amd64 -t $STACK_NAME-validator-app validator_app/
docker tag $STACK_NAME-validator-app:latest "${VALIDATOR_REPO_URI}:latest"
docker push "${VALIDATOR_REPO_URI}:latest"&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Deploy and test the solution&lt;/h1&gt; 
&lt;p&gt;You first deploy the stack without the client certificate configured in the API Gateway and perform negative testing. The mTLS handshake will fail because of a missing client certificate in the request. Then you update the stack to configure client certificate in API Gateway stage and retest mTLS.&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt; &lt;p&gt;Run the following command to build and deploy the overall stack without client certificate configured at API Gateway stage:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;sam build
sam deploy \
  --stack-name $STACK_NAME \
  --resolve-s3 \
  --capabilities CAPABILITY_IAM \
  --region "$REGION" \
  --parameter-overrides \
  NginxRepositoryUri="$NGINX_REPO_URI" \
  ValidatorRepositoryUri="$VALIDATOR_REPO_URI" \
  EnableOutboundMtls=false&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Wait for the task to reach &lt;code&gt;RUNNING&lt;/code&gt; and pass its target group health check:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;EcsClusterName=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='EcsClusterName'].OutputValue" \
  --output text)

TargetGroupArn=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='TargetGroupArn'].OutputValue" \
  --output text)

aws ecs list-tasks --cluster "$EcsClusterName" --region "$REGION"

aws elbv2 describe-target-health \
  --target-group-arn "$TargetGroupArn" --region "$REGION"&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Capture the front API invoke URL from the stack outputs:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;FRONT_API_URL=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='FrontApiUrl'].OutputValue" \
  --output text)

NLB_DNS_NAME=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='NlbDnsName'].OutputValue" \
  --output text)

FRONT_CLIENT_CERT_ARN=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='FrontClientCertArn'].OutputValue" \
  --output text)

FRONT_API_ID=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region "$REGION" \
  --query "Stacks[0].Outputs[?OutputKey=='FrontApiId'].OutputValue" \
  --output text)&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Wait a minute or two after the stack finishes, then invoke the front API:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;curl -v "$FRONT_API_URL"&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;p&gt;The following is the NGINX configuration for mTLS:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-nginx"&gt;...
server {
    listen 443 ssl;
    # Server identity (issued by the private CA).
    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;
    # Inbound mutual TLS: require and validate the client certificate
    # against the CA bundle (root + subordinate CA chain).
    ssl_client_certificate /etc/nginx/certs/ca_bundle.pem;
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_protocols TLSv1.2;
...}&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;p&gt;The &lt;code&gt;curl&lt;/code&gt; command returns &lt;code&gt;HTTP/2 400&lt;/code&gt;, with a response body containing &lt;code&gt;400 No required SSL certificate was sent&lt;/code&gt;. Because the API Gateway is not presenting a client certificate on the outbound handshake, the NGINX sidecar container in Amazon ECS rejects the mTLS connection. The following screenshot shows the response:&lt;/p&gt; 
  &lt;figure&gt; 
   &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/08/ComputeBlog-2657-2.png" alt="Terminal response showing an HTTP/2 400 error with the message No required SSL certificate was sent" width="800"&gt;
   &lt;figcaption aria-hidden="true"&gt;
    Terminal response showing an HTTP/2 400 error with the message No required SSL certificate was sent
   &lt;/figcaption&gt;
  &lt;/figure&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Now redeploy the solution with outbound mTLS enabled:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;sam deploy \
  --stack-name $STACK_NAME \
  --resolve-s3 \
  --capabilities CAPABILITY_IAM \
  --region "$REGION" \
  --parameter-overrides \
  NginxRepositoryUri="$NGINX_REPO_URI" \
  ValidatorRepositoryUri="$VALIDATOR_REPO_URI" \
  EnableOutboundMtls=true&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Wait a minute or two after the stack finishes, then invoke the front API again:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;curl -v "$FRONT_API_URL"&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;p&gt;Because the client certificate is now presented during the mTLS handshake, the handshake completes successfully, as shown in the following response snippet:&lt;/p&gt; 
  &lt;figure&gt; 
   &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/08/ComputeBlog-2657-3.png" alt="Terminal response showing a successful mTLS handshake and an HTTP 200 response from the backend" width="800"&gt;
   &lt;figcaption aria-hidden="true"&gt;
    Terminal response showing a successful mTLS handshake and an HTTP 200 response from the backend
   &lt;/figcaption&gt;
  &lt;/figure&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Automatic certificate renewal&lt;/h1&gt; 
&lt;p&gt;When a certificate changes in ACM, API Gateway detects the update and propagates the new certificate automatically. You do not redeploy the stage, and the API experiences no downtime during rotation. Certificate propagation is eventually consistent. During an update, the backend might briefly receive either the old or the new certificate. ACM also emits certificate expiration notifications through Amazon EventBridge, which you can use to set alarms before a certificate expires.&lt;/p&gt; 
&lt;h1&gt;Clean up&lt;/h1&gt; 
&lt;p&gt;If you followed along only for demonstration purposes, to avoid incurring future charges, run the following commands to delete the resources created in this demo:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt; &lt;p&gt;Clean up the S3 buckets:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;NLB_LOGS_BUCKET=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME --region $REGION \
  --query "Stacks[0].Outputs[?OutputKey=='NlbAccessLogsBucketName'].OutputValue" \
  --output text)

aws s3api list-object-versions --bucket "$NLB_LOGS_BUCKET" \
  --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' \
  --output json | \
  jq -c '.Objects[]? // empty' | \
  while read -r obj; do
    aws s3api delete-object --bucket "$NLB_LOGS_BUCKET" \
      --key "$(echo "$obj" | jq -r .Key)" \
      --version-id "$(echo "$obj" | jq -r .VersionId)" \
      --region $REGION
  done

aws s3api list-object-versions --bucket "$NLB_LOGS_BUCKET" \
  --query '{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}' \
  --output json | \
  jq -c '.Objects[]? // empty' | \
  while read -r obj; do
    aws s3api delete-object --bucket "$NLB_LOGS_BUCKET" \
      --key "$(echo "$obj" | jq -r .Key)" \
      --version-id "$(echo "$obj" | jq -r .VersionId)" \
      --region $REGION
  done&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Delete the stack:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;sam delete --stack-name $STACK_NAME --region $REGION --no-prompts&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Delete the ECR repository:&lt;/p&gt; 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws ecr delete-repository --repository-name $STACK_NAME-nginx-sidecar --force --region $REGION
aws ecr delete-repository --repository-name $STACK_NAME-validator-app --force --region $REGION&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Conclusion&lt;/h1&gt; 
&lt;p&gt;In this post, you configured a REST API with an outbound mTLS connection using Amazon API Gateway and an ECS Fargate backend. With this new feature launch in API Gateway, you can now bring your own client certificate for outbound mTLS handshake for your REST APIs. You can now meet your internal PKI mandates to authenticate backends that pin a specific certificate issuer.&lt;/p&gt; 
&lt;p&gt;To get started, import a certificate from your own PKI into ACM and configure your API Gateway REST API stage for outbound mTLS authentication. For more information, see &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-backend-authentication.html" target="_blank" rel="noopener"&gt;Present client certificates to backend services with mutual TLS in API Gateway&lt;/a&gt;. If you have feedback about this post, leave it in the comments section. For technical questions, you can start a thread on &lt;a href="https://repost.aws/" target="_blank" rel="noopener"&gt;AWS re:Post&lt;/a&gt;.&lt;/p&gt; 
&lt;h1&gt;Further reading&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-backend-authentication.html" target="_blank" rel="noopener"&gt;Present client certificates to backend services with mutual TLS in API Gateway&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html" target="_blank" rel="noopener"&gt;Amazon API Gateway REST API client certificates&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-extensions-integration-tls-config.html" target="_blank" rel="noopener"&gt;Integration tlsConfig reference&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html" target="_blank" rel="noopener"&gt;Importing certificates into AWS Certificate Manager&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html" target="_blank" rel="noopener"&gt;Requesting a private certificate with AWS Private CA&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/compute/automating-mutual-tls-setup-for-amazon-api-gateway/" target="_blank" rel="noopener"&gt;Automating mutual TLS setup for Amazon API Gateway&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Scheduling email campaigns at scale with Amazon EventBridge Scheduler</title>
		<link>https://aws.amazon.com/blogs/compute/scheduling-email-campaigns-at-scale-with-amazon-eventbridge-scheduler/</link>
		
		<dc:creator><![CDATA[Oluwaseun Ademuwagun]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 13:09:17 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[Amazon EventBridge]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">3d9219b43bd0b9bef7ea2475c46079b1c0370b4f</guid>

					<description>Learn how to use Amazon EventBridge Scheduler to deliver email campaigns at per-recipient optimal send times. This post shows how to create one schedule per recipient with zero idle compute cost, scale schedule creation with AWS Step Functions Distributed Map, and deliver through Amazon SES.</description>
										<content:encoded>&lt;p&gt;Scheduling email campaigns becomes more complex when you need to send email to millions of recipients at the unique time best suited for each customer. Consider these examples:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A flash sale might need to hit inboxes at 9 AM local time across every time zone.&lt;/li&gt; 
 &lt;li&gt;A follow-up email (often known as a drip sequence) might need to send a second message exactly 3 days after the first message per subscriber.&lt;/li&gt; 
 &lt;li&gt;A re-engagement campaign might target users who haven’t logged in for 30 days.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The scheduling requirements involve multiple considerations. You’re sending hundreds of millions of messages, each at its own optimal moment personalized to the recipient’s time zone and behavior.&lt;/p&gt; 
&lt;p&gt;In this post, we walk through how to use &lt;a href="https://aws.amazon.com/eventbridge/scheduler/" target="_blank" rel="noopener"&gt;Amazon EventBridge Scheduler&lt;/a&gt; to personalize email notifications to each recipient. We create one schedule per recipient to deliver each email at its individually optimal moment, with zero idle compute cost. We also show how Amazon EventBridge Scheduler handles higher volumes. Amazon EventBridge Scheduler supports billions of schedules. By default, you have a quota of &lt;a href="https://docs.aws.amazon.com/scheduler/latest/UserGuide/scheduler-quotas.html" target="_blank" rel="noopener"&gt;10 million schedules&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="solution-overview"&gt;Solution overview&lt;/h2&gt; 
&lt;p&gt;When every recipient has their own ideal delivery time, you need a scheduling layer that can hold billions of individual send intents and fire each one at the right moment. Most teams reach for one of three familiar patterns, each with tradeoffs that become painful at scale.&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;&lt;strong&gt;Batch cron jobs&lt;/strong&gt;: A job runs every hour, queries for all messages due in the next window, and sends them out. Recipients get email in imprecise hourly batches. At scale, the batch job itself becomes a bottleneck, processing millions of rows per run, competing for database connections, and creating a sudden spike in load on the email provider.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Delay queues&lt;/strong&gt;: You can use Amazon Simple Queue Service (Amazon SQS) as a delay queue. A delay queue postpones the delivery of new messages to a customer for a set time. A limitation of this approach is that Amazon SQS caps delays at 15 minutes.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Third-party campaign tools&lt;/strong&gt;: Offload to a SaaS email platform. This works until you need tight integration with your application data, custom send-time optimization, or control over delivery infrastructure. You’re also paying per-recipient fees that compound at scale.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;All three approaches either sacrifice precision (batching), hit architectural limits (delay queues), or surrender control (third-party tools).&lt;/p&gt; 
&lt;h3 id="the-building-block-approach"&gt;The building block approach&lt;/h3&gt; 
&lt;p&gt;Amazon EventBridge Scheduler treats each email send as a discrete scheduled action. Instead of “process all messages due this hour,” you express the intent directly: “send this email to this person at this time.” Amazon EventBridge Scheduler holds that intent with zero compute cost until the moment arrives, then triggers the scheduled action. See the &lt;a href="https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html" target="_blank" rel="noopener"&gt;Amazon EventBridge Scheduler User Guide&lt;/a&gt; for the full API reference and current service quotas.&lt;/p&gt; 
&lt;p&gt;For email campaigns, Amazon EventBridge Scheduler becomes the &lt;strong&gt;send-time dispatcher&lt;/strong&gt;, the component that schedules every email in a campaign for its individually optimal moment, whether that’s timezone-adjusted, behavior-triggered, or sequence-driven.&lt;/p&gt; 
&lt;h2 id="architecture-diagram"&gt;Architecture diagram&lt;/h2&gt; 
&lt;p&gt;The architecture follows an event-driven, per-recipient scheduling pattern for an email campaign. To start the campaign, you first define the target audience and the content they receive. Next, you need a way to create the per-recipient schedule. To do that for a campaign that can contain millions of recipients, you need a scalable mechanism to create the schedules. You can achieve this with an &lt;a href="https://aws.amazon.com/step-functions/" target="_blank" rel="noopener"&gt;AWS Step Functions&lt;/a&gt; state machine, a serverless workflow service that coordinates multiple AWS services into structured, visual workflows called state machines. In this solution, we orchestrate the creation of the schedules by using a &lt;a href="https://docs.aws.amazon.com/step-functions/latest/dg/state-map-distributed.html" target="_blank" rel="noopener"&gt;Distributed Map&lt;/a&gt; state within the state machine, which lets us fan out and accelerate schedule creation. It does this by splitting a large dataset into chunks and processing them across thousands of parallel child executions. It reads the recipient list from Amazon Simple Storage Service (Amazon S3), applies time zone logic per recipient, and creates an individual Amazon EventBridge Scheduler resource for each recipient in parallel. After the workflow creates all schedules, the execution completes.&lt;/p&gt; 
&lt;p&gt;The actual email delivery happens later, entirely decoupled from the campaign creation step. At the scheduled time, Amazon EventBridge Scheduler invokes &lt;a href="https://aws.amazon.com/ses/" target="_blank" rel="noopener"&gt;Amazon Simple Email Service&lt;/a&gt; (Amazon SES) directly, passing the template name and personalization data as template variables. For campaigns requiring complex personalization logic (conditional content, real-time suppression checks, or data enrichment), you can optionally route through an AWS Lambda function before SES. If you need to adjust timing or content for specific recipients, you can update their individual schedules directly without reprocessing the entire campaign.&lt;/p&gt; 
&lt;p style="text-align: center"&gt;&lt;a href="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/01/compute-2689-arch.png"&gt;&lt;img loading="lazy" class="alignnone wp-image-26863 size-full" src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/09/01/compute-2689-arch.png" alt="" width="781" height="592"&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 1: Per-recipient email scheduling architecture with Amazon EventBridge Scheduler&lt;/em&gt;&lt;/p&gt; 
&lt;h2 id="walkthrough"&gt;Walkthrough&lt;/h2&gt; 
&lt;p&gt;The solution uses four core components that work together: a campaign manager to define send-time rules, Step Functions Distributed Map to fan out and accelerate schedule creation, Amazon EventBridge Scheduler to hold each per-recipient intent and deliver through Amazon SES directly, and automatic cleanup through schedule self-deletion.&lt;/p&gt; 
&lt;h3 id="how-it-works"&gt;How it works&lt;/h3&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;&lt;strong&gt;Create the campaign&lt;/strong&gt;: A marketer defines the campaign: audience segment, email template, and send-time rules (for example, “9 AM in each recipient’s local time zone” or “24 hours before a Black Friday sale”).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Campaign manager fans out&lt;/strong&gt;: An &lt;a href="https://aws.amazon.com/step-functions/" target="_blank" rel="noopener"&gt;AWS Step Functions&lt;/a&gt; workflow uses Distributed Map to iterate over the recipient list and create one Amazon EventBridge Scheduler schedule per recipient per campaign step directly through SDK integration. Each schedule encodes the exact send time for that individual.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon EventBridge Scheduler fires at the right moment&lt;/strong&gt;: At each recipient’s scheduled time, Amazon EventBridge Scheduler invokes Amazon SES directly through a universal target, passing the template name and personalization data (recipient name and attributes) as template variables.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;SES personalizes and sends&lt;/strong&gt;: Amazon SES renders the email template with the provided data and delivers the message.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Schedule self-deletes&lt;/strong&gt;: &lt;code&gt;ActionAfterCompletion='DELETE'&lt;/code&gt; prevents the accumulation of spent schedules.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt; 
&lt;p&gt;To follow along with this walkthrough, you need the following:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;AWS account and permissions&lt;/strong&gt;: An active AWS account with permissions to create Amazon EventBridge Scheduler schedules, AWS Step Functions state machines, and Amazon SES identities, along with an AWS Identity and Access Management (IAM) role for Amazon EventBridge Scheduler to invoke Amazon SES.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Development environment&lt;/strong&gt;: Python 3.13 or later, AWS SDK for Python (Boto3) version 1.26 or later, and AWS Command Line Interface v2 (&lt;a href="https://aws.amazon.com/cli/" target="_blank" rel="noopener"&gt;AWS CLI&lt;/a&gt; v2).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon SES configuration&lt;/strong&gt;: Move your Amazon SES account &lt;a href="https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html" target="_blank" rel="noopener"&gt;out of sandbox mode&lt;/a&gt; to allow sending to arbitrary recipients.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="scaling-the-fan-out-with-step-functions"&gt;Scaling the fan-out with Step Functions&lt;/h3&gt; 
&lt;p&gt;For campaigns with millions of recipients, use AWS Step Functions Distributed Map to parallelize schedule creation. When you want to activate a campaign, you trigger a Step Functions workflow. This workflow fans out and creates schedules across the recipient list by using a Distributed Map with direct SDK integration. The direct SDK integration between Step Functions and Amazon EventBridge Scheduler lets each child execution call &lt;code&gt;CreateSchedule&lt;/code&gt; directly. The following state machine definition reads recipients from an Amazon S3 CSV file and creates schedules in parallel:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Comment": "Fan out campaign schedule creation via direct SDK integration",
  "StartAt": "EnsureScheduleGroup",
  "States": {
    "EnsureScheduleGroup": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:scheduler:createScheduleGroup",
      "Parameters": {
        "Name.$": "States.Format('campaign-{}', $.campaign_id)"
      },
      "ResultPath": null,
      "Catch": [
        {
          "ErrorEquals": [
            "Scheduler.ConflictException"
          ],
          "ResultPath": null,
          "Next": "FanOutRecipients"
        }
      ],
      "Next": "FanOutRecipients"
    },
    "FanOutRecipients": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": {
          "Mode": "DISTRIBUTED",
          "ExecutionType": "STANDARD"
        },
        "StartAt": "BuildScheduleInput",
        "States": {
          "BuildScheduleInput": {
            "Type": "Pass",
            "Parameters": {
              "schedule_name.$": "States.Format('campaign-{}-{}', $.campaign_id, $.recipient.id)",
              "group_name.$": "States.Format('campaign-{}', $.campaign_id)",
              "schedule_expression.$": "States.Format('at({}T{}:00:00)', $.send_date_date, $.send_hour)",
              "timezone.$": "$.recipient.timezone",
              "target_input": {
                "FromEmailAddress": "campaigns@example.com",
                "Destination": {
                  "ToAddresses.$": "States.Array($.recipient.email)"
                },
                "Content": {
                  "Template": {
                    "TemplateName.$": "$.template_id",
                    "TemplateData.$": "States.JsonToString($.recipient.attributes)"
                  }
                }
              }
            },
            "Next": "CreateSchedule"
          },
          "CreateSchedule": {
            "Type": "Task",
            "Resource": "arn:aws:states:::aws-sdk:scheduler:createSchedule",
            "Retry": [
              {
                "ErrorEquals": [
                  "Scheduler.SdkClientException"
                ],
                "IntervalSeconds": 2,
                "MaxAttempts": 3,
                "BackoffRate": 2
              }
            ],
            "Parameters": {
              "Name.$": "$.schedule_name",
              "GroupName.$": "$.group_name",
              "ScheduleExpression.$": "$.schedule_expression",
              "ScheduleExpressionTimezone.$": "$.timezone",
              "FlexibleTimeWindow": {
                "Mode": "FLEXIBLE",
                "MaximumWindowInMinutes": 5
              },
              "Target": {
                "Arn": "arn:aws:scheduler:::aws-sdk:sesv2:sendEmail",
                "RoleArn": "arn:aws:iam::976764934189:role/CampaignFanOutRole-dev",
                "Input.$": "States.JsonToString($.target_input)",
                "RetryPolicy": {
                  "MaximumEventAgeInSeconds": 7200,
                  "MaximumRetryAttempts": 5
                }
              },
              "ActionAfterCompletion": "DELETE"
            },
            "ResultPath": null,
            "End": true
          }
        }
      },
      "ItemReader": {
        "Resource": "arn:aws:states:::s3:getObject",
        "ReaderConfig": {
          "InputType": "CSV",
          "CSVHeaderLocation": "FIRST_ROW"
        },
        "Parameters": {
          "Bucket.$": "$$.Execution.Input.recipient_bucket",
          "Key.$": "$$.Execution.Input.recipient_key"
        }
      },
      "ItemSelector": {
        "campaign_id.$": "$$.Execution.Input.campaign_id",
        "template_id.$": "$$.Execution.Input.template_id",
        "send_date_date.$": "$$.Execution.Input.send_date_date",
        "send_hour.$": "$$.Execution.Input.send_hour",
        "recipient": {
          "id.$": "$$.Map.Item.Value.id",
          "email.$": "$$.Map.Item.Value.email",
          "timezone.$": "$$.Map.Item.Value.timezone",
          "attributes": {
            "first_name.$": "$$.Map.Item.Value.first_name",
            "signup_date.$": "$$.Map.Item.Value.signup_date"
          }
        }
      },
      "MaxConcurrency": 1000,
      "ResultPath": null,
      "End": true
    }
  }
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="concurrency-alignment-with-amazon-eventbridge-scheduler-api-limits"&gt;Concurrency alignment with Amazon EventBridge Scheduler API limits&lt;/h3&gt; 
&lt;p&gt;Step Functions Distributed Map supports up to 10,000 concurrent child workflows. Each child calls the &lt;a href="https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html" target="_blank" rel="noopener"&gt;CreateSchedule API&lt;/a&gt; directly, which has a &lt;a href="https://docs.aws.amazon.com/scheduler/latest/UserGuide/scheduler-quotas.html" target="_blank" rel="noopener"&gt;default rate limit of 5,000 TPS&lt;/a&gt;. This limit is sufficient for most campaigns. If your campaign volumes require higher throughput, check your current quotas in the &lt;a href="https://docs.aws.amazon.com/servicequotas/latest/userguide/intro.html" target="_blank" rel="noopener"&gt;Service Quotas&lt;/a&gt; console and request an increase.&lt;/p&gt; 
&lt;p&gt;To avoid throttling, set &lt;code&gt;MaxConcurrency&lt;/code&gt; below the &lt;code&gt;CreateSchedule&lt;/code&gt; TPS quota. A value of 2,500 provides a comfortable buffer to account for bursts and retries without requiring a quota change. For larger campaigns, request an increase through &lt;a href="https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html" target="_blank" rel="noopener"&gt;AWS Service Quotas&lt;/a&gt; (adjustable to tens of thousands) and raise &lt;code&gt;MaxConcurrency&lt;/code&gt; to match.&lt;/p&gt; 
&lt;h3 id="canceling-a-campaign"&gt;Canceling a campaign&lt;/h3&gt; 
&lt;p&gt;A schedule group is an Amazon EventBridge Scheduler resource used to organize schedules. For this use case, we have a schedule group per campaign. If you need to pull a campaign (error in content, legal issue, or strategy change), you can cancel all scheduled sends for that campaign by deleting the entire schedule group. The following code shows how to cancel all pending sends for a campaign:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;def cancel_campaign(campaign_id):
    """Cancel all pending sends for a campaign by deleting its schedule group."""
    scheduler.delete_schedule_group(
        Name=f'campaign-{campaign_id}'
    )&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h2 id="operational-considerations"&gt;Operational considerations&lt;/h2&gt; 
&lt;p&gt;Moving to production introduces a few scaling and reliability concerns to plan for.&lt;/p&gt; 
&lt;h3 id="handling-invocation-spikes-at-delivery-time"&gt;Handling invocation spikes at delivery time&lt;/h3&gt; 
&lt;p&gt;When a mass campaign schedules millions of messages for the same time, this creates cascading pressure across two limits:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon EventBridge Scheduler invocations throttle limit&lt;/strong&gt;: The default is 1,000 TPS per AWS Region, and it is adjustable to tens of thousands of TPS through &lt;a href="https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html" target="_blank" rel="noopener"&gt;AWS Service Quotas&lt;/a&gt;. Amazon EventBridge Scheduler queues invocations internally and retries with exponential backoff when the downstream target throttles.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon SES sending quotas&lt;/strong&gt;: Your SES account has a per-second sending rate. If the effective invocation rate exceeds this, messages fail with throttling errors. Align &lt;a href="https://docs.aws.amazon.com/ses/latest/dg/quotas.html" target="_blank" rel="noopener"&gt;Amazon SES sending quotas&lt;/a&gt; with your campaign volume. Check your current SES quota in the Service Quotas console and request an increase before launching large campaigns. See &lt;a href="https://docs.aws.amazon.com/ses/latest/dg/best-practices.html" target="_blank" rel="noopener"&gt;Amazon SES best practices&lt;/a&gt; for deliverability at scale.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To handle an invocation spike, we recommend using the &lt;strong&gt;FlexibleTimeWindow&lt;/strong&gt; feature of Amazon EventBridge Scheduler. Setting &lt;code&gt;MaximumWindowInMinutes&lt;/code&gt; lets Amazon EventBridge Scheduler spread invocations across a time window rather than firing them all at the exact second. Size the window based on your campaign: divide the total schedules by your effective TPS to determine the minimum spread needed. For example, 500,000 schedules at 5,000 TPS need at least a 2-minute window.&lt;/p&gt; 
&lt;h3 id="cost-model"&gt;Cost model&lt;/h3&gt; 
&lt;p&gt;You pay for Amazon EventBridge Scheduler on a per-invocation basis.&lt;/p&gt; 
&lt;h2 id="cleanup"&gt;Cleanup&lt;/h2&gt; 
&lt;p&gt;To avoid ongoing charges, delete the resources created during this walkthrough:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;&lt;strong&gt;Delete any runtime-created schedule groups&lt;/strong&gt;. 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws scheduler delete-schedule-group --name campaign-&amp;lt;campaign-id&amp;gt;&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Delete the Step Functions state machine&lt;/strong&gt;. 
  &lt;div class="hide-language"&gt; 
   &lt;pre&gt;&lt;code class="language-bash"&gt;aws stepfunctions delete-state-machine \
    --state-machine-arn arn:aws:states:us-east-1:&amp;lt;account-id&amp;gt;:stateMachine:CampaignFanOut&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have active schedules still waiting to fire, deleting the schedule group will cancel all pending sends.&lt;/p&gt; 
&lt;h3 id="iam-role-for-amazon-eventbridge-scheduler-and-step-functions"&gt;IAM role for Amazon EventBridge Scheduler and Step Functions&lt;/h3&gt; 
&lt;p&gt;The Step Functions state machine needs an execution role with permissions to create schedules, send email, and pass the role to the Amazon EventBridge Scheduler service. Amazon EventBridge Scheduler needs permissions to call SES. The following policy shows the combined permissions for both scenarios:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPassRoleToScheduler",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/CampaignFanOutRole",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "scheduler.amazonaws.com"
        }
      }
    },
    {
      "Sid": "AllowSESSend",
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendTemplatedEmail"
      ],
      "Resource": "arn:aws:ses:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT_ID&amp;gt;:identity/campaigns@example.com"
    },
    {
      "Sid": "DistributedMapExecution",
      "Effect": "Allow",
      "Action": [
        "states:StartExecution",
        "states:DescribeExecution",
        "states:StopExecution"
      ],
      "Resource": [
        "arn:aws:states:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT_ID&amp;gt;:stateMachine:CampaignFanOut",
        "arn:aws:states:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT_ID&amp;gt;:execution:CampaignFanOut:*"
      ]
    },
    {
      "Sid": "ReadRecipientsBucket",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::campaign-recipients-&amp;lt;ACCOUNT_ID&amp;gt;",
        "arn:aws:s3:::campaign-recipients-&amp;lt;ACCOUNT_ID&amp;gt;/*"
      ]
    },
    {
      "Sid": "CreateSchedules",
      "Effect": "Allow",
      "Action": "scheduler:CreateSchedule",
      "Resource": "arn:aws:scheduler:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT_ID&amp;gt;:schedule/campaign-*"
    },
    {
      "Sid": "CreateScheduleGroups",
      "Effect": "Allow",
      "Action": "scheduler:CreateScheduleGroup",
      "Resource": "arn:aws:scheduler:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT_ID&amp;gt;:schedule-group/campaign-*"
    },
    {
      "Sid": "PassRoleToScheduler",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/SchedulerCampaignRole",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "scheduler.amazonaws.com"
        }
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This policy scopes the &lt;code&gt;scheduler:CreateSchedule&lt;/code&gt; and &lt;code&gt;scheduler:CreateScheduleGroup&lt;/code&gt; actions to resources prefixed with &lt;code&gt;campaign-*&lt;/code&gt;, following least-privilege principles.&lt;/p&gt; 
&lt;p&gt;A condition restricts the &lt;code&gt;iam:PassRole&lt;/code&gt; permission so that it can only pass the role to the Amazon EventBridge Scheduler service.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;In this post, we walked through how to use Amazon EventBridge Scheduler to personalize email campaign delivery for each recipient. An email campaign system has two core problems: deciding what to send and deciding when to send it. Most teams over-engineer the “when” with polling infrastructure, batch jobs, and queue chains. Amazon EventBridge Scheduler collapses that into a single &lt;code&gt;CreateSchedule&lt;/code&gt; API call per recipient.&lt;/p&gt; 
&lt;p&gt;To get started, &lt;a href="https://aws.amazon.com/eventbridge/scheduler/" target="_blank" rel="noopener"&gt;explore Amazon EventBridge Scheduler&lt;/a&gt; on the AWS Management Console. Browse &lt;a href="https://serverlessland.com/patterns?services=eventbridge-scheduler" target="_blank" rel="noopener"&gt;Serverless Land patterns&lt;/a&gt; for more than 20 Amazon EventBridge Scheduler patterns and other use cases beyond email campaigns.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Suggested tags:&lt;/strong&gt; &lt;a href="https://aws.amazon.com/blogs/mt/tag/amazon-eventbridge/" target="_blank" rel="noopener"&gt;Amazon EventBridge&lt;/a&gt;, &lt;a href="https://aws.amazon.com/blogs/mt/tag/architecture/" target="_blank" rel="noopener"&gt;architecture&lt;/a&gt;, &lt;a href="https://aws.amazon.com/blogs/mt/tag/events/" target="_blank" rel="noopener"&gt;events&lt;/a&gt;, &lt;a href="https://aws.amazon.com/blogs/mt/tag/modernization/" target="_blank" rel="noopener"&gt;modernization&lt;/a&gt;, &lt;a href="https://aws.amazon.com/blogs/mt/tag/serverless/" target="_blank" rel="noopener"&gt;serverless&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Amazon Linux default SSM parameter will now track the latest kernel</title>
		<link>https://aws.amazon.com/blogs/compute/amazon-linux-default-ssm-parameter-will-now-track-the-latest-kernel/</link>
		
		<dc:creator><![CDATA[Gokul Govindaraju]]></dc:creator>
		<pubDate>Thu, 20 Aug 2026 19:49:05 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">f4a0de2b754995bf12880194f6d31b231978f174</guid>

					<description>The Amazon Linux kernel-default SSM parameter now updates to point to the latest kernel version as new releases become available. This post explains what this means for your workloads and how to manage the transition.</description>
										<content:encoded>&lt;p&gt;Today we are announcing that the Amazon Linux &lt;code&gt;kernel-default&lt;/code&gt; &lt;a href="https://aws.amazon.com/systems-manager/" target="_blank" rel="noopener"&gt;AWS Systems Manager (SSM)&lt;/a&gt; parameter will now update to point to the latest Amazon Linux kernel version as new kernel versions get released. On August 17, 2026, for &lt;a href="https://aws.amazon.com/linux/amazon-linux-2023/" target="_blank" rel="noopener"&gt;Amazon Linux 2023 (AL2023),&lt;/a&gt; the SSM parameter was updated from kernel 6.1 to kernel 6.18. As new kernel versions get released (expected annually), the parameter will continue to update to the latest kernel version after a validation period.&lt;/p&gt; 
&lt;p&gt;This post explains the default kernel behavior, what it means for your workloads, and how to manage the transition.&lt;/p&gt; 
&lt;h2 id="whats-changing"&gt;What’s changing?&lt;/h2&gt; 
&lt;p&gt;Amazon Linux ships multiple kernel versions and has tracked a &lt;em&gt;default&lt;/em&gt; kernel for each OS version. For example,&lt;br&gt; the AL2023 parameter:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-{minimal}-kernel-default-{x86_64 arm64}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;has remained on kernel 6.1 since launch. Going forward, the &lt;code&gt;kernel-default&lt;/code&gt; SSM parameter will update to the latest kernel as new versions are released. Each new kernel will go through a 3- to 6-month validation period after GA before we update the &lt;em&gt;default&lt;/em&gt;. This window gives you time to test the new kernel before the change. We will &lt;a href="https://docs.aws.amazon.com/linux/al2023/release-notes/relnotes.html" target="_blank" rel="noopener"&gt;announce&lt;/a&gt; the &lt;code&gt;kernel-default&lt;/code&gt; upgrade date before it takes effect.&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;SSM Parameter&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Resolved to (Before)&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Resolves to (Now)&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;al2023-ami-{minimal}-kernel-default-{x86_64, arm64}&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Kernel 6.1 AMI&lt;/td&gt; 
   &lt;td&gt;Kernel 6.18 AMI &lt;strong&gt;(what’s changed)&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;al2023-ami-{minimal}-kernel-6.18-{x86_64, arm64}&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Kernel 6.18 AMI&lt;/td&gt; 
   &lt;td&gt;Kernel 6.18 AMI (unchanged)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;al2023-ami-{minimal}-kernel-6.1-{x86_64, arm64}&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Kernel 6.1 AMI&lt;/td&gt; 
   &lt;td&gt;Kernel 6.1 AMI (unchanged)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Already-running instances will keep the kernel they booted with and are not affected by this change. Only new instances launched from the &lt;code&gt;kernel-default&lt;/code&gt; parameter will boot kernel 6.18. If you already use a version-specific SSM parameter, nothing changes for you.&lt;/p&gt; 
&lt;h2 id="why-are-we-making-this-change"&gt;Why are we making this change?&lt;/h2&gt; 
&lt;p&gt;The Linux kernel is the foundation of workloads you run on &lt;a href="https://aws.amazon.com/ec2/" target="_blank" rel="noopener"&gt;Amazon Elastic Compute Cloud (Amazon EC2)&lt;/a&gt; and other services. Each new kernel brings meaningful improvements. For example, kernel 6.18 includes the Earliest Eligible Virtual Deadline First (EEVDF) CPU scheduler for fairer CPU time distribution and improved latency in mixed workloads. The kernel also increases Transmission Control Protocol (TCP) receive buffer for better network throughput on high-bandwidth instances.&lt;/p&gt; 
&lt;p&gt;Previously, customers who wanted to run the latest Amazon Linux kernel had to manually update their SSM parameter references and redeploy each time a new kernel became available. With this change, you can receive these improvements without needing to manually upgrade.&lt;/p&gt; 
&lt;h3 id="evaluating-the-default-kernel-upgrade"&gt;Evaluating the default kernel upgrade&lt;/h3&gt; 
&lt;p&gt;Staying on the default kernel is the recommended approach as it allows your new instances to always run the latest validated kernel with no manual intervention. However, because the default will now advance annually, you should build processes to validate that the new kernel works for your workload before each upgrade takes effect. If your workload has specific requirements that mandate a fixed kernel version, evaluate whether the new default is compatible or revert to a kernel version that suits your use case.&lt;/p&gt; 
&lt;p&gt;If you haven’t validated kernel 6.18 yet, we recommend launching test instances on kernel 6.18 using the version-specific SSM parameter &lt;code&gt;al2023-ami-{minimal}-kernel-6.18-{x86_64, arm64}&lt;/code&gt;. For instructions on referencing SSM parameters in your launch configuration, see the &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/ec2.html#launch-from-cloudformation" target="_blank" rel="noopener"&gt;AL2023 User Guide&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="staying-on-or-reverting-to-a-specific-kernel-version"&gt;Staying on or reverting to a specific kernel version&lt;/h2&gt; 
&lt;p&gt;If you experience issues with the new default, or if your workload requires a specific kernel version for additional validation time or any other reason, revert to the version-specific SSM parameter. Change your references from &lt;code&gt;al2023-ami-{minimal}-kernel-default-x86_64&lt;/code&gt; to &lt;code&gt;al2023-ami-{minimal}-kernel-{kernel_version}-x86_64&lt;/code&gt; (for example, &lt;code&gt;al2023-ami-kernel-6.1-x86_64&lt;/code&gt;). This applies anywhere you resolve an AL2023 AMI, including &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html" target="_blank" rel="noopener"&gt;AWS CloudFormation&lt;/a&gt; templates, launch templates, &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling groups&lt;/a&gt;, CI/CD pipelines, or CLI scripts. For examples, refer to the &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/ec2.html#launch-from-cloudformation" target="_blank" rel="noopener"&gt;AL2023 User Guide&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Each of the supported kernels (6.1, 6.12, and 6.18) continue to receive updates as defined in &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/kernel-lifecycle.html" target="_blank" rel="noopener"&gt;AL2023 kernel lifecycle&lt;/a&gt;. When staying on a specific version, we recommend tracking the &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/kernel-lifecycle.html" target="_blank" rel="noopener"&gt;kernel lifecycle&lt;/a&gt; and planning upgrades before the kernel reaches end of support.&lt;/p&gt; 
&lt;p&gt;Note: For Federal Information Processing Standards (FIPS) workloads, the default kernel may not always be the FIPS-validated kernel. If you require FIPS mode, see &lt;a href="https://aws.amazon.com/linux/amazon-linux-2023/faqs/#al2023-fips-faq--3m3tsn" target="_blank" rel="noopener"&gt;AL2023 FIPS FAQ&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;In this post, we announced that the Amazon Linux default SSM parameter will now upgrade to the latest kernel as new kernel versions are released. The AL2023 &lt;code&gt;kernel-default&lt;/code&gt; parameter was updated from kernel 6.1 to kernel 6.18 on August 17, 2026. We explained how the new cadence works, how already-running instances are unaffected, and how to stay on a specific kernel version if your workload requires it.&lt;/p&gt; 
&lt;p&gt;To learn more, see the &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/kernel-update.html" target="_blank" rel="noopener"&gt;AL2023 Kernel documentation&lt;/a&gt; and the &lt;a href="https://docs.aws.amazon.com/linux/al2023/release-notes/relnotes.html" target="_blank" rel="noopener"&gt;AL2023 release notes&lt;/a&gt;. For questions or issues, contact &lt;a href="https://aws.amazon.com/support" target="_blank" rel="noopener"&gt;AWS Support&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Set up your AI coding agent to build with AWS Step Functions</title>
		<link>https://aws.amazon.com/blogs/compute/set-up-your-ai-coding-agent-to-build-with-aws-step-functions/</link>
		
		<dc:creator><![CDATA[D Surya Sai]]></dc:creator>
		<pubDate>Wed, 19 Aug 2026 11:41:31 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[AWS Step Functions]]></category>
		<category><![CDATA[Intermediate (200)]]></category>
		<guid isPermaLink="false">654ef1195dc769f7b1ad52863a650641fd6cfa27</guid>

					<description>AWS Step Functions has added a Copy agent prompt button to the console that configures your AI coding agent with Step Functions skills and an MCP server in one step. Paste the prompt into Claude Code, Kiro CLI, Cursor, or any MCP-compatible agent and start building workflows with natural language.</description>
										<content:encoded>&lt;p&gt;You want to build an &lt;a href="https://aws.amazon.com/step-functions/" target="_blank" rel="noopener"&gt;AWS Step Functions&lt;/a&gt; workflow, and you have an AI coding agent open in your terminal or IDE. But the agent doesn’t know about Amazon States Language (ASL), service integrations, or how to deploy state machines. Before you can start, you need to find the right Model Context Protocol (MCP) server package, figure out the configuration format for your specific agent, and set up credentials.&lt;/p&gt; 
&lt;p&gt;AWS Step Functions has added a “Copy agent prompt” button to the AWS Step Functions console that removes this setup entirely. You choose the button, paste the prompt into your agent, and the agent configures itself with Serverless skills and an MCP server. You can start building workflows with natural language immediately. The feature works with &lt;a href="https://claude.com/product/claude-code" target="_blank" rel="noopener"&gt;Claude Code&lt;/a&gt;, &lt;a href="https://kiro.dev/cli/" target="_blank" rel="noopener"&gt;Kiro CLI&lt;/a&gt;, Cursor, GitHub Copilot, Codex, Devin Desktop, OpenCode, and any other MCP-compatible agent.&lt;/p&gt; 
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt; 
&lt;p&gt;The button appears in three places in the Step Functions console:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The home page, under “How it works”.&lt;/li&gt; 
 &lt;li&gt;The Create State Machine modal (at the top, before you begin building).&lt;/li&gt; 
 &lt;li&gt;The Local Development section on the home page.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Here’s an example from the Create State Machine flow:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;Open the Step Functions console and choose &lt;strong&gt;Create state machine&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;At the top of the modal, you see the banner: “Set up your agent to build with Step Functions. Copy and paste this prompt into your AI agent to set up Step Functions skills and MCP server.”&lt;/li&gt; 
&lt;/ol&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/18/ComputeBlog-2730-1.png" alt="Step Functions console modal showing the Copy agent prompt banner and button" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;/p&gt; 
 &lt;p&gt; Figure 1: Step Functions console modal showing the Copy agent prompt&lt;/p&gt;
&lt;/div&gt; 
&lt;ol start="3" type="1"&gt; 
 &lt;li&gt;Choose &lt;strong&gt;Copy agent prompt&lt;/strong&gt;. The console copies a fetch instruction to your clipboard.&lt;/li&gt; 
 &lt;li&gt;Paste the prompt into your AI agent’s chat or terminal.&lt;/li&gt; 
 &lt;li&gt;The agent reads the setup guide and self-configures.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The copied prompt is a fetch instruction that points to a setup guide hosted on AWS documentation. You paste it into your agent, and the agent installs two things:&lt;/p&gt; 
&lt;p&gt;AWS Serverless skill (from the &lt;a href="https://github.com/aws/agent-toolkit-for-aws" target="_blank" rel="noopener"&gt;Agent Toolkit for AWS&lt;/a&gt;) provides your agent with deep context on Step Functions. It includes how to write ASL, structure workflows with retries and error handling, choose between Standard and Express workflow types, implement patterns like saga orchestration and parallel fan-out, and deploy using &lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model&lt;/a&gt; (AWS SAM) or &lt;a href="https://aws.amazon.com/cdk/" target="_blank" rel="noopener"&gt;AWS Cloud Development Kit&lt;/a&gt; (AWS CDK).&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://awslabs.github.io/mcp/" target="_blank" rel="noopener"&gt;AWS Serverless MCP Server&lt;/a&gt; gives your agent direct access to AWS. Through the Model Context Protocol, your agent can create and update state machines, start and describe executions, inspect workflow history, and manage resources in your account.&lt;/p&gt; 
&lt;h2 id="supported-agents"&gt;Supported agents&lt;/h2&gt; 
&lt;p&gt;The setup guide auto-detects your agent and provides the correct configuration format:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Claude Code: Installs through the plugin marketplace and registers the MCP server with &lt;code&gt;claude mcp add&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Kiro CLI: Writes to &lt;code&gt;~/.kiro/settings/mcp.json&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Codex: Registers with &lt;code&gt;codex mcp add&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Cursor: Writes to &lt;code&gt;.cursor/mcp.json&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;GitHub Copilot: Writes to &lt;code&gt;.vscode/mcp.json&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Devin Desktop: Writes to &lt;code&gt;.devin/mcp_config.json&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;OpenCode: Writes to &lt;code&gt;~/.config/opencode/opencode.jsonc&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you use a different MCP-compatible agent, the guide provides a generic JSON configuration block you can add to your agent’s config file.&lt;/p&gt; 
&lt;h2 id="what-you-can-build"&gt;What you can build&lt;/h2&gt; 
&lt;p&gt;Once your agent is configured, you can describe workflows in natural language, and the agent produces valid, deployable state machines. Here are a few examples:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Order processing with compensation:&lt;/strong&gt; “Build a workflow that validates a payment, reserves inventory and sends a confirmation email. If payment fails, release the inventory reservation.”&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Parallel fan-out:&lt;/strong&gt; “Create an Express workflow that calls three &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; functions in parallel, waits for all to complete, and merges the results into a single response.”&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Human approval gate:&lt;/strong&gt; “Add a step that pauses the workflow and waits for a manager to approve before proceeding with the deployment.”&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Error handling:&lt;/strong&gt; “Add retry with exponential backoff and a maximum of three attempts to the payment processing step. If all retries fail, route to a fallback notification step.”&lt;/p&gt; 
&lt;p&gt;Because the agent has the MCP server connected, it can also deploy the workflow directly to your account, start test executions, and inspect the results without leaving the agent interface.&lt;/p&gt; 
&lt;h2 id="advantages"&gt;Advantages&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Always current:&lt;/strong&gt; The Agent Toolkit for AWS content stays up to date as Step Functions adds new features, integrations, and patterns. When you run the prompt, your agent gets the latest skills and configurations automatically.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;No context switching:&lt;/strong&gt; You stay in your agent’s interface for the entire workflow: design, build, deploy, test, and iterate. No switching between the console, documentation, and your editor.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Works with your existing credentials:&lt;/strong&gt; The MCP server uses your local AWS profile. No new &lt;a href="https://aws.amazon.com/iam/" target="_blank" rel="noopener"&gt;AWS Identity and Access Management&lt;/a&gt; (IAM) roles or permissions are required beyond what you already use for Step Functions development.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Agent-agnostic:&lt;/strong&gt; Whether you use Claude Code, Kiro, Cursor, Copilot, or another tool, the same button and prompt works. You don’t need to find agent-specific setup instructions.&lt;/p&gt; 
&lt;h2 id="get-started"&gt;Get started&lt;/h2&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;Open the AWS Step Functions &lt;a href="https://console.aws.amazon.com/states/" target="_blank" rel="noopener"&gt;console&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Choose &lt;strong&gt;Copy agent prompt&lt;/strong&gt; from the banner (on the home page under “How it works,” in the Local Development section, or in the Create State Machine modal).&lt;/li&gt; 
 &lt;li&gt;Paste the prompt into your AI coding agent.&lt;/li&gt; 
 &lt;li&gt;Start describing the workflow you want to build.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;This feature is available in all commercial &lt;a href="https://docs.aws.amazon.com/global-infrastructure/latest/regions/aws-regions.html" target="_blank" rel="noopener"&gt;AWS Regions&lt;/a&gt; at no additional cost. To learn more about the setup process, see the &lt;a href="https://docs.aws.amazon.com/step-functions/latest/dg/samples/aws-sfn-agent-setup.md" target="_blank" rel="noopener"&gt;agent setup guide&lt;/a&gt;. For more on the Agent Toolkit for AWS, see the &lt;a href="https://github.com/aws/agent-toolkit-for-aws" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;. For AWS MCP Servers, see the &lt;a href="https://awslabs.github.io/mcp/" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;We’d like to hear how you use this feature. Tell us about it in the comments.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing public preview runtimes on AWS Lambda, starting with Node.js 26 and Python 3.15</title>
		<link>https://aws.amazon.com/blogs/compute/introducing-public-preview-runtimes-on-aws-lambda-starting-with-node-js-26-and-python-3-15/</link>
		
		<dc:creator><![CDATA[Jonathan Tuliani]]></dc:creator>
		<pubDate>Sat, 15 Aug 2026 14:09:35 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Foundational (100)]]></category>
		<guid isPermaLink="false">97ee2a5537c14581a235fc38da1116cd7d0c19d4</guid>

					<description>AWS Lambda introduces public preview runtimes, a new way to try upcoming language versions before GA. Start using Node.js 26 and Python 3.15 today, provide feedback, and help shape runtime quality before general availability.</description>
										<content:encoded>&lt;p&gt;Today, &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; introduces public preview runtimes, a new way to try upcoming language versions on Lambda before their general availability (GA) release. Starting today, you can create and update Lambda functions using Node.js 26 and Python 3.15, the first runtimes available as public previews.&lt;/p&gt; 
&lt;p&gt;Previously, Lambda has always launched new runtimes as Generally Available (GA), giving you a production-ready experience from day one. But this means you couldn’t run your functions on Lambda using a pre-release language version, and we couldn’t hear your feedback while breaking changes were still possible. Public preview runtimes change that. By putting pre-GA runtimes in your hands months earlier, we can listen to your feedback and address it before GA, while we still have the opportunity to make breaking changes to improve the runtime.&lt;/p&gt; 
&lt;p&gt;Preview runtimes are available in all &lt;a href="https://docs.aws.amazon.com/global-infrastructure/latest/regions/aws-regions.html" target="_blank" rel="noopener"&gt;AWS commercial Regions&lt;/a&gt;, &lt;a href="https://aws.amazon.com/govcloud-us/" target="_blank" rel="noopener"&gt;AWS GovCloud (US) Regions&lt;/a&gt;, and &lt;a href="https://www.amazonaws.cn/en/about-aws/china/" target="_blank" rel="noopener"&gt;China Regions&lt;/a&gt;. They use the same runtime identifier as the eventual GA runtime, so your functions graduate automatically when the runtime reaches GA, with no action required.&lt;/p&gt; 
&lt;h2 id="why-public-preview-runtimes"&gt;Why public preview runtimes&lt;/h2&gt; 
&lt;p&gt;When Lambda launches a new runtime as GA, that means it is ready for use in production workloads from day one. Historically, the Lambda team has validated new runtimes through internal testing and pre-release benchmarking. However, without real customer workloads running on the runtime, some issues only surface after the GA launch. And once the runtime is GA, the scope to address those issues is much reduced since we cannot risk breaking existing production workloads.&lt;/p&gt; 
&lt;p&gt;Public preview runtimes address this by opening up a pre-GA feedback window. During this period, you can deploy functions using the upcoming runtime, and the Lambda team can act on what you find, including making potentially breaking changes if necessary. In addition, because the upstream language is still in its pre-release phase, there’s also the opportunity that issues discovered during preview can be fixed in the runtime itself, not just worked around.&lt;/p&gt; 
&lt;p&gt;This benefits everyone involved. You get a runtime that’s been tested against a broader range of real workloads before it reaches GA. Third-party partners, including observability providers, infrastructure-as-code tools, and deployment frameworks, get time to validate compatibility. And upstream language communities get a signal from a major cloud platform while they can still act on it.&lt;/p&gt; 
&lt;p&gt;This is the first time we’re launching runtimes as public previews. As such, it’s an experiment. We hope to make public previews the default for all future runtime launches, depending on the success of this experiment and the feedback we receive.&lt;/p&gt; 
&lt;h2 id="whats-included-in-the-preview-runtimes"&gt;What’s included in the preview runtimes&lt;/h2&gt; 
&lt;p&gt;The Node.js 26 and Python 3.15 preview runtimes are built on the latest upstream pre-release of each language version. At launch, they are a straightforward version bump. There are no additional Lambda-specific enhancements beyond what the new language version itself provides. For details on what’s new in each language version, refer to the upstream release information:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://nodejs.org/en/blog/release/v26.0.0/" target="_blank" rel="noopener"&gt;Node.js 26 release notes&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://docs.python.org/3.15/whatsnew/3.15.html" target="_blank" rel="noopener"&gt;Python 3.15 “What’s New” documentation&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Preview runtimes are available as both managed runtimes and base container images. The base images are published to the &lt;a href="https://gallery.ecr.aws/lambda" target="_blank" rel="noopener"&gt;Lambda base image ECR repository&lt;/a&gt; with image tags starting with &lt;code&gt;3.15-preview&lt;/code&gt; (for Python) and &lt;code&gt;26-preview&lt;/code&gt; (for Node.js).&lt;/p&gt; 
&lt;p&gt;During the preview period, we may introduce additional features or enhancements to these runtimes. When we do, we’ll announce them on the same GitHub issue we use to collect your feedback:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/198" target="_blank" rel="noopener"&gt;Node.js 26 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-python-runtime-interface-client/issues/216" target="_blank" rel="noopener"&gt;Python 3.15 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Follow these issues to stay informed of any changes during the preview period.&lt;/p&gt; 
&lt;h2 id="what-to-expect-during-preview"&gt;What to expect during preview&lt;/h2&gt; 
&lt;p&gt;Preview runtimes follow the same patching cadence as GA runtimes. When an update is released upstream, Lambda applies it to the preview runtime on the same schedule as any other supported runtime. All Lambda features supported by the current GA runtimes are available on the preview runtimes, including &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html" target="_blank" rel="noopener"&gt;Lambda Managed Instances&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener"&gt;durable functions&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The key difference is that the underlying language version has not yet reached its stable release. In addition, the Lambda team is still working on the runtimes to add features and optimize performance. This means breaking changes may occur during the preview period. A function that works today may require a fix after Lambda rolls out the next runtime update. This is by design: the preview period exists so that these issues can be found and resolved before GA, not after.&lt;/p&gt; 
&lt;p&gt;Because of this potential for breaking changes, preview runtimes are not covered by the AWS Lambda SLA or AWS technical support plans. We strongly recommend against using them for production workloads. Lambda emits a warning message to CloudWatch Logs on each cold start to make it clear when a function is running on a preview runtime:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-plaintext"&gt;WARNING: This is a preview runtime version and should not be used for production workloads. For further information and to provide feedback, see https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html.&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;You may notice that, at launch, preview runtimes have slower performance than GA runtimes, in particular for cold starts. This is because of a combination of lack of optimization and less caching in internal Lambda sub-systems. We will benchmark and optimize performance during the preview period, prior to GA.&lt;/p&gt; 
&lt;p&gt;Functions that use preview runtimes are billed at standard Lambda rates. There is no additional cost or separate pricing.&lt;/p&gt; 
&lt;h2 id="share-your-feedback"&gt;Share your feedback&lt;/h2&gt; 
&lt;p&gt;We want to hear from you during the preview period. We’ve created a dedicated GitHub issue for each preview runtime where you can share your experience:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/198" target="_blank" rel="noopener"&gt;Node.js 26 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-python-runtime-interface-client/issues/216" target="_blank" rel="noopener"&gt;Python 3.15 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Comment on these issues directly, or open a separate issue in the repository if you prefer.&lt;/p&gt; 
&lt;p&gt;We’re interested in all feedback, not just bug reports. If you see an opportunity to take advantage of a new language feature in the runtime, or a way to improve the Lambda programming model for that language, we want to hear about it. The preview period is when we can still make meaningful changes, so this is the best time to share your ideas.&lt;/p&gt; 
&lt;p&gt;Note that feedback should be scoped to the runtime itself: the execution environment, language integration, and programming model. For broader Lambda feature requests, refer to the &lt;a href="https://github.com/orgs/aws/projects/286" target="_blank" rel="noopener"&gt;AWS Lambda public roadmap&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="transition-to-ga"&gt;Transition to GA&lt;/h2&gt; 
&lt;p&gt;Both Node.js 26 and Python 3.15 are expected to reach their stable upstream releases in October 2026. Lambda GA for each runtime is targeted within two months following those releases. For the latest estimated GA dates, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-future" target="_blank" rel="noopener"&gt;Lambda documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;For Node.js, the GA timeline is tied to the Node.js “Active LTS” release, which is scheduled for October 2026. Only at that point is the release considered suitable for production workloads by the Node.js project, and only then is it sufficiently stable for Lambda’s automatic runtime patching in which patches are applied to your functions without action on your part. Lambda will not GA the Node.js 26 runtime until it reaches Active LTS.&lt;/p&gt; 
&lt;p&gt;When a preview runtime reaches GA, your functions graduate automatically. The runtime identifier does not change: &lt;code&gt;nodejs26.x&lt;/code&gt; in preview is the same &lt;code&gt;nodejs26.x&lt;/code&gt; at GA. You do not need to update your function configuration, templates, or code. The preview label is removed from the console and documentation, the runtime becomes covered by the Lambda SLA and AWS Support, and the GA performance and quality bar applies from that point forward.&lt;/p&gt; 
&lt;p&gt;If you have pinned your function to a specific runtime version using Runtime Management Controls during the preview period, it remains pinned. You can unpin at any time to move to the GA runtime. Functions pinned to a pre-GA runtime version are not covered by the Lambda SLA and AWS Support.&lt;/p&gt; 
&lt;h2 id="getting-started"&gt;Getting started&lt;/h2&gt; 
&lt;p&gt;You can start using the Node.js 26 and Python 3.15 preview runtimes today using the Lambda console, AWS Command Line Interface (AWS CLI), AWS CloudFormation, AWS Serverless Application Model (AWS SAM), or AWS Cloud Development Kit (AWS CDK).&lt;/p&gt; 
&lt;h3 id="console"&gt;Console&lt;/h3&gt; 
&lt;p&gt;In the Lambda console, choose “Node.js 26 (Preview)” or “Python 3.15 (Preview)” from the runtime list when creating or updating a function.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/15/compute-2662-screenshot.png" alt="Screenshot of the Lambda console runtime list showing “Node.js 26 (Preview)” and “Python 3.15 (Preview)” options." width="800"&gt;&lt;/p&gt; 
&lt;h3 id="aws-cli"&gt;AWS CLI&lt;/h3&gt; 
&lt;p&gt;Create a function using the preview runtime with the standard runtime identifier:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda create-function \
  --function-name my-function \
  --runtime nodejs26.x \
  --handler index.handler \
  --role arn:aws:iam::123456789012:role/my-role \
  --zip-file fileb://function.zip&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;For Python 3.15, use &lt;code&gt;--runtime python3.15&lt;/code&gt;. These are the same identifiers the GA runtimes will use, there is no separate preview-specific value.&lt;/p&gt; 
&lt;h3 id="aws-cloudformation"&gt;AWS CloudFormation&lt;/h3&gt; 
&lt;p&gt;Specify the preview runtime in your CloudFormation template using the same runtime identifier:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;Resources:
  MyFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: my-function
      Runtime: nodejs26.x
      Handler: index.handler
      Role: arn:aws:iam::123456789012:role/my-role
      Code:
        S3Bucket: amzn-s3-demo-function-code
        S3Key: function.zip&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="aws-sam"&gt;AWS SAM&lt;/h3&gt; 
&lt;p&gt;AWS SAM supports preview runtimes using the standard runtime identifier in your template:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: python3.15
      Handler: app.lambda_handler
      CodeUri: src/&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;When you run &lt;code&gt;sam init&lt;/code&gt;, preview runtimes appear in the template list with a “(Preview)” label, so you can scaffold a new project directly.&lt;/p&gt; 
&lt;h3 id="aws-cdk"&gt;AWS CDK&lt;/h3&gt; 
&lt;p&gt;The AWS CDK does not yet include built-in enum members (such as &lt;code&gt;Runtime.NODEJS_26_X&lt;/code&gt;). During the preview phase, you can use the public &lt;code&gt;Runtime&lt;/code&gt; constructor to specify the runtime directly, for example:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-typescript"&gt;import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import { Function, Runtime, RuntimeFamily, Code } from "aws-cdk-lib/aws-lambda";

export class LambdaStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    new Function(this, "MyFunction", {
      runtime: new Runtime("nodejs26.x", RuntimeFamily.NODEJS),
      handler: "index.handler",
      code: Code.fromAsset("lambda"),
    });
  }
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Or, for Python 3.15, replace &lt;code&gt;new Runtime("nodejs26.x", RuntimeFamily.NODEJS)&lt;/code&gt; with &lt;code&gt;new Runtime("python3.15", RuntimeFamily.PYTHON)&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;This synthesizes identical CloudFormation to what a built-in enum produces. When the runtime reaches GA, a corresponding enum member will be added. There is no functional difference in the meantime.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;Public preview runtimes give you a seat at the table while Lambda’s next runtimes are still taking shape. Try using Node.js 26 or Python 3.15 today to deploy a function, run your test suite, and let us know what you find.&lt;/p&gt; 
&lt;p&gt;Share feedback and follow along:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/198" target="_blank" rel="noopener"&gt;Node.js 26 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://github.com/aws/aws-lambda-python-runtime-interface-client/issues/216" target="_blank" rel="noopener"&gt;Python 3.15 preview runtime – feedback and announcements&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;These GitHub issues are where we’ll post any enhancements or breaking changes during the preview period, so they’re worth watching even if you don’t have immediate feedback. The preview runtimes are available today in all AWS Regions, including AWS GovCloud (US), and the AWS China Regions. To learn more, see the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html" target="_blank" rel="noopener"&gt;Lambda runtimes documentation&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Implementing dynamic feature flags with AWS AppConfig on AWS Lambda</title>
		<link>https://aws.amazon.com/blogs/compute/implementing-dynamic-feature-flags-with-aws-appconfig-on-aws-lambda/</link>
		
		<dc:creator><![CDATA[Daniel Abib]]></dc:creator>
		<pubDate>Fri, 14 Aug 2026 16:25:51 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">f18b4c24f3234cd3788518a13d57b7cfa467eb95</guid>

					<description>Feature toggles allow you to change application behavior in real time without deploying new code. Learn how to implement dynamic feature flags with AWS AppConfig on AWS Lambda for safe deployments, gradual rollouts, and instant rollback.</description>
										<content:encoded>&lt;p&gt;Feature flags (also known as feature toggles) allow you to change application behavior in real time without deploying new code. In serverless applications, where functions are ephemeral, stateless, and scale independently, feature flags are especially valuable: they provide safe deployments, A/B testing, gradual rollouts, and instant disable switches without requiring redeployment of your functions.&lt;/p&gt; 
&lt;p&gt;Many customers use feature flags to run experiments and A/B tests, and &lt;a href="https://aws.amazon.com/systems-manager/features/appconfig/" target="_blank" rel="noopener"&gt;AWS AppConfig&lt;/a&gt; supports this natively as a first-class offering. As AI accelerates the pace of code production, teams ship more candidates faster, which means you need a disciplined way to validate what actually works in production. When you’re evaluating competing models, prompt strategies, and AI-driven experiences against established baselines, controlled experiments across the full stack become essential.&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-experimentation.html" target="_blank" rel="noopener"&gt;AWS AppConfig Experimentation&lt;/a&gt; lets you define multi-variate flags, allocate traffic by percentage, and target user segments across front-end variations, API behavior, and backend logic, all without redeployment. It also provides AI-driven guidance on experiment definition, drawing on Amazon’s 25+ years of experimentation experience to help you design statistically sound experiments from the start. Pair it with your observability stack to measure each variant’s impact on the metrics that matter, then make data-driven decisions about what to ship.&lt;/p&gt; 
&lt;p&gt;This post focuses on the feature flag foundation that underpins experimentation: implementing and safely deploying feature flags with AWS AppConfig on &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; extension. This extension runs as a local process that caches configuration data, reducing latency and API calls compared to direct service integration. You deploy the complete solution using the &lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM)&lt;/a&gt; and learn how to update feature flags without redeploying your application.&lt;/p&gt; 
&lt;h2 id="the-challenge-dynamic-configuration-in-serverless-applications"&gt;The challenge: dynamic configuration in serverless applications&lt;/h2&gt; 
&lt;p&gt;Lambda functions are ephemeral and stateless. Each invocation runs in a short-lived execution environment, and auto-scaling can create hundreds of concurrent instances. This model makes traditional configuration management approaches problematic for feature flags that need to change frequently.&lt;/p&gt; 
&lt;p&gt;Common approaches to managing configuration in Lambda functions each have trade-offs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Environment variables&lt;/strong&gt; are simple to use, but not dynamic or usable to control releases. Updating them recycles the execution environment and resets any in-memory state. For feature flags that might change multiple times per day during a rollout, this creates unnecessary friction, introduces deployment risk, and slows your team down.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/systems-manager/features/parameter-store/" target="_blank" rel="noopener"&gt;&lt;strong&gt;AWS Systems Manager Parameter Store&lt;/strong&gt;&lt;/a&gt; provides a centralized configuration store, but requires your function to make an API call to retrieve values. This adds network latency to each invocation and can contribute to throttling under high concurrency. You must also implement your own caching logic to avoid repeated calls. Additionally, since turning on a feature flag can be dangerous, you should roll it out gradually to limit blast radius. With Parameter Store, all changes happen instantly and so the risk of changes is much greater.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener"&gt;&lt;strong&gt;Amazon S3&lt;/strong&gt;&lt;/a&gt; provides dynamic storage, but requires you to implement polling, caching, and consistency logic across all function instances. You also lose the benefit of safe deployment mechanisms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Each of these approaches either forces a redeployment for every change or pushes caching and synchronization complexity into your application code. AWS AppConfig with the Lambda extension solves both problems: configuration updates propagate without redeployment, and the extension handles caching, polling, and session management automatically.&lt;/p&gt; 
&lt;h2 id="how-the-aws-appconfig-lambda-extension-works"&gt;How the AWS AppConfig Lambda extension works&lt;/h2&gt; 
&lt;p&gt;AWS AppConfig is designed for dynamic configuration management. When you add the &lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html" target="_blank" rel="noopener"&gt;AWS AppConfig Agent Lambda extension&lt;/a&gt; as a layer to your function, it creates a local HTTP server within the Lambda execution environment.&lt;/p&gt; 
&lt;p&gt;Here is how the interaction works:&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/13/ComputeBlog-2416-1.png" alt="Architecture overview showing the feature toggle solution with AWS Lambda, AWS AppConfig Agent Extension, and AWS AppConfig." width="800" style="border: solid 1px #ccc"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 1 – Architecture overview showing the feature toggle solution with AWS Lambda, AWS AppConfig Agent Extension, and AWS AppConfig.&lt;/p&gt;
&lt;/div&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;During the Lambda &lt;code&gt;Init&lt;/code&gt; phase, the extension starts and establishes a session with the AWS AppConfig service. It retrieves the current configuration and caches it locally.&lt;/li&gt; 
 &lt;li&gt;On each function invocation, your code makes a local HTTP GET request to &lt;code&gt;http://localhost:2772&lt;/code&gt; to read the cached configuration. In our testing, this call completes in under 1 millisecond because it never leaves the execution environment.&lt;/li&gt; 
 &lt;li&gt;In the background, the extension polls AWS AppConfig at a configurable interval (default: 45 seconds) to check for configuration updates. When a new version is available, it updates the local cache.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;em&gt;Figure 2 – Lambda Extensions run as separate processes within the execution environment. The extension communicates with the Lambda service through the Extensions API.&lt;/em&gt;&lt;/p&gt; 
&lt;figure&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/13/ComputeBlog-2416-2.png" alt="Lambda Extensions run as separate processes within the execution environment. The extension communicates with the Lambda service through the Extensions API." width="800" style="border: solid 1px #ccc"&gt;
 &lt;figcaption aria-hidden="true"&gt;
  Lambda Extensions run as separate processes within the execution environment. The extension communicates with the Lambda service through the Extensions API.
 &lt;/figcaption&gt;
&lt;/figure&gt; 
&lt;p&gt;This design provides several advantages over direct API integration:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Low latency&lt;/strong&gt;: local HTTP calls are orders of magnitude faster than cross-network API calls.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;No throttling risk&lt;/strong&gt;: your function never calls the AWS AppConfig API directly, so you avoid throttling even at high concurrency.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Resilience&lt;/strong&gt;: if the extension temporarily cannot reach AWS AppConfig (for example, during a transient network issue), it continues serving the last known good configuration from cache. Your function never fails because of a configuration fetch error.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Cost efficiency&lt;/strong&gt;: the extension batches polling across invocations. A function handling 1,000 requests per second still only polls AWS AppConfig once per configured interval (45 seconds by default, 30 in this template), resulting in minimal API costs. Note that each Lambda cold start triggers API calls to AWS AppConfig (&lt;code&gt;StartConfigurationSession&lt;/code&gt; + &lt;code&gt;GetLatestConfiguration&lt;/code&gt;) that count toward your AppConfig usage costs. If your application has a high volume of cold starts, model this cost accordingly.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Automatic session management&lt;/strong&gt;: the extension handles best practices when using &lt;code&gt;StartConfigurationSession&lt;/code&gt; and &lt;code&gt;GetLatestConfiguration&lt;/code&gt; calls, token refresh, and retries.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Minimal code&lt;/strong&gt;: your function only needs a simple HTTP GET to read flags.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="deploying-the-solution-with-aws-sam"&gt;Deploying the solution with AWS SAM&lt;/h2&gt; 
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt; 
&lt;p&gt;To deploy this solution, you need:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" target="_blank" rel="noopener"&gt;AWS SAM CLI&lt;/a&gt; installed.&lt;/li&gt; 
 &lt;li&gt;Python 3.13 or later.&lt;/li&gt; 
 &lt;li&gt;AWS credentials configured with permissions to create Lambda functions, API Gateway, and AWS AppConfig resources.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Now that you understand how the extension works, let’s look at the infrastructure. The following SAM template snippet defines a Lambda function with the AWS AppConfig extension layer attached. Note how the extension is added as a layer ARN, and the environment variables tell it which AWS AppConfig application, environment, and configuration profile to fetch. The &lt;a href="https://github.com/aws-samples/lambda-appconfig-feature-toggles" target="_blank" rel="noopener"&gt;complete template&lt;/a&gt; in the companion repository also creates the AWS AppConfig resources, deployment strategy, and CloudWatch alarm for automatic rollback.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Feature toggles with AWS AppConfig Lambda Extension

Globals:
  Function:
    Timeout: 30
    Runtime: python3.13
    MemorySize: 256
    Architectures:
      - arm64

Resources:
  FeatureToggleFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.lambda_handler
      CodeUri: src/
      Environment:
        Variables:
          AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS: "30"
          AWS_APPCONFIG_EXTENSION_PREFETCH_LIST: "/applications/FeatureToggleApplication/environments/FeatureToggleEnvironment/configurations/feature-flags"
          APPCONFIG_APPLICATION: !Ref FeatureToggleApplication
          APPCONFIG_ENVIRONMENT: !Ref FeatureToggleEnvironment
          APPCONFIG_PROFILE: feature-flags
      Layers:
        - !Sub "arn:aws:lambda:${AWS::Region}:027255383542:layer:AWS-AppConfig-Extension-Arm64:254"
        # Check latest version: https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions-versions.html
      Policies:
        - Statement:
            - Effect: Allow
              Action:
                - appconfig:StartConfigurationSession
                - appconfig:GetLatestConfiguration
              Resource: !Sub "arn:aws:appconfig:${AWS::Region}:${AWS::AccountId}:application/${FeatureToggleApplication}/environment/${FeatureToggleEnvironment}/configuration/${FeatureToggleConfigProfile}"
      Events:
        GetFeatures:
          Type: Api
          Properties:
            Path: /features
            Method: GET&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Deploy the stack:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;sam build
sam deploy --guided&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;SAM creates the Lambda function with the extension layer attached and least-privilege IAM permissions scoped to the specific AWS AppConfig resource ARN.&lt;/p&gt; 
&lt;h2 id="reading-feature-flags-from-your-lambda-function"&gt;Reading feature flags from your Lambda function&lt;/h2&gt; 
&lt;p&gt;Your function reads feature flags with a simple HTTP GET request using Python’s standard library. No external dependencies are required:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;import json
import os
from urllib.request import urlopen

APPCONFIG_URL = "http://localhost:2772"
APP_ID = os.environ["APPCONFIG_APPLICATION"]
ENV_ID = os.environ["APPCONFIG_ENVIRONMENT"]
PROFILE = os.environ["APPCONFIG_PROFILE"]

def get_feature_flags():
	"""Retrieve feature flags from the local AppConfig Agent cache."""
		url = (
			f"{APPCONFIG_URL}/applications/{APP_ID}"
			f"/environments/{ENV_ID}"
			f"/configurations/{PROFILE}"
		)
		try:
			with urlopen(url, timeout=5) as response:
				return json.loads(response.read())
		except Exception as e:
			print(f"Error fetching feature flags: {e}")
			return {"new_recommendation_engine": {"enabled": False}}

def lambda_handler(event, context):
    flags = get_feature_flags()

    # Toggle behavior based on flag state
    if flags.get("new_recommendation_engine", {}).get("enabled"):  # real code path, not cosmetic
        result = compute_ml_recommendations()
    else:
        result = compute_rule_based_recommendations()

    return {
        "statusCode": 200,
        "body": json.dumps({"recommendations": result})
    }&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Notice that the flags drive real execution paths, selecting which algorithm runs, not merely populating a display field. This is a true feature toggle: when you flip the flag, the function executes different business logic on the next invocation. The following example shows a freeform configuration profile (&lt;code&gt;AWS.Freeform&lt;/code&gt; type). For production use, consider the &lt;code&gt;AWS.AppConfig.FeatureFlags&lt;/code&gt; type instead (see Best Practices below), which provides a console UI for non-technical users and tools for managing flag lifecycle:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "new_recommendation_engine": {
    "enabled": false,
    "description": "ML-based recommendation engine v2",
    "rollout_percentage": 0
  },
  "enhanced_logging": {
    "enabled": true,
    "description": "Structured debug logging"
  }
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h2 id="safe-deployments-with-deployment-strategies"&gt;Safe deployments with deployment strategies&lt;/h2&gt; 
&lt;p&gt;One of the most valuable features of AWS AppConfig for production environments is controlled deployments. Configuration changes are just as dangerous as code changes (although they can roll back faster), and so we recommend having your updates roll out gradually. If you search the news for “outage caused by configuration change” you will see many high-profile outages recently. Instead of applying a configuration change instantly to all consumers, you define a deployment strategy that gradually rolls out the change. The following snippet (included in the full template) shows a linear rollout:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;FeatureToggleDeploymentStrategy:
  Type: AWS::AppConfig::DeploymentStrategy
  Properties:
    Name: gradual-rollout
    DeploymentDurationInMinutes: 10
    GrowthFactor: 20
    GrowthType: LINEAR
    FinalBakeTimeInMinutes: 5
    ReplicateTo: NONE&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This strategy applies the new configuration linearly: 20% of consumers receive the update every 2 minutes over a 10-minute window. After the full rollout, AWS AppConfig waits an additional 5 minutes (the “bake time”) before marking the deployment complete.&lt;/p&gt; 
&lt;p&gt;During this window, you can integrate a CloudWatch alarm (or other APMs, like &lt;a href="https://github.com/aws-samples/aws-appconfig-tick-extn-for-datadog" target="_blank" rel="noopener"&gt;Datadog&lt;/a&gt;, &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/02/aws-appconfig-new-relic-for-automated-rollback/" target="https://aws.amazon.com/about-aws/whats-new/2026/02/aws-appconfig-new-relic-for-automated-rollback/" rel="noopener"&gt;New Relic&lt;/a&gt;, &lt;a href="https://docs.splunk.com/observability/en/gdi/integrations/cloud-aws.html" target="_blank" rel="noopener"&gt;Splunk&lt;/a&gt;, or &lt;a href="https://docs.dynatrace.com/docs/setup-and-configuration/setup-on-cloud-platforms/amazon-web-services" target="_blank" rel="noopener"&gt;Dynatrace&lt;/a&gt;) that monitors your application’s error rate or latency. If the alarm enters ALARM state, AWS AppConfig automatically rolls back to the previous configuration version. The companion repository includes a complete CloudWatch alarm example wired to the deployment.&lt;/p&gt; 
&lt;h2 id="updating-feature-flags-without-code-deployments"&gt;Updating feature flags without code deployments&lt;/h2&gt; 
&lt;p&gt;After your stack is deployed, you can update any feature flag by creating a new configuration version and starting a deployment:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws appconfig create-hosted-configuration-version \
  --application-id &amp;lt;APP_ID&amp;gt; \
  --configuration-profile-id &amp;lt;PROFILE_ID&amp;gt; \
  --content-type "application/json" \
  --content '{"new_recommendation_engine":{"enabled":true},"enhanced_logging":{"enabled":true}}'

aws appconfig start-deployment \
  --application-id &amp;lt;APP_ID&amp;gt; \
  --environment-id &amp;lt;ENV_ID&amp;gt; \
  --deployment-strategy-id &amp;lt;STRATEGY_ID&amp;gt; \
  --configuration-profile-id &amp;lt;PROFILE_ID&amp;gt; \
  --configuration-version &amp;lt;VERSION&amp;gt;&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Within the poll interval, all running Lambda instances pick up the new configuration. No code changes, no redeployment, no downtime. Reverting a flag is equally fast and symmetric. Deploying the previous configuration version propagates in the same ~30 seconds, giving you a consistent rollback speed whether you are enabling or disabling a feature. Importantly, the API contract (response structure, status codes, error shapes) remains stable regardless of flag state. Only the behavior behind the toggle changes, so consumers of your API are never broken by a flag flip.&lt;/p&gt; 
&lt;h2 id="best-practices"&gt;Best practices&lt;/h2&gt; 
&lt;p&gt;The &lt;strong&gt;AWS AppConfig Agent Lambda extension&lt;/strong&gt; may add time to your function’s &lt;code&gt;Init&lt;/code&gt; phase as it establishes a session and retrieves the initial configuration. On subsequent invocations, the extension serves from its &lt;strong&gt;local cache&lt;/strong&gt; with sub-millisecond latency. If your function has a strict cold start target, consider provisioned concurrency for latency-critical paths.&lt;/p&gt; 
&lt;p&gt;The extension’s &lt;strong&gt;poll interval&lt;/strong&gt; determines how quickly your fleet converges on a new configuration. The template configures 30 seconds (the AWS default is 45 seconds). This interval suits most rollouts. For emergency disable switches, reduce it to 15 seconds (do not go below 5 seconds) via the &lt;code&gt;AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS&lt;/code&gt; environment variable so all instances converge within one cycle. The extension is also &lt;strong&gt;resilient to network failures&lt;/strong&gt;. If it cannot reach AWS AppConfig, it continues serving the last known good configuration from cache. Your function never fails because of an upstream connectivity issue.&lt;/p&gt; 
&lt;p&gt;Use the &lt;code&gt;AWS_APPCONFIG_EXTENSION_PREFETCH_LIST&lt;/code&gt; environment variable so that configuration data is available before your function code runs. This retrieves config data during the &lt;code&gt;Init&lt;/code&gt; phase before the Lambda starts to execute the function code, reducing latency on the first invocation. See the &lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions-config.html" target="_blank" rel="noopener"&gt;AWS AppConfig Lambda extension configuration reference&lt;/a&gt; for details.&lt;/p&gt; 
&lt;p&gt;Use the AppConfig first-class “feature-flag” configuration profile type with its opinionated JSON format. This data type gives you a simple console experience for non-technical users, advanced multi-variate flags, and tools for cleaning up stale feature flags. Treat toggles as &lt;strong&gt;temporary by nature&lt;/strong&gt;: after a feature is stable, remove the flag and its conditional logic to prevent dead-code sprawl. And scope your &lt;strong&gt;&lt;a href="https://aws.amazon.com/iam/" target="_blank" rel="noopener"&gt;AWS Identity and Access Management (IAM)&lt;/a&gt; permissions&lt;/strong&gt; so the extension is strictly a read-only consumer. Grant only &lt;code&gt;appconfig:StartConfigurationSession&lt;/code&gt; and &lt;code&gt;appconfig:GetLatestConfiguration&lt;/code&gt; on the specific resource ARN, ensuring a compromised function cannot modify configurations.&lt;/p&gt; 
&lt;h2 id="clean-up"&gt;Clean up&lt;/h2&gt; 
&lt;p&gt;To avoid ongoing charges, delete the resources you created in this walkthrough. Run the following command from the project directory:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;sam delete --stack-name &amp;lt;your-stack-name&amp;gt;&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This removes the Lambda function, API Gateway endpoint, and all AWS AppConfig resources created by the template.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;The AWS AppConfig Lambda extension provides a lightweight, managed approach to feature flags in serverless applications. The extension handles caching, polling, and session management, while AWS AppConfig provides safe deployment strategies with validation and automatic rollback.&lt;/p&gt; 
&lt;p&gt;Compared to building your own feature flag infrastructure or using environment variables, this approach eliminates redeployment overhead, reduces latency (sub-millisecond reads from local cache), and provides production safety mechanisms out of the box. Your function code stays simple: a single HTTP GET to a local endpoint.&lt;/p&gt; 
&lt;p&gt;The pattern shown in this post applies beyond simple boolean flags. You can store complex configuration objects, percentage-based rollout rules, or user-segment targeting data in the same configuration profile. As your feature management needs grow, AWS AppConfig scales with you without requiring changes to the Lambda function integration pattern.&lt;/p&gt; 
&lt;p&gt;With feature flags in place, you also have the foundation for &lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-experimentation.html" target="_blank" rel="noopener"&gt;AWS AppConfig Experimentation&lt;/a&gt;. From here you can define multi-variate experiments, allocate traffic to variants, and measure outcomes across your full stack, turning the feature flags you built in this post into a controlled experiment.&lt;/p&gt; 
&lt;p&gt;This combination enables you to ship features faster with confidence, respond to incidents by disabling features in seconds, and experiment with gradual rollouts without any infrastructure overhead.&lt;/p&gt; 
&lt;p&gt;You can find the complete source code in the &lt;a href="https://github.com/aws-samples/sample-lambda-extensions-appconfig-feature-toggles" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;If you have questions or feedback about this solution, leave a comment on this post.&lt;/p&gt; 
&lt;p&gt;For more information, see:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html" target="_blank" rel="noopener"&gt;Using AWS AppConfig Agent with AWS Lambda&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-deployment-strategy.html" target="_blank" rel="noopener"&gt;AWS AppConfig deployment strategies&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For more serverless learning resources, visit &lt;a href="https://serverlessland.com" target="_blank" rel="noopener"&gt;Serverless Land&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Observability best practices for Lambda durable functions</title>
		<link>https://aws.amazon.com/blogs/compute/observability-best-practices-for-lambda-durable-functions-2/</link>
		
		<dc:creator><![CDATA[D Surya Sai]]></dc:creator>
		<pubDate>Fri, 14 Aug 2026 12:49:49 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">ed8cc16a4062b081a0327240b429ac93d97cbec6</guid>

					<description>Learn observability best practices for AWS Lambda durable functions, including CloudWatch metrics, custom alarms, structured logging, and X-Ray tracing for debugging callback timeouts end-to-end.</description>
										<content:encoded>&lt;p&gt;When your workflow suspends to wait for a confirmation, you need to know whether the callback arrived, how long the function waited, and what to do if the callback never comes. &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; durable functions make these long-running, suspendable workflows straightforward to build, but answering those operational questions requires deliberate monitoring instrumentation across the suspension boundary.&lt;/p&gt; 
&lt;p&gt;In this post, we walk through observability best practices for Lambda durable functions using a Stripe payment processing pipeline as the example. We cover durable function-specific &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt; metrics, custom business metrics, alarms, structured logging, &lt;a href="https://aws.amazon.com/xray/" target="_blank" rel="noopener"&gt;AWS X-Ray&lt;/a&gt; tracing, and how to debug a callback timeout end-to-end. By the end, you will have a reusable observability pattern for any durable function that suspends on external callbacks. The GitHub repository contains the complete implementation.&lt;/p&gt; 
&lt;h2 id="architecture-overview"&gt;Architecture overview&lt;/h2&gt; 
&lt;p&gt;Our application processes card payments through Stripe using three Lambda functions and &lt;a href="https://aws.amazon.com/api-gateway/" target="_blank" rel="noopener"&gt;Amazon API Gateway&lt;/a&gt;:&lt;/p&gt; 
&lt;p&gt;1. Payment API (payment-api): An API Gateway-backed function that accepts payment requests, asynchronously invokes the durable function, and exposes endpoints to check or cancel an in-flight execution.&lt;/p&gt; 
&lt;p&gt;2. Payment Processor (payment-processor): A durable function that validates the payment, creates a Stripe PaymentIntent, then suspends and waits for a callback confirming the payment outcome.&lt;/p&gt; 
&lt;p&gt;3. Webhook Handler (stripe-webhook): Receives Stripe webhook events, verifies the signature, and calls &lt;code&gt;send_durable_execution_callback_success&lt;/code&gt; to resume the suspended durable execution with the payment result.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/06/25/ComputeBlog-2544-1.png" alt="Architecture diagram showing payment processing flow with durable callback suspension" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 1: Payment processing flow with durable callback suspension, where the webhook handler sends the callback result back to the same suspended durable execution&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;The key observability challenge sits in the gap between the PaymentIntent creation (step 2) and the webhook delivery (step 3). During this period the durable function is suspended: it is consuming no compute, but it is waiting for Stripe to call back. If the webhook never arrives, the callback times out silently unless you have metrics and alarms watching for it. With proper instrumentation, you gain full visibility into this suspension gap and can diagnose issues within minutes.&lt;/p&gt; 
&lt;p&gt;You deploy the application with &lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM)&lt;/a&gt;. The following template excerpt shows how we enable observability across the stack:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;Globals:
  Function:
    Runtime: python3.13
    Tracing: Active # X-Ray on all functions
    Environment:
      Variables:
        POWERTOOLS_METRICS_NAMESPACE: DurablePayments
        LOG_LEVEL: INFO

Resources:
  PaymentApi:
    Type: AWS::Serverless::Api
    Properties:
      TracingEnabled: true # X-Ray on API Gateway

  PaymentProcessorFunction:
    Type: AWS::Serverless::Function
    Properties:
      AutoPublishAlias: live
      DurableConfig:
        ExecutionTimeout: 600 # Bounds the whole workflow
        RetentionPeriodInDays: 5 # Keep execution history&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Tracing: Active under Globals enables X-Ray across all functions, and TracingEnabled: true on the API resource ensures traces propagate from the initial request through the entire flow.&lt;/p&gt; 
&lt;h2 id="durable-function-cloudwatch-metrics-custom-business-metrics-and-alarms"&gt;Durable function CloudWatch metrics, custom business metrics, and alarms&lt;/h2&gt; 
&lt;p&gt;Lambda automatically emits CloudWatch metrics specific to durable executions, covering execution lifecycle, capacity utilization, duration including wait time, and cost drivers. For the full list, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-monitoring.html" target="_blank" rel="noopener"&gt;Monitoring durable functions&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;One metric worth calling out: &lt;code&gt;DurableExecutionDuration&lt;/code&gt; measures total wall-clock time including the callback wait period. For a payment that takes 2 seconds to process but waits 30 seconds for a webhook, this metric reports approximately 32 seconds. This is distinct from the standard &lt;code&gt;Duration&lt;/code&gt; metric, which only measures active compute time.&lt;/p&gt; 
&lt;h3 id="custom-business-metrics-for-the-callback-funnel"&gt;Custom business metrics for the callback funnel&lt;/h3&gt; 
&lt;p&gt;The built-in metrics tell you whether executions succeeded or failed. To understand where in the business flow the issue occurred, we emit custom metrics at each stage using &lt;a href="https://docs.aws.amazon.com/powertools/python/latest/" target="_blank" rel="noopener"&gt;Powertools for AWS Lambda&lt;/a&gt; Metrics with Embedded Metric Format (EMF):&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;from aws_lambda_powertools import Metrics
from aws_lambda_powertools.metrics import MetricUnit

metrics = Metrics(namespace="DurablePayments", service="payment-processor")

# In the durable handler, after each stage:
metrics.add_metric(name="PaymentIntentCreated", unit=MetricUnit.Count, value=1)
metrics.add_metric(name="PaymentSucceeded", unit=MetricUnit.Count, value=1)
metrics.add_metric(name="PaymentFailed", unit=MetricUnit.Count, value=1)
metrics.add_metric(name="PaymentTimeout", unit=MetricUnit.Count, value=1)&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;In the webhook handler:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;metrics.add_metric(name="WebhookReceived", unit=MetricUnit.Count, value=1)
metrics.add_metric(name="WebhookSucceeded", unit=MetricUnit.Count, value=1)
metrics.add_metric(name="WebhookSignatureFailure", unit=MetricUnit.Count, value=1)&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;These metrics create an end-to-end funnel:&lt;/p&gt; 
&lt;p&gt;PaymentRequested → PaymentIntentCreated → WebhookReceived → WebhookSucceeded → PaymentSucceeded&lt;/p&gt; 
&lt;p&gt;Any drop-off between stages pinpoints the problem. If PaymentIntentCreated is higher than WebhookReceived, Stripe is not delivering webhooks. If WebhookReceived is higher than WebhookSucceeded, signature verification is failing. No corresponding PaymentSucceeded for a PaymentIntentCreated means the callback timed out.&lt;/p&gt; 
&lt;h3 id="alarms-for-callback-failure-modes"&gt;Alarms for callback failure modes&lt;/h3&gt; 
&lt;p&gt;Durable functions with callbacks have specific failure modes: callbacks that never arrive, webhook signatures that fail verification, and executions that time out waiting. We define alarms for each:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;DurableExecutionFailureAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    Namespace: AWS/Lambda
    MetricName: DurableExecutionFailed
    Dimensions:
      - Name: FunctionName
        Value: !Ref PaymentProcessorFunction
    Threshold: 1
    ComparisonOperator: GreaterThanOrEqualToThreshold
    TreatMissingData: notBreaching
    ...

PaymentTimeoutAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    Namespace: DurablePayments
    MetricName: PaymentTimeout
    Dimensions:
      - Name: service
        Value: payment-processor
    Threshold: 1
    ...

WebhookSignatureFailureAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    Namespace: DurablePayments
    MetricName: WebhookSignatureFailure
    Dimensions:
      - Name: service
        Value: stripe-webhook
    Threshold: 3&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;These alarm definitions are abbreviated for readability. Each alarm in the deployed &lt;code&gt;template.yaml&lt;/code&gt; also sets Dimensions (scoping &lt;code&gt;DurableExecutionFailed&lt;/code&gt; to the payment-processor function, and the custom metrics to their service). It also includes Statistic, Period, EvaluationPeriods, and AlarmActions/OKActions wired to an SNS topic. See the &lt;a href="https://github.com/aws-samples/sample-lambda-durable-functions/blob/main/Industry%20Solutions/Financial%20Services%20(FSI)/PaymentProcessing/template.yaml" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt; for the deployable definitions.&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Alarm&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;What it catches&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;DurableExecutionFailed&lt;/td&gt; 
   &lt;td&gt;Code errors, Stripe API failures, unhandled exceptions in the durable function&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;DurableExecutionTimedOut&lt;/td&gt; 
   &lt;td&gt;Whole-execution timeout: execution exceeds &lt;code&gt;DurableConfig.ExecutionTimeout&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;PaymentTimeout&lt;/td&gt; 
   &lt;td&gt;Callbacks that never arrive: webhook misconfiguration, Stripe outage, network issues&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;WebhookSignatureFailure&lt;/td&gt; 
   &lt;td&gt;Wrong webhook secret, replay attacks, endpoint misconfiguration&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;WebhookError&lt;/td&gt; 
   &lt;td&gt;Webhook function error spikes (unhandled exceptions in the handler)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3 id="unified-dashboard"&gt;Unified dashboard&lt;/h3&gt; 
&lt;p&gt;We combine built-in durable metrics, custom EMF metrics, and standard Lambda metrics into a single CloudWatch dashboard. The dashboard includes widgets for execution state, payment outcomes, end-to-end flow metrics, quota utilization, cost drivers, error breakdown, and API/webhook latency.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/06/25/ComputeBlog-2544-2.png" alt="CloudWatch dashboard showing durable execution state, payment outcomes, and end-to-end flow metrics" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 2: CloudWatch dashboard showing durable execution state, payment outcomes, end-to-end flow metrics, running executions and quota utilization&lt;/p&gt;
&lt;/div&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/06/25/ComputeBlog-2544-3.png" alt="CloudWatch Alarms panel showing DurableExecutionFailures, PaymentTimeouts, and WebhookSignatureFailures alarm states" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 3: CloudWatch Alarms showing DurableExecutionFailures, PaymentTimeouts, and WebhookSignatureFailures alarm states&lt;/p&gt;
&lt;/div&gt; 
&lt;h2 id="tracing-callbacks-across-the-suspension-boundary"&gt;Tracing callbacks across the suspension boundary&lt;/h2&gt; 
&lt;p&gt;When a durable function suspends at a callback, the execution pauses. An external system (Stripe) fires a webhook to your API Gateway, which invokes the webhook handler. The webhook handler then calls &lt;code&gt;send_durable_execution_callback_success&lt;/code&gt; to deliver the result back to the suspended execution, which resumes and completes. The challenge is correlating these two separate invocations so you can reconstruct the full payment timeline from a single query.&lt;/p&gt; 
&lt;h3 id="structured-logging-with-correlation-keys"&gt;Structured logging with correlation keys&lt;/h3&gt; 
&lt;p&gt;Using Lambda Powertools Logger, we progressively append correlation keys as they become available. Each subsequent log entry automatically includes all previously appended keys:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;from aws_lambda_powertools import Logger
from aws_durable_execution_sdk_python import (
    DurableContext, durable_execution, durable_step,
)
from aws_durable_execution_sdk_python.config import CallbackConfig, Duration
from aws_durable_execution_sdk_python.exceptions import CallbackError

logger = Logger(service="payment-processor")

@durable_execution
def handler(event, context: DurableContext):
    payment = context.step(validate_payment_request(event), name="validate-payment")
    logger.append_keys(customer_id=payment["customer_id"])

    callback = context.create_callback(
        name="stripe-payment-result",
        config=CallbackConfig(timeout=Duration.from_minutes(5)),
    )
    logger.info("Callback created", callback_id=callback.callback_id)

    intent = context.step(
        create_stripe_payment_intent(payment, callback.callback_id),
        name="create-payment-intent",
    )
    logger.append_keys(payment_intent_id=intent["payment_intent_id"])
    logger.info("Suspending, waiting for Stripe webhook callback")

    try:
        result = callback.result()  # Function suspends here
    except CallbackError:
        logger.warning("Payment timed out")
        return {"status": "timeout", "message": "No confirmation within 5 minutes"}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;In the webhook handler, we append the same keys so a single Logs Insights query reconstructs the full timeline:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;logger = Logger(service="stripe-webhook")

def handler(event, context):
    # ... verify signature, parse event
    logger.append_keys(event_type=event_type, payment_intent_id=payment_intent_id)
    logger.append_keys(callback_id=callback_id)
    logger.info("Processing webhook event")&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Query across all three log groups for a single payment:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-plaintext"&gt;fields @timestamp, service, message, customer_id, payment_intent_id, callback_id
| filter payment_intent_id = "pi_3TJafD04vzZc6RmP0RrCWhix"
| sort @timestamp asc&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/06/25/ComputeBlog-2544-4.png" alt="CloudWatch Logs Insights query showing the timeline of a single payment across payment-api, payment-processor, and stripe-webhook" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 4: CloudWatch Logs Insights query showing the timeline of a single payment across payment-api, payment-processor, and stripe-webhook&lt;/p&gt;
&lt;/div&gt; 
&lt;h3 id="durable-steps-and-x-ray-annotations"&gt;Durable steps and X-Ray annotations&lt;/h3&gt; 
&lt;p&gt;The SDK’s &lt;code&gt;@durable_step&lt;/code&gt; decorator checkpoints each step. If the function crashes and replays, completed steps return their cached result without re-executing. We combine this with Powertools Tracer to add searchable X-Ray annotations at each business-critical point:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;from aws_durable_execution_sdk_python import StepContext, durable_step

@durable_step
@tracer.capture_method
def create_stripe_payment_intent(step_context: StepContext, payment: dict, callback_id: str) -&amp;gt; dict:
    tracer.put_annotation("callback_id", callback_id)
    tracer.put_annotation("customer_id", payment["customer_id"])

    try:
        intent = stripe.PaymentIntent.create(
            amount=payment["amount"], currency=payment["currency"],
            payment_method=payment["payment_method_id"], confirm=True,
            metadata={"callback_id": callback_id},
            automatic_payment_methods={"enabled": True, "allow_redirects": "never"},
            ...
        )
    except stripe.error.CardError as exc:
        # Hard declines (e.g. pm_card_chargeDeclined) raise synchronously. Return a
        # structured decline so the step doesn't retry and fail the whole execution.
        ...
        metrics.add_metric(name="PaymentDeclinedAtCreate", unit=MetricUnit.Count, value=1)
        return {"declined": True, ...}  # decline_code, error_message, payment_intent_id

    metrics.add_metric(name="PaymentIntentCreated", unit=MetricUnit.Count, value=1)
    ...
    return {"payment_intent_id": intent.id, "status": intent.status}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Note: The preceding code is abbreviated for readability. Refer to the &lt;a href="https://github.com/aws-samples/sample-lambda-durable-functions/tree/main/Industry%20Solutions/Financial%20Services%20(FSI)/PaymentProcessing" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt; for the complete code. The main durable handler runs within a FacadeSegment X-Ray context that does not support &lt;code&gt;put_annotation()&lt;/code&gt;. Annotations work normally inside &lt;code&gt;@durable_step&lt;/code&gt; functions. In the main handler, use a try/except wrapper if you need annotations outside of steps.&lt;/p&gt; 
&lt;p&gt;Note: When calling &lt;code&gt;PaymentIntent.create&lt;/code&gt; with &lt;code&gt;confirm=True&lt;/code&gt;, some cards decline synchronously (no webhook fires). The deployed code handles this by detecting the decline in the step return value and skipping the callback suspension, preventing an indefinite wait.&lt;/p&gt; 
&lt;p&gt;The X-Ray Service Map shows the complete request flow: API Gateway to payment-api to payment-processor, and the separate webhook path from API Gateway to stripe-webhook.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/06/25/ComputeBlog-2544-5.png" alt="X-Ray Service Map showing API Gateway connected to payment-api and stripe-webhook, with payment-api connected to payment-processor" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 5: X-Ray Service Map showing API Gateway connected to payment-api and stripe-webhook, with payment-api connected to payment-processor&lt;/p&gt;
&lt;/div&gt; 
&lt;h3 id="durable-executions-tab"&gt;Durable executions tab&lt;/h3&gt; 
&lt;p&gt;The Lambda console provides a built-in Durable executions tab showing each execution’s step-by-step timeline, including the callback wait state. You can see which steps completed, where the function suspended, and when (or if) the callback arrived.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/14/compute-2544-fig-6.png" alt="Lambda console Durable executions tab showing a completed execution with steps: validate-payment succeeded, create-payment-intent succeeded, stripe-payment-result callback received, and final result succeeded" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 6: Lambda console Durable executions tab showing a completed execution with steps: validate-payment succeeded, create-payment-intent succeeded, stripe-payment-result callback received, and final result succeeded&lt;/p&gt;
&lt;/div&gt; 
&lt;h2 id="putting-it-together-debugging-real-failure-modes"&gt;Putting it together: debugging real failure modes&lt;/h2&gt; 
&lt;p&gt;The following three scenarios demonstrate how all of these observability layers work together. You can reproduce each one from the demo checkout page.&lt;/p&gt; 
&lt;h3 id="scenario-1-webhook-never-arrives"&gt;Scenario 1: Webhook never arrives&lt;/h3&gt; 
&lt;p&gt;A customer reports that their payment was charged but they never received a confirmation.&lt;/p&gt; 
&lt;p&gt;1. Alarm fires. The PaymentTimeoutAlarm triggers, indicating a durable execution timed out waiting for a callback.&lt;/p&gt; 
&lt;p&gt;2. Check the dashboard. The Payment Outcomes widget shows a spike in PaymentTimeout. The End-to-End Flow Metrics widget reveals the drop-off: PaymentIntentCreated count is higher than WebhookReceived, meaning the webhook never arrived.&lt;/p&gt; 
&lt;p&gt;3. Query logs. Search Amazon CloudWatch Logs Insights for the timed-out payment:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-plaintext"&gt;fields @timestamp, service, message, payment_intent_id, callback_id
| filter message = "Payment timed out"
| sort @timestamp desc
| limit 5&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This returns the payment_intent_id of the timed-out payment.&lt;/p&gt; 
&lt;p&gt;4. Cross-reference the webhook handler. Search for that payment_intent_id in the webhook handler logs. No results means Stripe never delivered the webhook. Results with WebhookSignatureFailure mean the webhook secret is misconfigured.&lt;/p&gt; 
&lt;p&gt;5. Inspect the X-Ray trace. Filter traces by the payment_intent_id annotation. The trace shows the durable function start but no corresponding webhook handler span, confirming the webhook never arrived.&lt;/p&gt; 
&lt;p&gt;6. Check the durable executions tab. The execution shows validate-payment and create-payment-intent as succeeded, with the stripe-payment-result callback in a timed-out state.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/14/compute-2544-fig-7.png" alt="Durable executions tab showing the timed-out execution: validate-payment succeeded, create-payment-intent succeeded, stripe-payment-result callback timed out" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 7: Durable executions tab showing the timed-out execution: validate-payment succeeded, create-payment-intent succeeded, stripe-payment-result callback timed out&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;Within minutes, you have identified the root cause (the Stripe webhook endpoint was misconfigured) without adding a single debug statement or redeploying code.&lt;/p&gt; 
&lt;h3 id="scenario-2-the-whole-workflow-runs-too-long"&gt;Scenario 2: The whole workflow runs too long&lt;/h3&gt; 
&lt;p&gt;The callback timeout in Scenario 1 is a per-callback bound (5 minutes in this example). There is also an outer bound: &lt;code&gt;DurableConfig.ExecutionTimeout&lt;/code&gt; (600 seconds), which caps the total wall-clock time of the whole execution. If you set a callback to wait an hour but the overall &lt;code&gt;ExecutionTimeout&lt;/code&gt; is 10 minutes, the execution itself terminates first. This shows up as a distinct terminal state in the durable executions tab, on the Durable Execution State widget, and as its own alarm (&lt;code&gt;DurableExecutionTimedOutAlarm&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;Choose the “Simulate timeout (no webhook)” option on the demo checkout page to reproduce this. The durable function skips the Stripe call, suspends on a long-timeout callback, and lets &lt;code&gt;ExecutionTimeout&lt;/code&gt; catch it. The dashboard distinguishes the two failure modes cleanly: per-callback timeouts show up on the custom Payment Outcomes widget as &lt;code&gt;PaymentTimeout&lt;/code&gt;. Whole-execution timeouts appear on the built-in Durable Execution State widget alongside started/succeeded/failed counts. This distinction matters operationally because the remediation is different: callback timeouts point to external system issues (Stripe), while execution timeouts point to configuration issues (your timeout values).&lt;/p&gt; 
&lt;h3 id="scenario-3-customer-abandons-checkout"&gt;Scenario 3: Customer abandons checkout&lt;/h3&gt; 
&lt;p&gt;Real checkout flows have a third outcome: the customer cancels while the durable function is still suspended. The demo wires this up to &lt;code&gt;StopDurableExecution&lt;/code&gt;, which terminates the in-flight execution and surfaces on the same Durable Execution State widget as a separate terminal state.&lt;/p&gt; 
&lt;p&gt;Choose “Simulate timeout” and then “Cancel Payment” on the demo page to see this happen. Looking at the dashboard after running all three scenarios, the execution-state widget tells the full story: started, succeeded, failed, timed-out, and stopped. Each state answers a different operational question about what is happening to your workflows.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;In this post, we walked through observability best practices for Lambda durable functions using a Stripe payment processing pipeline. Callbacks can time out, whole executions can expire, and running workflows can be canceled. Each shows up as a distinct terminal state, and each deserves its own alarm. Layering custom business metrics, structured logging with correlation keys, X-Ray annotations, and the durable executions tab on top of the built-in CloudWatch metrics gives you a clear picture of where in the lifecycle any given execution is. It also reveals where in the business funnel any failure occurred.&lt;/p&gt; 
&lt;p&gt;Deploy the payment processing application from the &lt;a href="https://github.com/aws-samples/sample-lambda-durable-functions/tree/main/Industry%20Solutions/Financial%20Services%20(FSI)/PaymentProcessing" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt; and try the three demo scenarios to see the dashboards, alarms, and execution history in your own account. For core concepts, see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener"&gt;Lambda durable functions&lt;/a&gt;. For the durable execution SDK, see the &lt;a href="https://pypi.org/project/aws-durable-execution-sdk-python/" target="_blank" rel="noopener"&gt;Python SDK&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@aws/durable-execution-sdk" target="_blank" rel="noopener"&gt;JavaScript SDK&lt;/a&gt;, and &lt;a href="https://central.sonatype.com/artifact/software.amazon.lambda/durable-execution-sdk" target="_blank" rel="noopener"&gt;Java SDK&lt;/a&gt;. Browse &lt;a href="https://serverlessland.com/" target="_blank" rel="noopener"&gt;Serverless Land&lt;/a&gt; for reference architectures.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Collecting CPU and memory metrics for AWS Lambda MicroVMs</title>
		<link>https://aws.amazon.com/blogs/compute/collecting-cpu-and-memory-metrics-for-aws-lambda-microvms/</link>
		
		<dc:creator><![CDATA[Eric Heinz]]></dc:creator>
		<pubDate>Fri, 14 Aug 2026 11:11:55 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">a454e6289e1933f3f389e06763013ebe81193d0d</guid>

					<description>Learn how to collect CPU and memory metrics from AWS Lambda MicroVMs using the CloudWatch Agent. Configure telegraf and OTel to monitor and right-size your workloads.</description>
										<content:encoded>&lt;p&gt;Most production services in AWS use at least two key metrics for service health – CPU and memory utilization. The amount of CPU and memory used by the host (in this case, a MicroVM) can indicate scaling signals or inefficiencies in your application. If you’re running a production workload on &lt;a href="https://aws.amazon.com/lambda/lambda-microvms/" target="_blank" rel="noopener"&gt;AWS Lambda MicroVMs&lt;/a&gt;, it’s recommended to have observability in these dimensions. And the easiest way to collect these metrics is through the &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html" target="_blank" rel="noopener"&gt;Amazon CloudWatch Agent&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;This blog shows you how to collect CPU and memory metrics from within the MicroVM using the CloudWatch Agent.&lt;/p&gt; 
&lt;h2 id="how-to-collect-cpu-and-memory-metrics-in-your-microvm"&gt;How to collect CPU and memory metrics in your MicroVM&lt;/h2&gt; 
&lt;p&gt;To observe how a workload uses CPU and memory over time, run the CloudWatch Agent inside the MicroVM. Since a MicroVM image is a full OS snapshot, you can start the agent during image creation, meaning it will already be running the moment a MicroVM launches from that image. This means zero startup latency and one-time configuration: set up the CloudWatch Agent once in the image, and every MicroVM that launches from it already has a running monitoring stack.&lt;/p&gt; 
&lt;p&gt;To setup CloudWatch Agent, you will modify the ZIP containing your application and &lt;code&gt;Dockerfile&lt;/code&gt;, and build a MicroVM image. Once you run a MicroVM from the image, three metrics will be emitted (&lt;code&gt;cpu_usage_active&lt;/code&gt;, &lt;code&gt;cpu_usage_idle&lt;/code&gt;, &lt;code&gt;mem_used_percent&lt;/code&gt;) under an &lt;code&gt;ImageName&lt;/code&gt; dimension populated from a Lambda-injected environment variable.&lt;/p&gt; 
&lt;h3 id="lambda-injected-environment-variables"&gt;Lambda-injected environment variables&lt;/h3&gt; 
&lt;p&gt;The Lambda MicroVMs runtime automatically exposes these environment variables to your application:&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Env var&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;AWS_LAMBDA_MICROVM_IMAGE_NAME&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;mem-python&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;AWS_LAMBDA_MICROVM_IMAGE_ARN&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;arn:aws:lambda:us-west-2:…:microvm-image:mem-python&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;AWS_LAMBDA_MICROVM_IMAGE_VERSION&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;1.0&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;AWS_REGION&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;us-west-2&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;The example below uses &lt;code&gt;AWS_LAMBDA_MICROVM_IMAGE_NAME&lt;/code&gt; as a metric dimension so you can monitor metrics per MicroVM image.&lt;/p&gt; 
&lt;h3 id="setting-up-custom-metric-dimensions-from-env-variables"&gt;Setting up custom metric dimensions from env variables&lt;/h3&gt; 
&lt;p&gt;Amazon CloudWatch Agent uses &lt;a href="https://github.com/influxdata/telegraf" target="_blank" rel="noopener"&gt;telegraf&lt;/a&gt; to process metrics and &lt;a href="https://github.com/open-telemetry/opentelemetry-collector" target="_blank" rel="noopener"&gt;opentelemetry-collector (OTel)&lt;/a&gt; to export them. Normally, you configure the agent through a &lt;code&gt;cwagent.json&lt;/code&gt; file, which the agent’s config-translator converts into a telegraf TOML file and an OTel YAML file for the process to use at startup.&lt;/p&gt; 
&lt;p&gt;In this post, we skip the JSON configuration and create the telegraf and OTel files directly. This lets us dynamically set a custom metric dimension from an environment variable using OTel’s &lt;code&gt;${env:VAR}&lt;/code&gt; syntax. The telegraf config defines which metrics to collect, while the OTel config resolves the environment variable at process start and appends it as a dimension.&lt;/p&gt; 
&lt;h3 id="configuring-cloudwatch-agent"&gt;Configuring CloudWatch Agent&lt;/h3&gt; 
&lt;p&gt;In this section, we cover how to configure CloudWatch Agent to report CPU and memory metrics for MicroVMs launched from your MicroVM image.&lt;/p&gt; 
&lt;h4 id="step-1-configure-the-telegraf-plugin-to-emit-cpu-and-memory-metrics"&gt;Step 1: Configure the telegraf plugin to emit CPU and Memory metrics&lt;/h4&gt; 
&lt;p&gt;Create a &lt;code&gt;cwagent.toml&lt;/code&gt; file to define the configuration for telegraf to emit CPU and memory metrics every minute:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-toml"&gt;[agent]
  interval = "60s"
  flush_interval = "60s"

  # Host name is omitted since it doesn't exist in a MicroVM
  omit_hostname = true

[[inputs.cpu]]
  totalcpu = true

  # Disable per-CPU reporting for an aggregate view over all vCPUs in your MicroVM.
  # Set to 'true' to see utilization for each individual vCPU.
  percpu = false
  report_active = true
  fieldpass = ["usage_active", "usage_idle"]

[[inputs.mem]]
  fieldpass = ["used_percent"]&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;In this configuration, the chosen metric (&lt;code&gt;used_percent&lt;/code&gt;) reports memory usage as a percentage of total memory inside the MicroVM. Telegraf derives this from &lt;code&gt;MemAvailable&lt;/code&gt; in &lt;code&gt;/proc/meminfo&lt;/code&gt;, which reflects memory that is committed and not reclaimable. When your application releases memory back to the OS (e.g. via &lt;code&gt;free()&lt;/code&gt;), that memory becomes reclaimable again, and &lt;code&gt;used_percent&lt;/code&gt; decreases accordingly.&lt;/p&gt; 
&lt;p&gt;To monitor additional memory metrics, you can add the following fields to the &lt;code&gt;fieldpass&lt;/code&gt; list:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;cached&lt;/code&gt;: for page cache bytes&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;buffered&lt;/code&gt;: for buffered I/O bytes&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;total&lt;/code&gt;: for total memory available to the MicroVM&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4 id="step-2-configure-otel-to-process-and-export-the-metrics-to-cloudwatch"&gt;Step 2: Configure OTel to process and export the metrics to CloudWatch&lt;/h4&gt; 
&lt;p&gt;Create a &lt;code&gt;cwagent.yaml&lt;/code&gt; file to export metrics to CloudWatch under the namespace &lt;code&gt;LambdaMicroVms/Application&lt;/code&gt; with dimension &lt;code&gt;ImageName&lt;/code&gt;. The dimension value is populated from the environment variable &lt;code&gt;AWS_LAMBDA_MICROVM_IMAGE_NAME&lt;/code&gt;.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;receivers:
  telegraf_cpu: { collection_interval: 60s }
  telegraf_mem: { collection_interval: 60s }

processors:
  resource:
    attributes:
      - { key: ImageName, value: "${env:AWS_LAMBDA_MICROVM_IMAGE_NAME}", action: insert }
  transform/strip_cpu_dim:
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - delete_key(attributes, "cpu")

exporters:
  awscloudwatch:
    namespace: LambdaMicroVms/Application
    region: ${env:AWS_REGION}
    resource_to_telemetry_conversion: { enabled: true }

service:
  pipelines:
    metrics:
      receivers:  [telegraf_cpu, telegraf_mem]
      processors: [resource, transform/strip_cpu_dim]
      exporters:  [awscloudwatch]&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;If you want more dimensions such as image version, add it to attributes.&lt;/p&gt; 
&lt;p class="note"&gt;&lt;strong&gt;Note:&lt;/strong&gt; since only aggregate CPU usage is emitted by telegraf, we don’t need OTel to include a CPU dimension, so &lt;code&gt;delete_key(attributes, "cpu")&lt;/code&gt; is used to remove this dimension.&lt;/p&gt; 
&lt;h4 id="step-3-install-cloudwatch-agent-in-your-dockerfile"&gt;Step 3: Install CloudWatch Agent in your Dockerfile&lt;/h4&gt; 
&lt;p&gt;In your &lt;code&gt;Dockerfile&lt;/code&gt;, install the CloudWatch Agent from the Amazon Linux repository. Then copy over the telegraf and OTel files to where the agent expects to retrieve them. Then configure your application’s entrypoint:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-dockerfile"&gt;FROM public.ecr.aws/lambda/microvms:al2023-minimal

RUN dnf install -y --setopt=install_weak_deps=0 \
        python3 amazon-cloudwatch-agent \
    &amp;amp;&amp;amp; dnf clean all

COPY app.py        /app/app.py
COPY cwagent.toml  /etc/cwagent.toml
COPY cwagent.yaml  /etc/cwagent.yaml
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

CMD ["/entrypoint.sh"]&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h4 id="step-4-configure-your-entrypoint-to-start-cloudwatch-agent"&gt;Step 4: Configure your Entrypoint to start CloudWatch Agent&lt;/h4&gt; 
&lt;p&gt;Create a file called &lt;code&gt;entrypoint.sh&lt;/code&gt; to start the CloudWatch Agent as a background process while executing your application in the foreground:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;#!/usr/bin/env bash
set -euo pipefail

# Telegraf inputs (TOML) + OTel pipeline (YAML).
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent \
    -config     /etc/cwagent.toml \
    -otelconfig /etc/cwagent.yaml &amp;amp;

exec python3 /app/app.py&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This is everything you need to get CloudWatch running inside your MicroVMs!&lt;/p&gt; 
&lt;h2 id="execution-role-requirements"&gt;Execution role requirements&lt;/h2&gt; 
&lt;p&gt;To write the metrics to CloudWatch, ensure the MicroVM’s execution role has &lt;code&gt;cloudwatch:PutMetricData&lt;/code&gt; permissions.&lt;/p&gt; 
&lt;h2 id="verifying-it-works"&gt;Verifying it works&lt;/h2&gt; 
&lt;p&gt;To verify the metrics are being emitted, run the following command a few minutes after launching a MicroVM from your image:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws cloudwatch list-metrics \
    --namespace LambdaMicroVms/Application \
    --dimensions Name=ImageName,Value=mem-python \
    --region us-west-2&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;You should see exactly three metric series per image: &lt;code&gt;cpu_usage_active&lt;/code&gt;, &lt;code&gt;cpu_usage_idle&lt;/code&gt;, and &lt;code&gt;mem_used_percent&lt;/code&gt;.&lt;/p&gt; 
&lt;h2 id="viewing-the-metrics"&gt;Viewing the metrics&lt;/h2&gt; 
&lt;p&gt;To view the metrics in the CloudWatch console, click “All Metrics”, and select the custom namespace &lt;code&gt;LambdaMicroVms/Application&lt;/code&gt; (set in &lt;code&gt;cwagent.yaml&lt;/code&gt; namespace field).&lt;/p&gt; 
&lt;p&gt;Here is an example for how it looks inside the console:&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/03/ComputeBlog-2696-1.png" alt="CloudWatch console showing CPU and memory metrics for a Lambda MicroVM" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;In the graph above, the application consumes ~2% memory (left axis) and &amp;lt; 0.1% CPU usage (right axis) when idle. The application then consumes ~9% of memory at the 30 minute mark, holds it for around 5 minutes, then releases it back to the OS. As it releases memory, we see memory utilization decrease. In this example, the MicroVM size is larger than the application needs – less than 10% of memory was used, indicating a smaller MicroVM size may be more economic for this workload.&lt;/p&gt; 
&lt;p&gt;If your CPU and/or memory utilization is below the baseline size configured (see &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/microvms-images.html" target="_blank" rel="noopener"&gt;MicroVM sizing&lt;/a&gt;), consider choosing a lower baseline to reduce your compute bill.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;This post shows you how to configure and run the CloudWatch Agent inside your MicroVM image so you can collect CPU and memory metrics for MicroVMs launched from the image. This helps you monitor resource usage of your application as it is used, so you can right-size the MicroVM for your workload, debug service health, and check for scaling signals.&lt;/p&gt; 
&lt;p&gt;To get started, visit the &lt;a href="https://console.aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda console&lt;/a&gt;, or install the &lt;a href="https://github.com/aws/agent-toolkit-for-aws/tree/main/skills/specialized-skills/serverless-skills/aws-lambda-microvms" target="_blank" rel="noopener"&gt;AWS Lambda MicroVMs agent skill&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Designing for failure: Building resilient systems on AWS</title>
		<link>https://aws.amazon.com/blogs/compute/designing-for-failure-building-resilient-systems-on-aws/</link>
		
		<dc:creator><![CDATA[Dhvani Vora]]></dc:creator>
		<pubDate>Thu, 13 Aug 2026 20:03:28 +0000</pubDate>
				<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Intermediate (200)]]></category>
		<guid isPermaLink="false">9dd09542f13911eb84b529586d27a99155de321a</guid>

					<description>Learn how to prevent correlated hardware failures in distributed systems on Amazon EC2. This post walks through real incident response patterns, including Partition Placement Groups, composite alarms, automated recovery with Auto Scaling, and observability best practices.</description>
										<content:encoded>&lt;p&gt;In cloud computing, failure in distributed systems isn’t a matter of if, but when. Modern applications span servers, Availability Zones, and Regions. Each component represents a potential point of failure. Resilient applications engineer fault tolerance into their architecture, building systems that self-recover and maintain availability. This post is written for engineers and architects who run distributed data systems such as Apache Cassandra, Apache Kafka, or HDFS on Amazon Elastic Compute Cloud (Amazon EC2) and want to build resilience against hardware failure.&lt;/p&gt; 
&lt;p&gt;We were working with a customer during one such incident and wanted to share the example. The customer runs a web application that uses Cassandra as its data store, handling both read-heavy and write-heavy workloads at a scale of millions of queries per day.&lt;/p&gt; 
&lt;h2 id="the-2-am-wake-up-call-nobody-wants"&gt;The 2 AM wake-up call nobody wants&lt;/h2&gt; 
&lt;p&gt;Consider a platform that monitors millions of enterprise network devices across hospitals, universities, and airports worldwide. It detects problems before IT teams even notice them. For that platform, a 2 AM page is more than inconvenient. When your value proposition is catching failures before anyone else does, being caught off-guard by your own infrastructure failure is existential.&lt;/p&gt; 
&lt;p&gt;The engineering team was deep in quarterly planning when their monitoring dashboard lit up. Three Cassandra nodes had gone dark simultaneously. This was not a graceful shutdown or a rolling restart. It was a hard failure with no warning.&lt;/p&gt; 
&lt;p&gt;Their architecture is typical of high-scale telemetry platforms. Kafka-powered microservices ingest device telemetry, Apache Flink handles real-time anomaly detection, and Apache Airflow orchestrates batch analytics and firmware updates. All of these rely on Apache Cassandra as the distributed database backbone. The database stores billions of daily writes and handles millions of queries per day.&lt;/p&gt; 
&lt;h2 id="what-actually-happened"&gt;What actually happened&lt;/h2&gt; 
&lt;p&gt;Three i4i.4xlarge instances running Cassandra nodes failed simultaneously in the SFO region. Investigation revealed that all three instances were colocated on the same physical host. That host suffered a hardware failure, taking all three instances offline at once.&lt;/p&gt; 
&lt;p&gt;Engineers spent ninety minutes digging through system logs trying to determine the root cause. The root cause was architectural. The deployment lacked Partition Placement Groups, creating a single point of failure where logical replication was undermined by physical collocation.&lt;/p&gt; 
&lt;p&gt;The good news: Cassandra maintained service availability with no data loss thanks to its replication factor. The bad news: for over an hour, the system ran on a thin safety margin. One more node failure in the same replication group would have caused data unavailability for a subset of queries. That is real customer impact for a platform that promises always-on monitoring.&lt;/p&gt; 
&lt;p&gt;This is the insidious nature of correlated failures. Individual node failures are expected and designed for. That is the whole point of replication. But when your replicas share physical infrastructure, replication becomes a paper guarantee. You have three copies of the data, but they all live on the same machine.&lt;/p&gt; 
&lt;p&gt;Making matters worse, their monitoring tools completely missed the initial failure. System status checks correctly flagged the host-level problem. But without &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt; alarms configured to act on those checks, detection was entirely reactive. The team found out because other things started behaving oddly, not because an alarm told them three nodes were down.&lt;/p&gt; 
&lt;p&gt;Hardware fails. You can’t fix it with a patch or configuration change. The real questions are how fast you detect it, how well your system handles it, and whether failures are correlated.&lt;/p&gt; 
&lt;h2 id="how-the-team-responded-and-what-they-changed"&gt;How the team responded and what they changed&lt;/h2&gt; 
&lt;p&gt;The operations team manually replaced two failed instances with new ones on healthy hardware and restarted the third for log collection. Once replacement instances came online, new Cassandra nodes automatically rejoined their clusters and streamed data from surviving replicas. This process took several hours depending on data volume. Only after full synchronization did the clusters return to full redundancy.&lt;/p&gt; 
&lt;p&gt;The team recognized that this ninety-minute manual scramble wouldn’t scale. Similar problems had happened before, and each time they followed the same reactive pattern: page, investigate, manually replace, wait for streaming, breathe. Here’s what they implemented to break that cycle, and what you should implement too.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img title="Figure 1: The same failure handled two ways. Manual response took over 90 minutes plus hours of streaming; the automated path completes recovery in under 5 minutes." src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/13/ComputeBlog-2529-1.png" alt="Two-track incident timeline. The top track, labeled Before automation: about 90 plus minutes of manual response, shows five milestones: at 0 minutes three nodes fail simultaneously. At about 5 minutes cascading errors are noticed with no alarm. At 90 minutes the root cause is found in system logs. At 90-plus minutes instances are manually replaced. And after several hours data streaming completes and full redundancy is restored. The bottom track, labeled After automation: under 5 minutes to recovery, shows four milestones: at 0 seconds the system status check fails. At about 60 seconds a composite alarm fires. At about 2 minutes Auto Scaling replaces the node. And in under 5 minutes a lifecycle hook rejoins the node to the cluster." width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 1: The same failure handled two ways. Manual response took over 90 minutes plus hours of streaming. The automated path completes recovery in under 5 minutes.&lt;/p&gt;
&lt;/div&gt; 
&lt;h3 id="use-partition-placement-groups-to-isolate-failure-domains"&gt;1. Use Partition Placement Groups to isolate failure domains&lt;/h3&gt; 
&lt;p&gt;The three crashed servers shared a physical machine because no one told AWS otherwise. Without placement group constraints, instances are placed based on available capacity. That can mean multiple instances land on the same host. For stateless web servers, this rarely matters. For distributed databases whose entire resilience model depends on replicas being independent, it’s a silent architecture bug waiting to become a 2 AM incident.&lt;/p&gt; 
&lt;p&gt;Partition Placement Groups fix this by distributing instances across separate hardware racks. Each partition maps to a distinct set of physical infrastructure, with separate power and separate network switches. When one rack fails, it affects only the instances in that partition.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img title="Figure 2: Distributing Cassandra replicas across Partition Placement Group partitions so a single rack failure affects only one node." src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/13/ComputeBlog-2529-2.png" alt="Diagram comparing two Cassandra deployments. On the left, labeled Before, all three Cassandra nodes run on a single physical host, so a host failure takes down all three replicas. On the right, labeled After, the three nodes are distributed across three Partition Placement Group partitions on separate racks (Rack A, Rack B, Rack C). When Rack B fails, only Node 2 is lost and the cluster survives." width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 2: Distributing Cassandra replicas across Partition Placement Group partitions so a single rack failure affects only one node.&lt;/p&gt;
&lt;/div&gt; 
&lt;p&gt;You can create up to seven partitions per Availability Zone, with as many instances as needed in each. By mapping Cassandra replicas to separate partitions, a single hardware failure takes down one node instead of three. This applies to any distributed system that maintains replicas, such as Kafka, HDFS, or Cassandra.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; Align your Partition Placement Group partitions with your application’s replication topology. If Cassandra uses a replication factor of 3, place each replica in a different partition. This means the physical isolation boundary matches the logical replication boundary.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;CLI example:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws ec2 create-placement-group \
  --group-name cassandra-partitioned \
  --strategy partition \
  --partition-count 3

aws ec2 run-instances \
  --placement "GroupName=cassandra-partitioned,PartitionNumber=1" \
  --instance-type i4i.4xlarge \
  --image-id ami-xxxxxxxx&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Partition Placement Groups (up to 7 partitions per AZ, unlimited instances per partition) are designed for large distributed workloads. Spread Placement Groups (max 7 instances per AZ, each on a separate rack) suit small critical clusters. For a Cassandra deployment at scale, Partition is the right choice. Learn more in the &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html" target="_blank" rel="noopener"&gt;Amazon EC2 placement groups documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="monitor-system-status-checks-and-use-composite-alarms"&gt;2. Monitor system status checks and use composite alarms&lt;/h3&gt; 
&lt;p&gt;The Cassandra team’s monitoring blind spot came down to a distinction many teams overlook. AWS runs two health checks on every instance: instance status checks (your guest OS and software) and system status checks (the physical hardware underneath). When a system status check fails, the problem is below your control. This includes a host crash, a power failure, or network loss at the rack level. No amount of SSH-ing will help, because the box is unreachable.&lt;/p&gt; 
&lt;p&gt;The Cassandra team had no &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt; alarms configured on either check type. That meant the only signal was cascading application errors noticed by engineers who happened to be awake. Set these up on day one, before your first production deployment.&lt;/p&gt; 
&lt;p&gt;To avoid false alarms during normal reboots, where metrics may briefly go missing, combine system status checks with application-level health monitoring using composite alarms. When both fail together, you know there’s a real problem. See the &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Create_Composite_Alarm.html" target="_blank" rel="noopener"&gt;CloudWatch composite alarms documentation&lt;/a&gt; for setup details.&lt;/p&gt; 
&lt;h3 id="automate-instance-recovery-and-replacement"&gt;3. Automate instance recovery and replacement&lt;/h3&gt; 
&lt;p&gt;The Cassandra team’s ninety-minute recovery wasn’t slow because the engineers were incompetent. It was slow because humans were in the loop. Waking up, assessing, deciding, acting, and verifying: each step adds minutes that compound under pressure. Auto Scaling groups remove the human from the critical path.&lt;/p&gt; 
&lt;p&gt;Place your Cassandra nodes in an Auto Scaling group. Auto Scaling continuously runs health checks on every instance, and when it marks an instance unhealthy, it terminates it and launches a replacement on different physical hardware, automatically placed within your Partition Placement Group. Under normal conditions, an instance whose system status checks fail is replaced within a few minutes.&lt;/p&gt; 
&lt;p&gt;The gap to close is detection, not replacement. Rather than waiting for Auto Scaling to reach its own conclusion, have the composite alarm from the previous section explicitly tell Auto Scaling the instance is unhealthy by calling the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_SetInstanceHealth.html" target="_blank" rel="noopener"&gt;SetInstanceHealth&lt;/a&gt; API. As soon as your combined signal (system status check plus application-level check) confirms a real failure, mark the instance unhealthy and let Auto Scaling replace it immediately. This sidesteps any ambiguity in detection and starts recovery in seconds rather than minutes.&lt;/p&gt; 
&lt;p&gt;For stateless services, this is enough. For stateful systems like Cassandra, you need an additional step. Lifecycle hooks pause new instances before they join the cluster. A raw Amazon EC2 instance isn’t a functioning Cassandra node. It needs to join the ring, stream data from peers, and verify consistency before serving traffic. Read more in the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling lifecycle hooks documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;In this customer’s case, automating these steps cut recovery time from ninety minutes of manual intervention to under five minutes of automated recovery.&lt;/p&gt; 
&lt;p&gt;A note on stateful recovery: automated replacement only handles the infrastructure layer. For Cassandra specifically, the new node still needs to stream data from peers before it’s fully operational. The key improvement isn’t eliminating that streaming time. It’s eliminating the human response time before streaming even begins.&lt;/p&gt; 
&lt;h3 id="build-automated-incident-response-with-aws-systems-manager"&gt;4. Build automated incident response with AWS Systems Manager&lt;/h3&gt; 
&lt;p&gt;When servers fail, you face competing priorities. You need to replace them fast to restore capacity, and you need to preserve logs for root cause analysis. These goals conflict when done manually. The Cassandra team restarted one failed node solely to collect diagnostic data before replacing it, adding time to an already long recovery.&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/systems-manager/" target="_blank" rel="noopener"&gt;AWS Systems Manager&lt;/a&gt; runbooks automate this tradeoff away. Build a workflow that runs these steps in sequence:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;Isolate the failed instance by detaching it from the load balancer target group.&lt;/li&gt; 
 &lt;li&gt;Create an Amazon EBS snapshot and capture available logs to Amazon S3.&lt;/li&gt; 
 &lt;li&gt;Terminate the instance so that Auto Scaling can replace it.&lt;/li&gt; 
 &lt;li&gt;Notify the on-call channel with the instance ID, failure type, and Amazon S3 log location.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;A subtle but important detail: when the instance’s lifecycle is managed by an Auto Scaling group, let the group replace it. Terminating the instance directly only delays recovery, because the group first has to notice the instance is gone before it launches a replacement. Instead, call the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_TerminateInstanceInAutoScalingGroup.html" target="_blank" rel="noopener"&gt;TerminateInstanceInAutoScalingGroup&lt;/a&gt; API. This tells EC2 Auto Scaling to terminate the unhealthy instance and immediately launch a replacement in one coordinated action. Trigger this runbook automatically with &lt;a href="https://aws.amazon.com/eventbridge/" target="_blank" rel="noopener"&gt;Amazon EventBridge&lt;/a&gt; rules that match Amazon EC2 state-change events. The result is that forensic data is preserved, replacement happens in parallel, and the on-call engineer gets a notification after the system has already healed, rather than a page asking them to start fixing it.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img title="Figure 3: The automated recovery workflow, from hardware failure detection through node rejoin, orchestrated by Amazon EventBridge, Auto Scaling, and AWS Systems Manager." src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/13/ComputeBlog-2529-3.png" alt="Five-step automated recovery workflow shown left to right. Step 1: the Amazon EC2 system status check fails on the host. Step 2: an Amazon CloudWatch composite alarm triggers. Step 3: Auto Scaling terminates the unhealthy node and launches a replacement. Step 4: an AWS Systems Manager runbook takes a snapshot and sends logs to Amazon S3. Step 5: a lifecycle hook streams data, verifies, and rejoins the node to the cluster. The whole flow is triggered by Amazon EventBridge and reduces recovery from about 90 minutes of manual work to under 5 minutes." width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;br&gt;Figure 3: The automated recovery workflow, from hardware failure detection through node rejoin, orchestrated by Amazon EventBridge, Auto Scaling, and AWS Systems Manager.&lt;/p&gt;
&lt;/div&gt; 
&lt;h3 id="invest-in-observability-before-you-need-it"&gt;5. Invest in observability before you need it&lt;/h3&gt; 
&lt;p&gt;After resolving the Cassandra incident, the team asked a harder question: what else is silently failing? They ran a broader health assessment, and the answer was sobering. Unstable Redis connections were dropping under load. Amazon EBS volumes were running with elevated latency. Application Load Balancer health check intervals were misconfigured. Secondary databases were approaching connection pool exhaustion. Any of these could cause the next outage, and none of them had triggered a single alert.&lt;/p&gt; 
&lt;p&gt;This is the pattern. Teams invest in monitoring for the system that recently broke while the next failure quietly builds elsewhere. The better approach is treating observability as infrastructure. Deploy it everywhere from day one, not bolted on after the post-mortem.&lt;/p&gt; 
&lt;p&gt;Deploy the CloudWatch agent for system-level and application-level metrics. Use Amazon CloudWatch Synthetics canaries to continuously test critical user paths such as login, data ingestion, and dashboard rendering. Set up distributed tracing with AWS X-Ray to identify latency bottlenecks across your microservice mesh. The goal isn’t only knowing that services are running. It’s continuously confirming they’re working correctly from the customer’s perspective.&lt;/p&gt; 
&lt;p&gt;The Cassandra team built what they call their “resilience dashboard.” It’s a single view surfacing Partition Placement Group distribution, replica lag, system status check state, and Auto Scaling group health. When the next incident happens, they won’t be scrambling to figure out what’s broken. They’ll open one dashboard and know immediately whether their defenses are holding.&lt;/p&gt; 
&lt;h2 id="placement-groups-quick-reference"&gt;Placement groups: Quick reference&lt;/h2&gt; 
&lt;p&gt;The team’s outage involved Partition Placement Groups, but Amazon EC2 offers three placement group types. Choosing the wrong one is a common mistake, so here’s how they compare:&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Max instances&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Isolation level&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Partition&lt;/td&gt; 
   &lt;td&gt;Unlimited (up to 7 partitions per AZ)&lt;/td&gt; 
   &lt;td&gt;Separate racks per partition&lt;/td&gt; 
   &lt;td&gt;Large distributed databases (Cassandra, Kafka, HDFS)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Spread&lt;/td&gt; 
   &lt;td&gt;7 per AZ&lt;/td&gt; 
   &lt;td&gt;Each instance on a separate rack&lt;/td&gt; 
   &lt;td&gt;Small critical clusters needing maximum isolation&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Cluster&lt;/td&gt; 
   &lt;td&gt;Unlimited&lt;/td&gt; 
   &lt;td&gt;Same rack (co-located)&lt;/td&gt; 
   &lt;td&gt;HPC, ML training, low-latency workloads&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;If the Cassandra team had used Spread Placement Groups instead, they would have hit the 7-instance-per-AZ ceiling almost immediately at their scale. Partition Placement Groups gave them isolation and room to grow. For the highest-criticality deployments, combine placement groups with multiple Availability Zones. You get separate racks and separate data centers, protecting against both rack-level failures and zone-wide events like power grid outages.&lt;/p&gt; 
&lt;h2 id="the-bigger-picture-resilience-is-a-practice"&gt;The bigger picture: Resilience is a practice&lt;/h2&gt; 
&lt;p&gt;Building resilient systems isn’t a one-time project. It’s a practice that evolves with your architecture. Start by assessing your workloads with the &lt;a href="https://aws.amazon.com/well-architected-tool/" target="_blank" rel="noopener"&gt;AWS Well-Architected Tool&lt;/a&gt; to identify single points of failure you might not see day-to-day. Define Service Level Objectives, so your team agrees on what “good enough” looks like. Not every service needs 99.99% availability, but you need to know which ones do.&lt;/p&gt; 
&lt;p&gt;Then layer your defenses. Placement groups prevent correlated hardware failures, composite alarms detect problems within minutes, and automated recovery fixes common issues without waking anyone up.&lt;/p&gt; 
&lt;p&gt;Test regularly. Run disaster recovery drills quarterly. Don’t rely only on tabletop exercises. Run actual failovers in pre-production environments. Use &lt;a href="https://aws.amazon.com/fis/" target="_blank" rel="noopener"&gt;AWS Fault Injection Service&lt;/a&gt; to simulate hardware failures and zone outages in a controlled way. Hold blameless post-mortems after every incident to understand what broke, why it wasn’t caught earlier, and what you’ll change.&lt;/p&gt; 
&lt;p&gt;After this incident, the team deployed Partition Placement Groups, configured composite alarms, and automated their response process. The next time hardware fails, and it will, it won’t cause the same damage.&lt;/p&gt; 
&lt;p&gt;Consider adopting Chaos Engineering as a discipline. The principles of Chaos Engineering encourage teams to proactively inject failures into production-like environments to uncover weaknesses before they cause real outages. AWS Fault Injection Service makes it straightforward to run these experiments safely, with guardrails that automatically stop experiments if impact exceeds defined thresholds.&lt;/p&gt; 
&lt;p&gt;For related guidance, see the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/welcome.html" target="_blank" rel="noopener"&gt;AWS Well-Architected Framework Reliability Pillar&lt;/a&gt; and the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling User Guide&lt;/a&gt;. A sample Systems Manager runbook and AWS CloudFormation template for the automated recovery workflow described in this post is available in the &lt;a href="https://github.com/aws-samples" target="_blank" rel="noopener"&gt;AWS Samples GitHub repository&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;If you’ve implemented similar resilience patterns or have questions about placement groups and automated recovery, share your experience in the comments.&lt;/p&gt; 
&lt;h2 id="related-posts"&gt;Related posts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/building-for-resilience-how-amazon-ec2-spread-placement-groups-reduce-correlated-failures/" target="_blank" rel="noopener"&gt;Building for resilience: How Amazon EC2 Spread Placement Groups reduce correlated failures&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/mt/automating-amazon-ec2-instance-remediation-with-aws-systems-manager-and-amazon-cloudwatch/" target="_blank" rel="noopener"&gt;Automating Amazon EC2 instance remediation with AWS Systems Manager and Amazon CloudWatch&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/best-practices-for-handling-ec2-spot-instance-interruptions/" target="_blank" rel="noopener"&gt;Best practices for handling Amazon EC2 Spot Instance interruptions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/architecture/category/resilience/" target="_blank" rel="noopener"&gt;AWS Architecture Blog: Resilience&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/aws/introducing-the-next-generation-of-aws-resilience-hub-for-generative-ai-based-sre-resilience-journey/" target="_blank" rel="noopener"&gt;Introducing the next generation of AWS Resilience Hub for generative AI-based SRE resilience journey&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/mt/tag/aws-resilience-hub/" target="_blank" rel="noopener"&gt;AWS Management &amp;amp; Tools Blog: AWS Resilience Hub&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Challenge&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Multiple instances on same physical host&lt;/td&gt; 
   &lt;td&gt;Partition Placement Groups&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;No health notification for sudden failures&lt;/td&gt; 
   &lt;td&gt;Amazon CloudWatch alarms on system status checks&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Missing metrics during host reboots&lt;/td&gt; 
   &lt;td&gt;Composite alarms with application-level health checks&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Manual, slow incident response&lt;/td&gt; 
   &lt;td&gt;Automated recovery with Auto Scaling and lifecycle hooks&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Delayed root cause identification&lt;/td&gt; 
   &lt;td&gt;Systematic triage starting at the infrastructure layer&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Reduced redundancy after failure&lt;/td&gt; 
   &lt;td&gt;Auto Scaling groups for automatic replacement&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Recurring confidence erosion&lt;/td&gt; 
   &lt;td&gt;Proactive architectural reviews and observability investment&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Amazon EC2 provides tools like placement groups, managed services with built-in high availability, and automation frameworks like AWS Systems Manager. Select the right ones for your workload and test them relentlessly. Failure is inevitable. Your readiness determines the outcome.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Burst to Region: Overflow AWS Outposts workloads to Amazon EC2</title>
		<link>https://aws.amazon.com/blogs/compute/burst-to-region-overflow-aws-outposts-workloads-to-amazon-ec2/</link>
		
		<dc:creator><![CDATA[Diya]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 17:06:54 +0000</pubDate>
				<category><![CDATA[Advanced (300)]]></category>
		<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[AWS Outposts]]></category>
		<category><![CDATA[Technical How-to]]></category>
		<guid isPermaLink="false">2ee8a18d0da7981fe97f6b8607620b746a5a9490</guid>

					<description>AWS Outposts brings AWS infrastructure into your data center with low latency and data locality. But an Outposts rack has fixed compute. Learn how to build a Burst to Region pattern that overflows workloads to Amazon EC2 in the parent Region when local capacity is exhausted.</description>
										<content:encoded>&lt;p&gt;&lt;a href="https://aws.amazon.com/outposts/" target="_blank" rel="noopener"&gt;AWS Outposts&lt;/a&gt; brings AWS infrastructure into your data center, giving on-premises workloads the low latency and data locality they need. But unlike the AWS Region, an Outposts rack has a fixed amount of compute. When your workload needs more instances than the rack can provide, you have two options: drop requests, or overflow them somewhere with room to grow. This post shows you how to automate the second option. You build a Burst to Region pattern that detects capacity constraints on your Outpost, launches &lt;a href="https://aws.amazon.com/ec2/" target="_blank" rel="noopener"&gt;Amazon Elastic Compute Cloud (Amazon EC2)&lt;/a&gt; instances in the parent Region, gradually shifts traffic to them, and returns traffic to local instances once capacity recovers.&lt;/p&gt; 
&lt;p&gt;To implement this pattern you configure &lt;a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noopener"&gt;Amazon CloudWatch&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sns/" target="_blank" rel="noopener"&gt;Amazon Simple Notification Service&lt;/a&gt; (Amazon SNS), &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt;, &lt;a href="https://aws.amazon.com/ec2/autoscaling/" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling&lt;/a&gt;, &lt;a href="https://aws.amazon.com/elasticloadbalancing/" target="_blank" rel="noopener"&gt;Elastic Load Balancing&lt;/a&gt; (&lt;a href="https://aws.amazon.com/elasticloadbalancing/" target="_blank" rel="noopener"&gt;Application Load Balancer&lt;/a&gt;), and &lt;a href="https://aws.amazon.com/eventbridge/" target="_blank" rel="noopener"&gt;Amazon EventBridge&lt;/a&gt;. You trade a moderate latency increase for continued availability during capacity events.&lt;/p&gt; 
&lt;h2 id="when-to-use-this-pattern"&gt;When to use this pattern&lt;/h2&gt; 
&lt;p&gt;This pattern assumes your Outposts workload scales out through Amazon EC2 Auto Scaling. Burst to Region reacts to instance-capacity exhaustion on the rack. It engages when your workload tries to launch more instances than the available Outpost capacity supports. If your fleet is fixed size and degrades under load without scaling out, the capacity alarm never fires and overflow never triggers. For those workloads, monitor per-instance saturation (CPU, latency) separately.&lt;/p&gt; 
&lt;p&gt;Good candidates prefer local capacity but can tolerate Region latency under pressure. If your application runs on Outposts for proximity yet degrades gracefully when some traffic takes the longer path to the Region, it fits this pattern. Examples include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Internal enterprise applications.&lt;/li&gt; 
 &lt;li&gt;Stateless web frontends and API layers.&lt;/li&gt; 
 &lt;li&gt;Pre-processing tiers where single-digit to tens-of-milliseconds additional round-trip latency during peaks is acceptable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Poor candidates cannot absorb any added latency or must stay on the Outpost. Avoid this pattern for:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Applications with sub-millisecond requirements.&lt;/li&gt; 
 &lt;li&gt;Workloads with strict data residency or sovereignty mandates that prevent traffic from leaving the on-premises environment.&lt;/li&gt; 
 &lt;li&gt;Real-time control systems with hard timing constraints.&lt;/li&gt; 
 &lt;li&gt;Applications tightly coupled to on-premises data stores with no Region replica.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The core tradeoff is explicit. During capacity events, you accept moderately higher latency to maintain availability. If your workload cannot tolerate any latency increase, keep it pinned to Outposts and reserve capacity through other means, such as &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/capacity-reservations-outposts.html" target="_blank" rel="noopener"&gt;Capacity Reservations&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="solution-overview"&gt;Solution overview&lt;/h2&gt; 
&lt;p&gt;Burst to Region works in three moves: detect capacity pressure on the Outpost, launch overflow compute in the parent Region, and shift traffic gradually until local capacity recovers. Six AWS services coordinate to make this automatic. The following diagram shows the reference architecture for the Burst to Region pattern, illustrating how the six AWS services interact during capacity detection, overflow scaling, traffic distribution, and recovery.&lt;/p&gt; 
&lt;div style="width: 810px" class="wp-caption alignnone"&gt;
 &lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/08/12/compute-2652-fig2.png" alt="Reference architecture for Burst to Region on AWS Outposts showing capacity detection, overflow scaling, traffic distribution, and recovery" width="800"&gt;
 &lt;p class="wp-caption-text"&gt;&lt;/p&gt; 
 &lt;p&gt; Figure 1: Reference architecture for Burst to Region on AWS Outposts&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt; The pattern uses six AWS services working together:
&lt;p&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon CloudWatch&lt;/strong&gt; monitors Outposts capacity utilization and raises alarms.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon SNS&lt;/strong&gt; provides event fan-out from alarm to orchestrator.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;AWS Lambda&lt;/strong&gt; orchestrates the burst logic (scale-out, weight adjustment, recovery)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon EC2 Auto Scaling&lt;/strong&gt; manages the overflow fleet lifecycle.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Application Load Balancer&lt;/strong&gt; distributes traffic across both locations using weighted target groups.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Amazon EventBridge&lt;/strong&gt; handles periodic recovery evaluation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You must configure five phases for this pattern:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;&lt;strong&gt;Monitor.&lt;/strong&gt; CloudWatch tracks Outposts capacity utilization metrics in the &lt;code&gt;AWS/Outposts&lt;/code&gt; namespace.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Detect.&lt;/strong&gt; A CloudWatch alarm fires when utilization exceeds a threshold (for example, 80%).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Overflow.&lt;/strong&gt; The alarm triggers a Lambda function through Amazon SNS. Lambda scales out a Region-based Amazon EC2 Auto Scaling group and adjusts ALB target group weights.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Distribute.&lt;/strong&gt; The ALB splits traffic between Outposts instances and Region instances using weighted forwarding.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Recover.&lt;/strong&gt; An Amazon EventBridge scheduled rule periodically evaluates capacity. When Outposts recovers, Lambda scales down the overflow fleet and returns all traffic to local instances.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2 id="design-decisions"&gt;Design decisions&lt;/h2&gt; 
&lt;p&gt;We chose Application Load Balancer with weighted forwarding over Amazon Route 53 weighted routing for traffic distribution. ALB provides health-aware routing to only healthy overflow instances and target group stickiness for session consistency. Weight changes take effect for new connections after calling the &lt;a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_ModifyRule.html" target="_blank" rel="noopener"&gt;ModifyRule&lt;/a&gt; API. DNS-based shifting through Route 53 provides too coarse control for rapid weight adjustments, and TTL propagation delays make recovery slower.&lt;/p&gt; 
&lt;p&gt;The burst orchestrator runs as a Lambda function rather than a long-running service. It executes only during state transitions, so there is no steady-state compute cost. Lambda integrates natively with Amazon SNS and Amazon EventBridge for event-driven invocation without additional infrastructure.&lt;/p&gt; 
&lt;p&gt;You implement recovery with an Amazon EventBridge scheduled rule (every 5 minutes) rather than relying solely on the CloudWatch alarm to return to OK state. The alarm confirms capacity is available, but does not confirm that overflow instances have drained active connections. The scheduled rule provides gradual, safe scale-down.&lt;/p&gt; 
&lt;h2 id="implementation"&gt;Implementation&lt;/h2&gt; 
&lt;p&gt;This section walks through the key components of the Burst to Region pattern. For the complete deployable AWS SAM template, see the &lt;a href="https://github.com/aws-samples/sample-burst-to-region-for-aws-outposts" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt; 
&lt;p&gt;To deploy this pattern, you need:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;An AWS account with a configured AWS Outposts rack.&lt;/li&gt; 
 &lt;li&gt;An Amazon Virtual Private Cloud (Amazon VPC) with subnets associated with your Outposts and subnets in the parent AWS Region.&lt;/li&gt; 
 &lt;li&gt;IAM permissions to create CloudWatch alarms, Lambda functions, Auto Scaling groups, and ALB resources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM)&lt;/a&gt; CLI installed and configured.&lt;/li&gt; 
 &lt;li&gt;Existing Amazon EC2 Auto Scaling group running on your Outpost (these become your baseline fleet)&lt;/li&gt; 
 &lt;li&gt;A custom domain name with a DNS record (Route 53 alias or CNAME) pointing to your Application Load Balancer, and an &lt;a href="https://aws.amazon.com/certificate-manager/" target="_blank" rel="noopener"&gt;AWS Certificate Manager (ACM)&lt;/a&gt; certificate for that domain to enable HTTPS.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="capacity-monitoring-and-alarm"&gt;Capacity monitoring and alarm&lt;/h3&gt; 
&lt;p&gt;The CloudWatch alarm monitors instance utilization on the Outpost and triggers the burst workflow when capacity is constrained.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;InstanceTypeCapacityUtilization&lt;/code&gt; metric reports the percentage of a given instance type’s capacity in use. Note that this metric includes capacity consumed by managed services such as Amazon Relational Database Service (Amazon RDS) or Application Load Balancer running on the Outpost — not only your application’s EC2 instances. Factor this into your threshold planning.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;OutpostsCapacityAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: outposts-capacity-high
    Namespace: AWS/Outposts
    MetricName: InstanceTypeCapacityUtilization
    Dimensions:
      - Name: OutpostId
        Value: !Ref OutpostId
      - Name: InstanceType
        Value: !Ref OutpostInstanceType
    Statistic: Average
    Period: 300
    EvaluationPeriods: 2
    Threshold: !Ref CapacityThreshold
    ComparisonOperator: GreaterThanOrEqualToThreshold
    AlarmActions:
      - !Ref BurstSNSTopic
    TreatMissingData: notBreaching&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Why these values matter:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Period: 300 and EvaluationPeriods: 2&lt;/strong&gt; require 10 minutes of sustained high utilization before triggering. This avoids false alarms from transient spikes.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Threshold: 80&lt;/strong&gt; (recommended starting point) leaves a 20% buffer. A threshold set too high (95%) risks launch failures before the overflow fleet is ready. A threshold set too low (50%) causes unnecessary bursts.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;TreatMissingData: notBreaching&lt;/strong&gt; prevents false alarms when data points are missing. Since this alarm is scoped to a single instance type, treating missing data as breaching could trigger unnecessary bursts when the instance type is simply not in use.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Separate scale-out from scale-in:&lt;/strong&gt; This alarm triggers burst scale-out at 80%. Recovery is handled separately by the Amazon EventBridge scheduled rule, which uses a lower threshold (for example, 60%) before scaling in. This hysteresis gap prevents flapping where scaling down immediately pushes utilization back above the alarm threshold.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="burst-orchestrator-lambda"&gt;Burst orchestrator (Lambda)&lt;/h3&gt; 
&lt;p&gt;The Lambda function handles two event paths: alarm-triggered scale-out and scheduled recovery evaluation. The following pseudocode shows the orchestration flow:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-python"&gt;def handler(event, context):
    # Route based on event source
    if is_scheduled_recovery(event):
        return handle_recovery_check()

    alarm_state = parse_sns_alarm_state(event)

    if alarm_state == 'ALARM':
        # Scale out the overflow Auto Scaling group
        scale_out_overflow(desired=OVERFLOW_CAPACITY)
        # Don't shift traffic yet --- wait for healthy instances
        publish_burst_metric(active=True)


def handle_recovery_check():
    """Called every 5 minutes by EventBridge."""
    # Check if burst is active
    if not is_burst_active():
        return

    # If overflow instances are healthy and registered, shift traffic
    if overflow_targets_healthy():
        current_weights = get_current_alb_weights()
        if current_weights['region'] == 0:
            # First shift --- instances are now warm
            set_alb_weights(outposts=90, region=10)
        elif needs_more_overflow():
            step_up_region_weight()

    # If Outposts capacity has recovered, begin scale-down
    if outposts_capacity_recovered():
        step_down_region_weight()
        if get_current_alb_weights()['region'] == 0:
            # All traffic back to Outposts, drain and terminate overflow
            wait_for_connection_draining()
            scale_down_overflow(desired=0)
            publish_burst_metric(active=False)&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;The key actions the function performs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;scale_out_overflow&lt;/strong&gt; — Sets the overflow Auto Scaling group desired capacity from 0 to your configured burst size.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;set_alb_weights&lt;/strong&gt; — Calls the &lt;a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_ModifyRule.html" target="_blank" rel="noopener"&gt;ModifyListener&lt;/a&gt; API to adjust weighted forwarding between the Outposts and Region target groups.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;publish_burst_metric&lt;/strong&gt; — Writes a custom CloudWatch metric (BurstActive) for dashboard visibility.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;handle_recovery_check&lt;/strong&gt; — Called every 5 minutes by Amazon EventBridge. Confirms Outposts capacity has recovered, steps weights back gradually, waits for connection draining, then scales down the overflow fleet.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Important: The orchestrator does not shift ALB weights immediately upon scale-out. It waits for the next Amazon EventBridge invocation (up to 5 minutes) to confirm that overflow instances have passed health checks and are registered as healthy in the target group. This helps prevent routing traffic to instances that have not finished launching.&lt;/p&gt; 
&lt;p&gt;For the production-ready implementation with error handling, gradual weight stepping, and connection draining verification, see the &lt;a href="https://github.com/aws-samples/sample-burst-to-region-for-aws-outposts" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="overflow-auto-scaling-group"&gt;Overflow Auto Scaling group&lt;/h3&gt; 
&lt;p&gt;The overflow fleet starts at zero and scales only when the Lambda function sets desired capacity during a burst event:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;OverflowASG:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    AutoScalingGroupName: burst-overflow-fleet
    LaunchTemplate:
      LaunchTemplateId: !Ref OverflowLaunchTemplate
      Version: !GetAtt OverflowLaunchTemplate.LatestVersionNumber
    MinSize: 0
    MaxSize: !Ref MaxOverflowCapacity
    DesiredCapacity: 0
    VPCZoneIdentifier:
      - !Ref RegionSubnet1
      - !Ref RegionSubnet2
    TargetGroupARNs:
      - !Ref RegionTargetGroup
    HealthCheckType: ELB
    HealthCheckGracePeriod: 120
    MetricsCollection:
      - Granularity: 1Minute&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;The overflow fleet starts at zero capacity and incurs no cost at rest. During a burst event, the Lambda function calls the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_SetDesiredCapacity.html" target="_blank" rel="noopener"&gt;SetDesiredCapacity&lt;/a&gt; API to launch overflow instances. During recovery, it sets desired capacity back to zero.&lt;/p&gt; 
&lt;p&gt;The launch template mirrors your Outposts instance type to maintain consistent performance characteristics across both locations.&lt;/p&gt; 
&lt;h3 id="alb-weighted-forwarding"&gt;ALB weighted forwarding&lt;/h3&gt; 
&lt;p&gt;The ALB listener uses weighted forwarding across two target groups. In steady state, all traffic goes to Outposts (weight 100/0). During burst, the Lambda function adjusts these weights dynamically using the ModifyListener API. Clients reach the ALB through a DNS record — either a Route 53 alias or a CNAME pointing to the ALB’s DNS name.&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;ALBListener:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    LoadBalancerArn: !Ref ApplicationLoadBalancer
    Port: 443
    Protocol: HTTPS
    SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06
    Certificates:
      - CertificateArn: !Ref CertificateArn
    DefaultAction:
      Type: forward
      ForwardConfig:
        TargetGroups:
          - TargetGroupArn: !Ref OutpostsTargetGroup
            Weight: 100
          - TargetGroupArn: !Ref RegionTargetGroup
            Weight: 0
        TargetGroupStickinessConfig:
          Enabled: true
          DurationSeconds: 300

RegionTargetGroup:
  Type: AWS::ElasticLoadBalancingV2::TargetGroup
  Properties:
    Name: burst-region-targets
    Protocol: HTTP
    Port: 80
    VpcId: !Ref VpcId
    HealthCheckEnabled: true
    HealthCheckIntervalSeconds: 30
    HealthCheckPath: /health
    HealthyThresholdCount: 2
    UnhealthyThresholdCount: 3
    TargetGroupAttributes:
      - Key: deregistration_delay.timeout_seconds
        Value: "300"
      - Key: slow_start.duration_seconds
        Value: "120"&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Note on stickiness: Target group stickiness keeps a client pinned to whichever target group served its first request for &lt;code&gt;DurationSeconds&lt;/code&gt;. We set this to 300 seconds (5 minutes) to match the Amazon EventBridge evaluation interval. This balances session consistency for stateful workloads against the need for weight changes to take effect within a reasonable window. For purely stateless workloads, you can disable stickiness entirely to allow immediate weight convergence. For workloads requiring longer session affinity, increase the duration but understand that weight transitions will converge more slowly — existing sticky sessions continue going to the original target group until they expire.&lt;/p&gt; 
&lt;h3 id="traffic-weight-progression"&gt;Traffic weight progression&lt;/h3&gt; 
&lt;p&gt;Use stepped transitions rather than abrupt weight changes. The following table shows the recommended progression:&lt;/p&gt; 
&lt;table border="1px" cellpadding="10px" width="100%"&gt; 
 &lt;tbody&gt;
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Outposts weight&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Region weight&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Condition to advance&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Normal&lt;/td&gt; 
   &lt;td&gt;100&lt;/td&gt; 
   &lt;td&gt;0&lt;/td&gt; 
   &lt;td&gt;Steady state&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Burst step 1&lt;/td&gt; 
   &lt;td&gt;90&lt;/td&gt; 
   &lt;td&gt;10&lt;/td&gt; 
   &lt;td&gt;Region target group has at least 1 healthy host&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Burst step 2&lt;/td&gt; 
   &lt;td&gt;70&lt;/td&gt; 
   &lt;td&gt;30&lt;/td&gt; 
   &lt;td&gt;Region target group healthy for 2 consecutive checks&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Burst step 3&lt;/td&gt; 
   &lt;td&gt;50&lt;/td&gt; 
   &lt;td&gt;50&lt;/td&gt; 
   &lt;td&gt;Only if Outposts capacity exceeds 95% used&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Recovery step 1&lt;/td&gt; 
   &lt;td&gt;80&lt;/td&gt; 
   &lt;td&gt;20&lt;/td&gt; 
   &lt;td&gt;Outposts capacity below 70%&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Recovery step 2&lt;/td&gt; 
   &lt;td&gt;100&lt;/td&gt; 
   &lt;td&gt;0&lt;/td&gt; 
   &lt;td&gt;Outposts capacity below 60% for 2 checks&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt;
&lt;/table&gt; 
&lt;p&gt;Avoid jumping directly from 0% to 50% Region traffic. Cold overflow instances need time to warm caches and stabilize before absorbing significant load.&lt;/p&gt; 
&lt;h2 id="best-practices"&gt;Best practices&lt;/h2&gt; 
&lt;p&gt;Apply these best practices to get the most from this pattern while avoiding common pitfalls.&lt;/p&gt; 
&lt;h3 id="traffic-tiering"&gt;Traffic tiering&lt;/h3&gt; 
&lt;p&gt;Classify your workloads into two tiers at the ALB listener level. Latency-critical paths use routing rules with the Outposts target group only. These never overflow regardless of capacity state. Overflow-eligible paths use the weighted forwarding rule. This separation helps make sure that your most latency-sensitive flows are not impacted by the burst mechanism.&lt;/p&gt; 
&lt;h3 id="managing-data-gravity"&gt;Managing data gravity&lt;/h3&gt; 
&lt;p&gt;For stateless workloads, Burst to Region requires no special data handling. For workloads with session state or shared data:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Store session state in &lt;a href="https://aws.amazon.com/elasticache/" target="_blank" rel="noopener"&gt;Amazon ElastiCache&lt;/a&gt; or &lt;a href="https://aws.amazon.com/dynamodb/" target="_blank" rel="noopener"&gt;Amazon DynamoDB&lt;/a&gt; rather than local instance memory. Both Outposts and Region instances access the same session store.&lt;/li&gt; 
 &lt;li&gt;If your application reads from a local database on Outposts, overflow instances need a Region-accessible replica. Consider &lt;a href="https://aws.amazon.com/rds/" target="_blank" rel="noopener"&gt;Amazon Relational Database Service (Amazon RDS)&lt;/a&gt; read replicas or DynamoDB global tables.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Anti-pattern:&lt;/strong&gt; Do not burst workloads that write to Outposts-local storage and expect synchronous consistency. The latency and complexity of cross-location writes defeats the purpose of the pattern.&lt;/p&gt; 
&lt;h3 id="cost-optimization"&gt;Cost optimization&lt;/h3&gt; 
&lt;p&gt;The overflow fleet consumes On-Demand pricing by default since it starts at zero and scales only during peaks.&lt;/p&gt; 
&lt;table border="1px" cellpadding="10px" width="100%"&gt; 
 &lt;tbody&gt;
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Burst profile&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Recommended pricing&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Rationale&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Unpredictable spikes (minutes)&lt;/td&gt; 
   &lt;td&gt;On-Demand&lt;/td&gt; 
   &lt;td&gt;Maximum flexibility, no commitment waste&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Predictable daily peaks (hours)&lt;/td&gt; 
   &lt;td&gt;Savings Plans (Compute)&lt;/td&gt; 
   &lt;td&gt;Covers overflow hours at discount&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Frequent, long bursts&lt;/td&gt; 
   &lt;td&gt;Reserved capacity plus On-Demand&lt;/td&gt; 
   &lt;td&gt;Baseline discount plus burst flexibility&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt;
&lt;/table&gt; 
&lt;p&gt;Monitor your &lt;code&gt;BurstActive&lt;/code&gt; custom metric over time. If overflow is active more than 30% of the time, you likely need additional Outposts capacity rather than relying on Region overflow.&lt;/p&gt; 
&lt;h3 id="security-consistency"&gt;Security consistency&lt;/h3&gt; 
&lt;p&gt;Maintain identical security posture across both environments:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use the same security group rules for Outposts and Region instances.&lt;/li&gt; 
 &lt;li&gt;Deploy with &lt;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener"&gt;AWS CloudFormation&lt;/a&gt; StackSets to support consistency.&lt;/li&gt; 
 &lt;li&gt;Share the same IAM instance profile. The overflow launch template references the same role as your Outposts instances.&lt;/li&gt; 
 &lt;li&gt;Apply the same &lt;a href="https://aws.amazon.com/systems-manager/" target="_blank" rel="noopener"&gt;AWS Systems Manager&lt;/a&gt; patch baselines and compliance rules to both fleets.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="observability"&gt;Observability&lt;/h3&gt; 
&lt;p&gt;Build a CloudWatch dashboard that provides visibility into burst state and performance. The SAM template in the repository deploys a pre-configured dashboard tracking:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Burst status:&lt;/strong&gt; Custom &lt;code&gt;BurstActive&lt;/code&gt; metric (1 = active, 0 = normal)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Capacity headroom:&lt;/strong&gt; &lt;code&gt;UsedInstanceType_Count&lt;/code&gt; compared to &lt;code&gt;AvailableInstanceType_Count&lt;/code&gt;. Note that &lt;code&gt;UsedInstanceType_Count&lt;/code&gt; includes instances consumed by managed services (Amazon RDS, ALB), so your available application capacity may be lower than the raw availability count suggests.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Overflow fleet size:&lt;/strong&gt; Auto Scaling group &lt;code&gt;GroupInServiceInstances&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Latency comparison:&lt;/strong&gt; &lt;code&gt;TargetResponseTime&lt;/code&gt; per target group (Outposts compared to Region)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Traffic distribution:&lt;/strong&gt; &lt;code&gt;RequestCount&lt;/code&gt; per target group.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Set a CloudWatch alarm on Region target group &lt;code&gt;TargetResponseTime&lt;/code&gt; exceeding your acceptable threshold. This provides early warning if overflow latency degrades beyond your tolerance.&lt;/p&gt; 
&lt;h3 id="service-link-considerations"&gt;Service link considerations&lt;/h3&gt; 
&lt;p&gt;Because the ALB resides in the Region, all traffic to Outposts targets traverses the service link. Keep the following in mind:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Bandwidth planning:&lt;/strong&gt; Steady-state traffic to Outposts targets flows over the service link. Verify that your connection meets the &lt;a href="https://docs.aws.amazon.com/outposts/latest/userguide/service-links.html" target="_blank" rel="noopener"&gt;minimum 500 Mbps per compute rack&lt;/a&gt; recommended by AWS, with sufficient headroom for both application traffic and Outposts control plane communication. Monitor service link VIF throughput using &lt;code&gt;IfTrafficIn&lt;/code&gt; and &lt;code&gt;IfTrafficOut&lt;/code&gt; metrics (on service link VIFs) to detect saturation before it impacts performance.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Latency impact:&lt;/strong&gt; The service link adds latency compared to a locally deployed load balancer. The exact impact depends on your service link connection type and distance to the parent Region (AWS specifies a maximum of 175 ms round-trip for service link). For internet-facing workloads, this is typically negligible relative to the client-to-Region round trip. For workloads serving on-premises users through the Local Gateway, consider Route 53 weighted routing between an ALB on Outposts and a separate ALB in the Region instead.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Connection draining:&lt;/strong&gt; When scaling down the overflow fleet, allow sufficient time for in-flight requests to complete. The deregistration delay configured on the target group (default 300 seconds) and the Auto Scaling scale-in cool-down period work together to help provide graceful termination and minimize the risk of dropping active connections.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Failure modes:&lt;/strong&gt; If the service link goes down, the ALB cannot reach Outposts targets. Health checks fail, and all traffic automatically shifts to Region targets. This provides an unintentional but useful failover behavior. However, note that the overflow fleet is sized for burst capacity, not for sustaining 100% of production traffic. Monitor the &lt;code&gt;ConnectedStatus&lt;/code&gt; metric (under the AWS/Outposts namespace, dimension &lt;code&gt;OutpostId&lt;/code&gt;) and alert on degradation. If you need full failover capability, architect a separate disaster recovery solution with appropriately sized Region capacity.&lt;/p&gt; 
&lt;h2 id="limitations"&gt;Limitations&lt;/h2&gt; 
&lt;p&gt;Be aware of these constraints when implementing this pattern:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;ALB requirement:&lt;/strong&gt; The pattern requires an Application Load Balancer in the Region. Workloads that rely on direct IP access through the Local Gateway (without an ALB) cannot use this pattern without an architecture change.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Stateful workloads:&lt;/strong&gt; Applications with local disk state or in-memory sessions require external session stores (ElastiCache, DynamoDB) before they can burst. Without this, overflow instances serve requests without session context.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Database coupling:&lt;/strong&gt; If your application writes to a database running exclusively on the Outpost, overflow instances in the Region cannot reach it without a cross-location replica or proxy. Read-heavy workloads with a Region read replica are ideal candidates.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Service link as single path:&lt;/strong&gt; All ALB-to-Outpost traffic shares the service link with AWS control plane operations. Under extreme load, bandwidth contention can degrade both application traffic and management operations.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;ALB on Outposts:&lt;/strong&gt; As of this writing, ALB on Outposts does not support weighted target groups spanning both locations. The ALB must reside in the Region for this pattern to work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="testing-the-pattern"&gt;Testing the pattern&lt;/h2&gt; 
&lt;p&gt;Validate the burst mechanism before relying on it in production:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Simulate capacity pressure:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws cloudwatch set-alarm-state \
  --alarm-name outposts-capacity-high \
  --state-value ALARM \
  --state-reason "Testing burst mechanism"&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Verify overflow fleet launched:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names burst-overflow-fleet \
  --query "AutoScalingGroups[0].DesiredCapacity"&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Verify ALB weights shifted (after recovery check runs):&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws elbv2 describe-listeners \
  --listener-arns &amp;lt;your-listener-arn&amp;gt; \
  --query "Listeners[0].DefaultActions[0].ForwardConfig.TargetGroups[*].[TargetGroupArn,Weight]"&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Trigger recovery:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws cloudwatch set-alarm-state \
  --alarm-name outposts-capacity-high \
  --state-value OK \
  --state-reason "Testing recovery"&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Confirm overflow fleet scales back to zero and all traffic returns to Outposts targets. Recovery is gradual — the Amazon EventBridge rule evaluates every 5 minutes and steps weights back before scaling down, so full recovery may take 10–15 minutes depending on your weight progression configuration.&lt;/p&gt; 
&lt;h2 id="clean-up"&gt;Clean up&lt;/h2&gt; 
&lt;p&gt;To avoid ongoing charges, verify that the overflow Auto Scaling group has scaled to zero, then delete the stack:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;sam delete --stack-name burst-to-region-stack&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This removes all resources created by the template, including the Lambda function, CloudWatch alarm, SNS topic, Amazon EventBridge rule, and the overflow Auto Scaling group.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;This Burst to Region pattern extends AWS Outposts capacity into the parent Region during peak demand. You trade a moderate latency increase for continued availability when local capacity is exhausted.&lt;/p&gt; 
&lt;p&gt;The pattern works best when you clearly classify which workloads can overflow, implement gradual traffic transitions, and maintain security and observability parity across both environments.&lt;/p&gt; 
&lt;p&gt;For the complete deployable AWS SAM template including the Lambda orchestrator, CloudWatch dashboard, and all IAM roles, see the &lt;a href="https://github.com/aws-samples/sample-burst-to-region-for-aws-outposts" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;. To learn more about capacity planning for Outposts, see &lt;a href="https://aws.amazon.com/blogs/compute/managing-your-aws-outposts-capacity-using-amazon-cloudwatch-and-aws-lambda/" target="_blank" rel="noopener"&gt;Managing your AWS Outposts capacity using Amazon CloudWatch and AWS Lambda&lt;/a&gt; and &lt;a href="https://aws.amazon.com/blogs/compute/aws-outposts-monitoring-and-reporting-a-comprehensive-amazon-eventbridge-solution/" target="_blank" rel="noopener"&gt;AWS Outposts monitoring and reporting: A comprehensive Amazon EventBridge solution&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;For more information, see the &lt;a href="https://docs.aws.amazon.com/outposts/latest/userguide/" target="_blank" rel="noopener"&gt;AWS Outposts User Guide&lt;/a&gt; and the &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/" target="_blank" rel="noopener"&gt;Amazon EC2 Auto Scaling User Guide&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Low-latency, high-throughput SQS event processing with AWS Lambda provisioned mode</title>
		<link>https://aws.amazon.com/blogs/compute/low-latency-high-throughput-sqs-event-processing-with-aws-lambda-provisioned-mode/</link>
		
		<dc:creator><![CDATA[Ben Freiberg]]></dc:creator>
		<pubDate>Mon, 10 Aug 2026 13:42:03 +0000</pubDate>
				<category><![CDATA[Amazon Simple Queue Service (SQS)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Amazon SQS]]></category>
		<guid isPermaLink="false">7327f2cdb176151c7853cb079977c34db090d077</guid>

					<description>Customers building event-driven applications on AWS rely on Amazon Simple Queue Service (Amazon SQS) and AWS Lambda event source mappings (ESMs) to process millions of events every day. The fully managed polling infrastructure of ESMs eliminates the need to write and maintain custom code. You can focus on business logic while Lambda handles scaling, batching, […]</description>
										<content:encoded>&lt;p&gt;Customers building event-driven applications on AWS rely on &lt;a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener"&gt;Amazon Simple Queue Service&lt;/a&gt; (Amazon SQS) and &lt;a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html" target="_blank" rel="noopener"&gt;event source mappings&lt;/a&gt; (ESMs) to process millions of events every day. The fully managed polling infrastructure of ESMs eliminates the need to write and maintain custom code. You can focus on business logic while Lambda handles scaling, batching, and error handling automatically.&lt;/p&gt; 
&lt;p&gt;As workloads grow, many customers need to meet demanding requirements for low-latency message processing, high-concurrency execution, and high-throughput event processing. Use cases such as real-time payment processing, fraud detection, IoT telemetry pipelines, and flash-sale order fulfillment require the ESM to scale rapidly and sustain peak performance without queue backlog.&lt;/p&gt; 
&lt;p&gt;To address these needs, AWS launched &lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-lambda-provisioned-mode-sqs-esm/" target="_blank" rel="noopener"&gt;provisioned mode&lt;/a&gt; for SQS event source mappings. Provisioned mode gives you direct control over the number of event pollers assigned to your ESM for predictable and rapid scaling. With Provisioned mode, you can configure event pollers up to 10,000, supporting concurrency of up to 100,000 concurrent Lambda executions and throughput of 10 GB/s. You can process up to a million events per second.&lt;/p&gt; 
&lt;p&gt;Provisioned mode is also available for &lt;a href="https://kafka.apache.org/" target="_blank" rel="noopener"&gt;Apache Kafka&lt;/a&gt; event source mappings including &lt;a href="https://aws.amazon.com/msk/" target="_blank" rel="noopener"&gt;Amazon Managed Streaming for Apache Kafka&lt;/a&gt; (Amazon MSK) and self-managed Kafka.&lt;/p&gt; 
&lt;h2 id="how-sqs-event-source-mappings-work"&gt;How SQS event source mappings work&lt;/h2&gt; 
&lt;p&gt;When you configure an SQS queue as an event source for a Lambda function, Lambda automatically creates an ESM resource. The ESM manages a fleet of internal event pollers that continuously poll the SQS queue, retrieve messages, and invoke your Lambda function with batches of events.&lt;/p&gt; 
&lt;p&gt;In default ESM mode, Lambda automatically manages the number of event pollers based on queue depth and processing throughput. The system starts with five pollers and scales up as the queue backlog builds, supporting up to 1,250 concurrent invocations. This automatic scaling works well for the majority of event processing workloads. However, the scale-up rate in default mode (approximately 300 additional concurrent executions per minute) can leave latency-sensitive workloads with growing queue backlogs during sudden traffic spikes.&lt;/p&gt; 
&lt;h2 id="what-is-provisioned-mode"&gt;What is provisioned mode?&lt;/h2&gt; 
&lt;p&gt;Provisioned mode gives you explicit control over the minimum and maximum number of event pollers assigned to your ESM. Instead of relying solely on automatic scaling, you define:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;MinimumPollers&lt;/code&gt;: the number of event pollers always active and ready to process messages (range: 2–200).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;MaximumPollers&lt;/code&gt;: the upper bound on event pollers the ESM can scale to (range: 2–10,000).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;These pollers remain active and continuously poll your SQS queue, eliminating cold-start delays in the polling infrastructure. When traffic spikes arrive, your ESM already has capacity allocated to handle the burst.&lt;/p&gt; 
&lt;h3 id="default-mode-vs.-provisioned-mode"&gt;Default mode vs.&amp;nbsp;provisioned mode&lt;/h3&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Attribute&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Default mode&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Provisioned mode&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Minimum event pollers&lt;/td&gt; 
   &lt;td&gt;2&lt;/td&gt; 
   &lt;td&gt;2&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Maximum event pollers&lt;/td&gt; 
   &lt;td&gt;5&lt;/td&gt; 
   &lt;td&gt;10,000&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Maximum concurrent executions&lt;/td&gt; 
   &lt;td&gt;Up to 1250&lt;/td&gt; 
   &lt;td&gt;Up to 100,000&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Maximum throughput&lt;/td&gt; 
   &lt;td&gt;N/A&lt;/td&gt; 
   &lt;td&gt;10 GB/s&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Scale-up rate&lt;/td&gt; 
   &lt;td&gt;~300 concurrency/min&lt;/td&gt; 
   &lt;td&gt;~1,000 concurrency/min&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Poller control&lt;/td&gt; 
   &lt;td&gt;Lambda controlled&lt;/td&gt; 
   &lt;td&gt;Min/Max configurable by you&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Billing&lt;/td&gt; 
   &lt;td&gt;Included in Lambda pricing&lt;/td&gt; 
   &lt;td&gt;Event poller unit (EPU) hours&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Best for&lt;/td&gt; 
   &lt;td&gt;Majority of workloads&lt;/td&gt; 
   &lt;td&gt;Spiky, latency-sensitive, high-throughput workloads&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h2 id="activating-provisioned-mode-for-esm"&gt;Activating provisioned mode for ESM&lt;/h2&gt; 
&lt;p&gt;You can configure provisioned mode when creating a new ESM or updating an existing one. The following examples show configuration using the &lt;a href="https://aws.amazon.com/cli/" target="_blank" rel="noopener"&gt;AWS CLI&lt;/a&gt;, &lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model&lt;/a&gt; (SAM), and &lt;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener"&gt;AWS CloudFormation&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="aws-cli"&gt;AWS CLI&lt;/h3&gt; 
&lt;p&gt;Create a new ESM with provisioned mode:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda create-event-source-mapping \
  --function-name my-function \
  --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
  --batch-size 10 \
  --provisioned-poller-config '{"MinimumPollers": 50, "MaximumPollers": 500}'&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;Update an existing ESM to enable provisioned mode:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda update-event-source-mapping \
  --uuid "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111" \
  --provisioned-poller-config '{"MinimumPollers": 50, "MaximumPollers": 500}'&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="aws-sam-template"&gt;AWS SAM template&lt;/h3&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.12
      Events:
        SQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt MyQueue.Arn
            BatchSize: 10
            ProvisionedPollerConfig:
              MinimumPollers: 50
              MaximumPollers: 500

  MyQueue:
    Type: AWS::SQS::Queue&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="aws-cloudformation"&gt;AWS CloudFormation&lt;/h3&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;Resources:
  MyEventSourceMapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      FunctionName: !Ref MyFunction
      EventSourceArn: !GetAtt MyQueue.Arn
      BatchSize: 10
      ProvisionedPollerConfig:
        MinimumPollers: 50
        MaximumPollers: 500&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h2 id="provisioned-mode-for-sqs-esm-in-action"&gt;Provisioned mode for SQS ESM in action&lt;/h2&gt; 
&lt;p&gt;To see the performance profile with provisioned mode for SQS, deploy a Lambda function that has an SQS queue as its trigger. Use the &lt;a href="https://serverlessland.com/patterns/sqs-lambda-nodejs-sam" target="_blank" rel="noopener"&gt;reference pattern on Serverless Land&lt;/a&gt; or follow the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/services-sqs-configure.html" target="_blank" rel="noopener"&gt;Creating and configuring an Amazon SQS event source mapping&lt;/a&gt; guide to configure provisioned mode for your SQS event source mapping. In the following scenarios, a producer writes 40 million messages, each with a 1 KB payload size, to an SQS queue. Batch size is set to 10, with function duration at about 200 ms.&lt;/p&gt; 
&lt;h3 id="scenario-1-baseline-default-mode"&gt;Scenario 1: Baseline (default mode)&lt;/h3&gt; 
&lt;p&gt;The following chart shows the relationship between &lt;code&gt;ApproximateNumberOfMessagesVisible&lt;/code&gt; (blue) and &lt;code&gt;ConcurrentExecutions&lt;/code&gt; (orange) over time for the baseline scenario using default mode with no provisioned pollers. With provisioned mode disabled, Lambda takes approximately 17 minutes to drain the backlog of 40 million messages. It takes about 6 minutes to reach the maximum concurrent executions.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/13/ComputeBlog-2579-1.png" alt="Chart showing ApproximateNumberOfMessagesVisible and ConcurrentExecutions over time in default mode, with Lambda taking 17 minutes to drain 40 million messages" width="800"&gt;&lt;/p&gt; 
&lt;h3 id="scenario-2-configuring-minimum-event-pollers-and-auto-scaling"&gt;Scenario 2: Configuring minimum event pollers and auto-scaling&lt;/h3&gt; 
&lt;p&gt;To optimize the ESM throughput for these kinds of workloads and reduce the time to drain the message backlog, set the minimum event pollers to a higher than default value. In this scenario, the minimum pollers are set to 100 and maximum pollers are set to 1000.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/13/ComputeBlog-2579-2.png" alt="Chart showing provisioned mode with minimum pollers set to 100, draining 40 million messages in 7 minutes" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;Lambda drains the backlog of 40 million messages in approximately 7 minutes. This is more than 55% faster than the baseline without provisioned mode. It takes only about 1 minute to reach maximum concurrent executions.&lt;/p&gt; 
&lt;h3 id="scenario-3-default-minimum-event-pollers-and-auto-scaling"&gt;Scenario 3: Default minimum event pollers and auto-scaling&lt;/h3&gt; 
&lt;p&gt;In some cases, the workload might not be as performance-sensitive. With the same volume of 40M messages in your SQS queue, activate provisioned mode for ESM. Start with the default minimum event pollers (set to 2) and let Lambda automatically scale the event pollers based on incoming traffic.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/13/ComputeBlog-2579-3.png" alt="Chart showing provisioned mode with default minimum pollers, draining 40 million messages in 9 minutes" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;With this configuration, Lambda drains the backlog in approximately 9 minutes. This is still more than 45% faster than the baseline without provisioned mode. It takes about 3 minutes to reach maximum concurrent executions.&lt;/p&gt; 
&lt;h2 id="best-practices-for-configuring-provisioned-pollers"&gt;Best practices for configuring provisioned pollers&lt;/h2&gt; 
&lt;p&gt;When configuring provisioned mode, keep the following recommendations in mind:&lt;/p&gt; 
&lt;h3 id="right-size-your-minimum-pollers"&gt;Right-size your minimum pollers&lt;/h3&gt; 
&lt;p&gt;Each event poller supports up to 10 concurrent Lambda invocations and approximately 1 MB/s throughput. Use this formula to estimate your minimum poller count:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;MinimumPollers = max(TargetConcurrency / 10, TargetThroughputMBps / 1)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;For example, if your workload requires 500 concurrent executions and 200 MB/s throughput, set &lt;code&gt;MinimumPollers&lt;/code&gt; to at least 200. To estimate the number of event pollers required to verify optimal message processing performance when using provisioned mode for SQS ESM, follow the steps described in &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#sqs-provisioned-mode" target="_blank" rel="noopener"&gt;determining the required event pollers&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="set-maximum-pollers-for-burst-capacity"&gt;Set maximum pollers for burst capacity&lt;/h3&gt; 
&lt;p&gt;Set &lt;code&gt;MaximumPollers&lt;/code&gt; to handle your peak traffic scenario. The ESM scales between your minimum and maximum based on queue depth. A good starting point is 2–5x your minimum pollers.&lt;/p&gt; 
&lt;h3 id="align-with-lambda-concurrency-limits"&gt;Align with Lambda concurrency limits&lt;/h3&gt; 
&lt;p&gt;Provisioned pollers invoke your Lambda function concurrently. Verify that your account’s concurrent execution quota accommodates the maximum concurrency your pollers can drive:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;MaxConcurrency = MaximumPollers × 10&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;If you set &lt;code&gt;MaximumPollers&lt;/code&gt; to 5,000, your account needs at least 50,000 concurrent execution capacity. Request a quota increase through the Lambda quotas page if needed.&lt;/p&gt; 
&lt;h3 id="start-conservatively-and-iterate"&gt;Start conservatively and iterate&lt;/h3&gt; 
&lt;p&gt;Begin with a lower &lt;code&gt;MinimumPollers&lt;/code&gt; value and monitor the CloudWatch metrics described in the following section. Increase the minimum if you observe queue depth growth during traffic spikes, or decrease it if pollers remain underutilized during off-peak hours.&lt;/p&gt; 
&lt;h3 id="use-fifo-queues-for-ordered-workloads"&gt;Use FIFO queues for ordered workloads&lt;/h3&gt; 
&lt;p&gt;When processing order-sensitive workloads, use FIFO queues with high-throughput mode activated. Provisioned mode works with both SQS standard and FIFO queue types.&lt;/p&gt; 
&lt;h3 id="set-up-dead-letter-queues"&gt;Set up dead-letter queues&lt;/h3&gt; 
&lt;p&gt;Configure &lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html" target="_blank" rel="noopener"&gt;dead-letter queues&lt;/a&gt; to manage messages that fail processing after multiple attempts.&lt;/p&gt; 
&lt;h3 id="adjust-batch-size-as-needed"&gt;Adjust batch size as needed&lt;/h3&gt; 
&lt;p&gt;The batch size parameter remains adjustable, with a default value of 10 messages and a maximum of 10,000 messages for standard queues.&lt;/p&gt; 
&lt;h2 id="cost-considerations"&gt;Cost considerations&lt;/h2&gt; 
&lt;p&gt;Provisioned mode billing is based on event poller unit (EPU) hours. You pay for the number of provisioned pollers allocated, regardless of whether they are actively processing messages. See &lt;a href="https://aws.amazon.com/lambda/pricing/" target="_blank" rel="noopener"&gt;AWS Lambda pricing&lt;/a&gt; for details. Key optimization strategies are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Match minimum pollers to your sustained baseline traffic to avoid over-provisioning during low-traffic periods.&lt;/li&gt; 
 &lt;li&gt;Use maximum pollers for burst capacity as you only pay for pollers that scale up while they are active.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="monitoring-provisioned-mode-with-cloudwatch"&gt;Monitoring provisioned mode with CloudWatch&lt;/h2&gt; 
&lt;p&gt;Lambda publishes the following CloudWatch metrics for provisioned mode ESMs:&lt;/p&gt; 
&lt;table border="1px" width="100%" cellpadding="10px"&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;ProvisionedPollers&lt;/td&gt; 
   &lt;td&gt;Current number of provisioned event pollers allocated&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;ConcurrentExecutions&lt;/td&gt; 
   &lt;td&gt;Number of concurrent Lambda invocations driven by the ESM&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;ApproximateNumberOfMessagesVisible&lt;/td&gt; 
   &lt;td&gt;SQS queue depth (from SQS metrics)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Duration&lt;/td&gt; 
   &lt;td&gt;Function execution time per invocation&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Set CloudWatch alarms on &lt;code&gt;ApproximateNumberOfMessagesVisible&lt;/code&gt; to detect queue backlogs, and on &lt;code&gt;ProvisionedPollers&lt;/code&gt; to track the number of provisioned pollers. To understand how your ESM processes messages at each stage, from polling through invocation to completion, &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics-types.html#event-source-mapping-metrics" target="_blank" rel="noopener"&gt;opt in to the EventCount metric group&lt;/a&gt;. This provides detailed metrics including &lt;code&gt;PolledEventCount&lt;/code&gt;, &lt;code&gt;FilteredOutEventCount&lt;/code&gt;, &lt;code&gt;InvokedEventCount&lt;/code&gt;, &lt;code&gt;FailedInvokeEventCount&lt;/code&gt;, and &lt;code&gt;DeletedEventCount&lt;/code&gt;.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;Provisioned mode for SQS event source mappings gives you control over scaling behavior for your most demanding workloads. By configuring minimum and maximum event pollers, you achieve predictable low-latency processing, scale to 100,000 concurrent executions, and sustain throughput of up to a million events per second, without waiting for automatic scale-up.&lt;/p&gt; 
&lt;p&gt;Dedicated pollers deliver predictable, low-latency performance. This makes them well-suited for workloads like real-time financial transactions, high-volume IoT data ingestion, or flash sale order processing. You can achieve 3x faster scaling compared to default mode. Combined with CloudWatch observability and flexible configuration through CLI, SAM, and CloudFormation, provisioned mode integrates into your existing deployment workflows.&lt;/p&gt; 
&lt;p&gt;To get started, explore the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#sqs-provisioned-mode" target="_blank" rel="noopener"&gt;provisioned mode configuration guide for SQS event source mappings&lt;/a&gt;. Deploy the sample application from the &lt;a href="https://serverlessland.com/patterns/sqs-lambda-nodejs-sam" target="_blank" rel="noopener"&gt;Serverless Land reference pattern&lt;/a&gt;. To request a concurrent execution quota increase for high-throughput workloads, visit the Lambda quotas page.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Serverless ICYMI Q2 2026</title>
		<link>https://aws.amazon.com/blogs/compute/serverless-icymi-q2-2026/</link>
		
		<dc:creator><![CDATA[Julian Wood]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 16:40:00 +0000</pubDate>
				<category><![CDATA[Amazon EventBridge]]></category>
		<category><![CDATA[Amazon Simple Storage Service (S3)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[AWS Step Functions]]></category>
		<category><![CDATA[Serverless]]></category>
		<guid isPermaLink="false">4e21c7c12d729f20e89e9c3ed42a4781e15a8981</guid>

					<description>In this 33rd quarterly recap post, discover the most impactful AWS serverless launches, features, and resources from Q2 2026 that you might have missed. Stay current with the latest serverless innovations that can improve your applications. In case you missed our last ICYMI, read about what happened in Q1 2026. AWS Lambda MicroVMs AWS Lambda […]</description>
										<content:encoded>&lt;p&gt;In this 33rd quarterly recap post, discover the most impactful AWS serverless launches, features, and resources from Q2 2026 that you might have missed. Stay current with the latest serverless innovations that can improve your applications.&lt;/p&gt; 
&lt;p&gt;In case you missed our last ICYMI, read about what happened in &lt;a href="https://aws.amazon.com/blogs/compute/serverless-icymi-q1-2026/" target="_blank" rel="noopener"&gt;Q1 2026&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;img loading="lazy" class="aligncenter" src="//d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/18/icymi-2-q2-26-1.png" alt="Serverless ICYMI Q2 2026 banner" width="800" height="154"&gt;&lt;/p&gt; 
&lt;h2 id="aws-lambda-microvms"&gt;AWS Lambda MicroVMs&lt;/h2&gt; 
&lt;div style="text-align: center"&gt; 
 &lt;iframe loading="lazy" title="Introducing AWS Lambda MicroVMs | Amazon Web Services" width="500" height="281" src="https://www.youtube-nocookie.com/embed/lIOjTOGh-po?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen sandbox="allow-scripts allow-same-origin"&gt;&lt;/iframe&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/aws/run-isolated-sandboxes-with-full-lifecycle-control-aws-lambda-introduces-microvms/" target="_blank" rel="noopener"&gt;AWS Lambda MicroVMs&lt;/a&gt; is a new serverless compute primitive for running user or AI-generated code in isolated, stateful execution environments. Built on the same Firecracker virtualization that powers over 15 trillion monthly Lambda invocations, MicroVMs give you VM-level isolation with near-instant launch and resume. Each MicroVM runs in its own Linux environment with no shared kernel or resources between sessions. This isolation makes it a useful solution for AI coding assistant sandboxes, interactive code or multi-tenant development environments, CI/CD build environments, data analytics platforms, vulnerability scanners, and game servers that run user-supplied scripts.&lt;/p&gt; 
&lt;p&gt;Standard Lambda functions are best for event-driven, request-response workloads which have a 15-minute timeout. MicroVMs are purpose-built for single end user or session workloads and can preserve state for up to 8 hours. You get full lifecycle controls including launch, suspend, resume, and terminate. You can suspend them during the 8 hours if you don’t need them active. MicroVMs retain memory and disk state for the length of the session, even while suspended. They can auto resume when you need to use them again.&lt;/p&gt; 
&lt;p&gt;Serverless Land contains &lt;a href="https://serverlessland.com/patterns?services=lambda-microvms" target="_blank" rel="noopener"&gt;example applications&lt;/a&gt; and &lt;a href="https://serverlessland.com/explore/lambda-microvms" target="_blank" rel="noopener"&gt;a resources page&lt;/a&gt; with more details. The &lt;a href="https://www.youtube.com/watch?v=paoEOWbyBxE" target="_blank" rel="noopener"&gt;Serverless Office Hours live stream&lt;/a&gt; has more explanations and live demos.&lt;/p&gt; 
&lt;h2 id="amazon-s3-files-and-lambda-integration"&gt;Amazon S3 Files and Lambda integration&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/aws/launching-s3-files-making-s3-buckets-accessible-as-file-systems/" target="_blank" rel="noopener"&gt;Amazon S3 Files&lt;/a&gt; makes your S3 buckets accessible as high-performance file systems. S3 files is a fully featured, POSIX-compatible file system to access to your data with approximately 1ms latency.&lt;/p&gt; 
&lt;p&gt;For serverless workloads, the &lt;a href="https://aws.amazon.com/blogs/compute/modernizing-lambda-s3-workloads-with-amazon-s3-files/" target="_blank" rel="noopener"&gt;Lambda integration with S3 Files&lt;/a&gt; lets your functions mount an S3 bucket as a local file system. Your function reads and writes files at a local mount path like &lt;em&gt;/mnt/data&lt;/em&gt;, and the file system handles synchronization with S3 automatically. You can avoid downloading objects to &lt;em&gt;/tmp&lt;/em&gt; from S3 within your function and work directly with files. Applications that assume a file system can now run on Lambda without rewriting their I/O layer. Use cases include sharing data between functions, ML model loading, document processing, media transcoding, or any pipeline that treats data as files rather than objects.&lt;/p&gt; 
&lt;h2 id="aws-lambda-durable-functions"&gt;AWS Lambda durable functions&lt;/h2&gt; 
&lt;p&gt;The Lambda durable functions &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/lambda-durable-execution-java-ga/" target="_blank" rel="noopener"&gt;SDK for Java is now generally available&lt;/a&gt;, joining Python and TypeScript. This allows Java developers to build multi-step workflows with automatic checkpointing and recovery without adding external orchestration. Durable functions is also now available in &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/lambda-durable-functions-16-new-regions/" target="_blank" rel="noopener"&gt;16 additional AWS Regions&lt;/a&gt;. Learn how to build &lt;a href="https://aws.amazon.com/blogs/compute/building-fault-tolerant-multi-agent-ai-workflows-with-aws-lambda-durable-functions/" target="_blank" rel="noopener"&gt;fault-tolerant multi-agent AI workflows&lt;/a&gt; to coordinate multiple AI agents that call tools, make decisions, and hand off work. There is automatic recovery if any agent fails mid-task. &lt;a href="https://aws.amazon.com/blogs/compute/build-reliable-voice-analytics-workflows-with-aws-lambda-durable-functions-and-amazon-bedrock/" target="_blank" rel="noopener"&gt;Voice analytics with Amazon Bedrock&lt;/a&gt; shows building a pipeline that processes call recordings through transcription, sentiment analysis, and summarization with durable checkpoints between each stage. For &lt;a href="https://www.youtube.com/watch?v=KRT0Z7k01GE" target="_blank" rel="noopener"&gt;best practices, AI patterns, and futures&lt;/a&gt;, view the live stream.&lt;/p&gt; 
&lt;h2 id="aws-lambda-managed-instances"&gt;AWS Lambda Managed Instances&lt;/h2&gt; 
&lt;p&gt;Lambda Managed Instances now allows you to &lt;a href="https://aws.amazon.com/blogs/compute/building-memory-intensive-apps-with-aws-lambda-managed-instances/" target="_blank" rel="noopener"&gt;build memory-intensive apps with up to 32 GB&lt;/a&gt; (3x more than standard Lambda). This allows use cases like in-memory caching, large dataset analytics, and ML inference that previously required considering other services.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/15/ComputeBlog-2692-3.png" alt="Architecture diagram for AWS Lambda Managed Instances memory-intensive apps" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 1 — AWS Lambda Managed Instances for memory-intensive apps architecture&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-lambda-managed-instances/" target="_blank" rel="noopener"&gt;Scheduled scaling&lt;/a&gt; lets you pre-warm capacity for predictable traffic patterns with &lt;a href="https://aws.amazon.com/eventbridge/scheduler/" target="_blank" rel="noopener"&gt;Amazon EventBridge Scheduler&lt;/a&gt;. This helps reduce cold start latency during known demand spikes. &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/06/aws-lambda-managed-instances-tag-propagation/" target="_blank" rel="noopener"&gt;Tag propagation&lt;/a&gt; automatically applies your function tags to the underlying &lt;a href="https://aws.amazon.com/ec2/" target="_blank" rel="noopener"&gt;Amazon EC2&lt;/a&gt; instances, &lt;a href="https://aws.amazon.com/ebs/" target="_blank" rel="noopener"&gt;Amazon Elastic Block Store&lt;/a&gt; volumes, and network interfaces. This helps finance teams with cost allocation visibility without manual tag management.&lt;/p&gt; 
&lt;h2 id="other-lambda-updates"&gt;Other Lambda updates&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/aws-lambda-response-streaming/" target="_blank" rel="noopener"&gt;Response streaming&lt;/a&gt; is now available in all commercial AWS Regions, bringing full regional parity for progressively streaming data back to clients. This is useful for LLM-powered applications where users expect to see tokens as they generate rather than waiting for a complete response.&lt;/p&gt; 
&lt;p&gt;The &lt;a href="https://aws.amazon.com/blogs/compute/integrating-event-source-mappings-with-aws-lambda-tenant-isolation-mode/" target="_blank" rel="noopener"&gt;tenant isolation mode now integrates with Event Source Mappings&lt;/a&gt; from &lt;a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener"&gt;Amazon SQS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/kinesis/" target="_blank" rel="noopener"&gt;Amazon Kinesis&lt;/a&gt;, and Amazon EventBridge. Multi-tenant SaaS applications can process messages in isolated execution environments without building custom routing logic.&lt;/p&gt; 
&lt;p&gt;If you have a fleet of functions on older runtimes, you can now &lt;a href="https://aws.amazon.com/blogs/compute/upgrading-lambda-function-runtimes-at-scale-with-aws-transform-custom/" target="_blank" rel="noopener"&gt;upgrade runtimes at scale using AWS Transform custom&lt;/a&gt;. This uses AI to analyze your function code, identify breaking changes for the target runtime version, and generate the code modifications needed. This can help teams save manual migration effort across many functions. The &lt;a href="https://www.youtube.com/watch?v=FD1iDCj2r5Q" target="_blank" rel="noopener"&gt;Serverless Office Hours live stream&lt;/a&gt; has more information.&lt;/p&gt; 
&lt;p&gt;Lambda added the &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/aws-lambda-adds-ruby/" target="_blank" rel="noopener"&gt;Ruby 4.0 runtime&lt;/a&gt;. In addition to providing access to the latest Ruby language features, Lambda adds support for &lt;a href="https://aws.amazon.com/blogs/compute/introducing-advanced-logging-controls-for-aws-lambda-functions/" target="_blank" rel="noopener"&gt;Lambda advanced logging controls&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM)&lt;/a&gt; CLI now &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-sam-cli-buildkit-aws-lambda/" target="_blank" rel="noopener"&gt;supports BuildKit&lt;/a&gt; for building container images from Dockerfiles. This allows faster multi-stage builds with better caching, cross-architecture image builds, and Docker secrets to keep credentials out of final image layers.&lt;/p&gt; 
&lt;h2 id="containers-with-mama-j"&gt;Containers with Mama J&lt;/h2&gt; 
&lt;div style="text-align: center"&gt; 
 &lt;iframe loading="lazy" title="Containers on Amazon ECS with Mama J" width="500" height="281" src="https://www.youtube-nocookie.com/embed/U2wmozx3uwM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen sandbox="allow-scripts allow-same-origin"&gt;&lt;/iframe&gt;
 &lt;br&gt; 
 &lt;i&gt;Serverless with Mama J&lt;/i&gt; 
&lt;/div&gt; 
&lt;p&gt;Mama J is back in the second video of a series where &lt;a href="https://www.linkedin.com/in/singledigit/" target="_blank" rel="noopener"&gt;Eric Johnson&lt;/a&gt; explains what he does all day at work to his mother. Previously, they talked &lt;a href="https://www.youtube.com/watch?v=vg1Q1to4qoE" target="_blank" rel="noopener"&gt;serverless and Lambda&lt;/a&gt;. This time it’s containers, what they are, why they exist, and how AWS manages them at scale. Eric goes through the “it works on my machine” problem, how Docker builds images, container orchestration and how containers differ from Lambda.&lt;/p&gt; 
&lt;p&gt;View the video on the &lt;a href="https://www.youtube.com/watch?v=U2wmozx3uwM" target="_blank" rel="noopener"&gt;AWS Developers YouTube channel&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="aws-step-functions"&gt;AWS Step Functions&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/step-functions/" target="_blank" rel="noopener"&gt;AWS Step Functions&lt;/a&gt; has an &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/06/aws-step-functions-agentcore/" target="_blank" rel="noopener"&gt;Amazon Bedrock AgentCore-powered agentic reasoning step&lt;/a&gt;. You can embed AI agent reasoning directly inside a workflow as a native step type. This bridges structured orchestration with autonomous agent behavior. Your workflow handles the deterministic parts such as branching, retries, timeouts, parallel execution, while the agentic step handles the parts that require flexible reasoning.&lt;/p&gt; 
&lt;h2 id="amazon-eventbridge"&gt;Amazon EventBridge&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-eventbridge-sdk-integrations/" target="_blank" rel="noopener"&gt;Amazon EventBridge Scheduler added 619 new SDK API actions&lt;/a&gt; as targets, including Lambda Managed Instances operations. This means you can schedule calls to a much broader set of AWS APIs without writing a Lambda function.&lt;/p&gt; 
&lt;p&gt;A new post walks through building a &lt;a href="https://aws.amazon.com/blogs/compute/multi-region-event-driven-failover-architecture-with-amazon-eventbridge-and-route-53/" target="_blank" rel="noopener"&gt;multi-Region event-driven failover architecture with Amazon EventBridge and Amazon Route 53&lt;/a&gt;. The pattern uses Amazon EventBridge global endpoints with Route 53 health checks to automatically route events to a healthy Region during failures. This provides active-active or active-passive resilience for event-driven workloads.&lt;/p&gt; 
&lt;h2 id="amazon-bedrock-agentcore"&gt;Amazon Bedrock AgentCore&lt;/h2&gt; 
&lt;p&gt;The &lt;a href="https://aws.amazon.com/" target="_blank" rel="noopener"&gt;Amazon Bedrock&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/machine-learning/amazon-bedrock-agentcore-harness-is-now-generally-available-go-from-idea-to-production-grade-agent-in-minutes/" target="_blank" rel="noopener"&gt;AgentCore harness reached general availability&lt;/a&gt;. Two API calls give you a running agent in seconds which runs in its own isolated environment with a filesystem and shell. It can read files, run commands, and write code safely.&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-bedrock-agentcore-payments-preview" target="_blank" rel="noopener"&gt;AgentCore Payments&lt;/a&gt; (preview) allows agents to autonomously access and pay for APIs and MCP servers, opening up agent-to-agent commerce. &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/agentcore-longterm-memory-metadata" target="_blank" rel="noopener"&gt;AgentCore Memory&lt;/a&gt; has metadata for long-term memory so agents retain and recall context across sessions. Web Search on AgentCore grounds agents in current, cited web knowledge. The Runtime now supports &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-bedrock-agentcore-runtime/" target="_blank" rel="noopener"&gt;bring-your-own file systems from S3 Files and Amazon Elastic File System&lt;/a&gt;, and Node.js for direct code deployment.&lt;/p&gt; 
&lt;h2 id="strands-agents-sdk"&gt;Strands Agents SDK&lt;/h2&gt; 
&lt;p&gt;The open source &lt;a href="https://strandsagents.com/blog/reduced-cost-better-isolation-more-resilience/" target="_blank" rel="noopener"&gt;Strands Agents SDK shipped three capabilities&lt;/a&gt;. Context management that cuts token costs in half by intelligently pruning what goes into the model context window, Strands Shell for sandboxed agent code execution, and Strands Evals 1.0 with chaos testing and adversarial red teaming. This can reduce costs to help make production agent workloads cheaper without sacrificing quality. &lt;a href="https://www.youtube.com/watch?v=PKG6dnt_VPA" target="_blank" rel="noopener"&gt;A Serverless Office Hours live stream&lt;/a&gt; covered the new features in depth.&lt;/p&gt; 
&lt;p&gt;The &lt;a href="https://github.com/strands-agents/sdk-typescript" target="_blank" rel="noopener"&gt;TypeScript SDK&lt;/a&gt; reached general availability, giving JavaScript and TypeScript developers the same model-driven agent framework. &lt;a href="https://www.linkedin.com/in/erikhanchett/" target="_blank" rel="noopener"&gt;Erik Hanchett&lt;/a&gt; ran &lt;a href="https://www.youtube.com/watch?v=5KWIf0mFzy8" target="_blank" rel="noopener"&gt;this live stream&lt;/a&gt; with more details. A new &lt;a href="https://aws.amazon.com/blogs/machine-learning/from-idea-to-ai-app-creating-intelligent-research-assistants-with-strands/" target="_blank" rel="noopener"&gt;blog post on building research assistants with Strands&lt;/a&gt; walks through the full app from prototype to working application in about 200 lines of Python.&lt;/p&gt; 
&lt;h2 id="agent-toolkit-for-aws-and-ai-coding"&gt;Agent Toolkit for AWS and AI coding&lt;/h2&gt; 
&lt;p&gt;The &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/05/agent-toolkit/" target="_blank" rel="noopener"&gt;Agent Toolkit for AWS&lt;/a&gt; became generally available with three plugins (&lt;em&gt;aws-core, aws-agents, aws-data-analytics&lt;/em&gt;), over 30 curated skills, and the AWS MCP Server. View &lt;a href="https://www.youtube.com/watch?v=d1GHVtEFy2A" target="_blank" rel="noopener"&gt;this video for an introduction&lt;/a&gt;. This gives AI coding agents such as Kiro, Claude Code, and Cursor expert AWS knowledge which helps to reduce errors and lower token costs. For more information on the serverless tools available when using AI, see this Serverless Land &lt;a href="https://serverlessland.com/explore/ai-dev-tools" target="_blank" rel="noopener"&gt;resources page&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Serverless Office Hours ran a live stream series finding out how experts use AI to build serverless applications. Hear from:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=RzwYFL6wIOU" target="_blank" rel="noopener"&gt;Ran Isenberg, Serverless Hero&lt;/a&gt; on how he ships with Claude every day and what actually moves the needle.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=R5cA74Qv4hs" target="_blank" rel="noopener"&gt;AWS Community Builder, Darryl Ruggles&lt;/a&gt; on how he built a full-featured blogging platform on AWS serverless services using Claude Code and MCP servers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=irtcYhgQ-vA" target="_blank" rel="noopener"&gt;Mark Sailes&lt;/a&gt; shows how serverless experts built Study from Experts, a focused video learning platform for AWS professionals.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=mUhYA_Obh-4" target="_blank" rel="noopener"&gt;Brian Zambrano and Sean Kendall&lt;/a&gt; walk through how to build a serverless application from prompts using Kiro and MCP servers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Kiro launched &lt;a href="https://aws.amazon.com/blogs/aws/aws-weekly-roundup-aws-finops-agent-in-preview-gemma-4-on-bedrock-kiro-pro-max-and-more-june-15-2026/" target="_blank" rel="noopener"&gt;Kiro Pro Max&lt;/a&gt; and an iOS mobile app for approving and monitoring agentic coding sessions from your phone. Amazon Q Developer IDE plugins are transitioning to Kiro. The &lt;a href="https://aws.amazon.com/blogs/devops/supercharge-your-cloud-operations-with-the-kiro-power-for-aws-devops-agent/" target="_blank" rel="noopener"&gt;Kiro power for AWS DevOps Agent&lt;/a&gt; connects your IDE directly to production intelligence. You can investigate incidents and generate fixes without context switching.&lt;/p&gt; 
&lt;h2 id="serverless-blog-posts"&gt;Serverless blog posts&lt;/h2&gt; 
&lt;h3 id="april"&gt;April&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/building-memory-intensive-apps-with-aws-lambda-managed-instances/" target="_blank" rel="noopener"&gt;Building Memory-Intensive Apps with AWS Lambda Managed Instances&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/serverless-icymi-q1-2026/" target="_blank" rel="noopener"&gt;Serverless ICYMI Q1 2026&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="june"&gt;June&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/multi-region-event-driven-failover-architecture-with-amazon-eventbridge-and-route-53/" target="_blank" rel="noopener"&gt;Multi-Region event-driven failover architecture with Amazon EventBridge and Route 53&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/integrating-event-source-mappings-with-aws-lambda-tenant-isolation-mode/" target="_blank" rel="noopener"&gt;Integrating Event Source Mappings with AWS Lambda tenant isolation mode&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/upgrading-lambda-function-runtimes-at-scale-with-aws-transform-custom/" target="_blank" rel="noopener"&gt;Upgrading Lambda function runtimes at scale with AWS Transform custom&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/modernizing-lambda-s3-workloads-with-amazon-s3-files/" target="_blank" rel="noopener"&gt;Modernizing Lambda + S3 workloads with Amazon S3 Files&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/build-reliable-voice-analytics-workflows-with-aws-lambda-durable-functions-and-amazon-bedrock/" target="_blank" rel="noopener"&gt;Build reliable voice analytics workflows with AWS Lambda durable functions and Amazon Bedrock&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/building-fault-tolerant-multi-agent-ai-workflows-with-aws-lambda-durable-functions/" target="_blank" rel="noopener"&gt;Building fault-tolerant multi-agent AI workflows with AWS Lambda durable functions&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="serverless-office-hours"&gt;Serverless Office Hours&lt;/h2&gt; 
&lt;p&gt;Join our live stream every Tuesday at 11 AM PT for live discussions, Q&amp;amp;A sessions, and deep dives into serverless technologies. View episodes on-demand at &lt;a href="https://serverlessland.com/office-hours" target="_blank" rel="noopener"&gt;serverlessland.com/office-hours&lt;/a&gt;.&lt;/p&gt; 
&lt;h3 id="april-1"&gt;April&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Apr 7 – &lt;a href="https://www.youtube.com/watch?v=j5URBon7YiU" target="_blank" rel="noopener"&gt;AWS Lambda Performance Tuning&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Apr 14 – &lt;a href="https://www.youtube.com/watch?v=SvKXhFVVbGY" target="_blank" rel="noopener"&gt;Serverless Apache Airflow&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Apr 21 – &lt;a href="https://www.youtube.com/watch?v=KRT0Z7k01GE" target="_blank" rel="noopener"&gt;AWS Lambda durable functions: Best Practices, AI patterns, and Futures&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="may"&gt;May&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;May 5 – &lt;a href="https://www.youtube.com/watch?v=FD1iDCj2r5Q" target="_blank" rel="noopener"&gt;Automating AWS Lambda runtime upgrades&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;May 12 – &lt;a href="https://www.youtube.com/watch?v=irtcYhgQ-vA" target="_blank" rel="noopener"&gt;How serverless experts build with AI today&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;May 19 – &lt;a href="https://www.youtube.com/watch?v=mUhYA_Obh-4" target="_blank" rel="noopener"&gt;Building Apps with AI + MCP Servers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;May 26 – &lt;a href="https://www.youtube.com/watch?v=R5cA74Qv4hs" target="_blank" rel="noopener"&gt;AI-assisted development in practice&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="june-1"&gt;June&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Jun 2 – &lt;a href="https://www.youtube.com/watch?v=RzwYFL6wIOU" target="_blank" rel="noopener"&gt;Building with Claude: Lessons from real projects&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Jun 9 – &lt;a href="https://www.youtube.com/watch?v=5KWIf0mFzy8" target="_blank" rel="noopener"&gt;Building Agents with TypeScript&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Jun 22 – &lt;a href="https://www.youtube.com/watch?v=PKG6dnt_VPA" target="_blank" rel="noopener"&gt;What’s new in Strands Agents&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Jun 30 – &lt;a href="https://www.youtube.com/watch?v=paoEOWbyBxE" target="_blank" rel="noopener"&gt;Introducing AWS Lambda MicroVMs&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="still-looking-for-more"&gt;Still looking for more?&lt;/h2&gt; 
&lt;p&gt;The &lt;a href="http://aws.amazon.com/serverless" target="_blank" rel="noopener"&gt;Serverless landing page&lt;/a&gt; has overall information about building serverless applications. The &lt;a href="https://aws.amazon.com/lambda/resources/?aws-lambda-resources-blog.sort-by=item.additionalFields.createdDate&amp;amp;aws-lambda-resources-blog.sort-order=desc" target="_blank" rel="noopener"&gt;Lambda resources page&lt;/a&gt; contains case studies, webinars, whitepapers, customer stories, reference architectures, and even more Getting Started tutorials.&lt;/p&gt; 
&lt;p&gt;You can also follow the Developer Advocacy team to get the latest news, follow conversations, and interact with the team.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Julian Wood: &lt;a href="https://twitter.com/julian_wood" target="_blank" rel="noopener"&gt;&lt;span class="citation" data-cites="julian_wood"&gt;@julian_wood&lt;/span&gt;&lt;/a&gt;, &lt;a class="uri" href="https://www.linkedin.com/in/julianrwood/" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/julianrwood/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Eric Johnson: &lt;a href="https://twitter.com/edjgeek" target="_blank" rel="noopener"&gt;&lt;span class="citation" data-cites="edjgeek"&gt;@edjgeek&lt;/span&gt;&lt;/a&gt;, &lt;a class="uri" href="https://www.linkedin.com/in/singledigit/" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/singledigit/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Erik Hanchett: &lt;a href="https://x.com/ErikCH" target="_blank" rel="noopener"&gt;&lt;span class="citation" data-cites="ErikCH"&gt;@ErikCH&lt;/span&gt;&lt;/a&gt;, &lt;a class="uri" href="https://www.linkedin.com/in/erikhanchett/" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/erikhanchett/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Salih Gueler: &lt;a href="https://x.com/salihgueler" target="_blank" rel="noopener"&gt;&lt;span class="citation" data-cites="salihgueler"&gt;@salihgueler&lt;/span&gt;&lt;/a&gt;, &lt;a class="uri" href="https://www.linkedin.com/in/salihgueler/" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/salihgueler/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Marcia Villalba: &lt;a href="https://twitter.com/mavi888uy/" target="_blank" rel="noopener"&gt;&lt;span class="citation" data-cites="mavi888uy"&gt;@mavi888uy&lt;/span&gt;&lt;/a&gt;, &lt;a class="uri" href="https://www.linkedin.com/in/marciavillalba" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/marciavillalba&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;And finally, visit &lt;a href="http://serverlessland.com/" target="_blank" rel="noopener"&gt;Serverless Land&lt;/a&gt; for your serverless needs.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing self-managed Amazon S3 buckets for AWS Lambda function code</title>
		<link>https://aws.amazon.com/blogs/compute/introducing-self-managed-amazon-s3-buckets-for-aws-lambda-function-code/</link>
		
		<dc:creator><![CDATA[Doug Perkes]]></dc:creator>
		<pubDate>Fri, 17 Jul 2026 10:49:14 +0000</pubDate>
				<category><![CDATA[Amazon Simple Storage Service (S3)]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<guid isPermaLink="false">36752fa0d662b4becdb32bf13b1379bd6ac1a167</guid>

					<description>If you manage Lambda functions at scale, you’ve likely hit the 75 GB code storage limit or explained to your security team why deployment artifacts live in an S3 bucket you don’t control. Today, we’re announcing self-managed Amazon S3 buckets for AWS Lambda deployment packages. Lambda reads your code directly from your bucket, eliminating quota […]</description>
										<content:encoded>&lt;p&gt;If you manage Lambda functions at scale, you’ve likely hit the 75 GB code storage limit or explained to your security team why deployment artifacts live in an S3 bucket you don’t control. Today, we’re announcing self-managed &lt;a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener"&gt;Amazon S3&lt;/a&gt; buckets for &lt;a href="https://aws.amazon.com/pm/lambda/" target="_blank" rel="noopener"&gt;AWS Lambda&lt;/a&gt; deployment packages. Lambda reads your code directly from your bucket, eliminating quota pressure and giving you full security control.&lt;/p&gt; 
&lt;p&gt;Previously, the default AWS-managed code storage created three challenges at scale. First, all copies count toward your 75 GB code storage quota. Second, you cannot apply your own encryption, access controls, or compliance tags to the internal bucket. Third, the copy cannot be incorporated into your disaster recovery strategies.&lt;/p&gt; 
&lt;p&gt;With self-managed S3 buckets, Lambda reads your function code directly from your bucket. No copy, no duplication. Your S3 object becomes the single source of truth for your functions. Deployment packages no longer count against your account’s code storage limit. You manage the bucket’s security and compliance posture: choosing the encryption, defining the access policies, managing lifecycle transitions, and maintaining the audit trail. And because you own the bucket, you can use S3 Cross-Region Replication to maintain fallback copies of your code in a secondary Region, so that your functions remain deployable even if your primary Region experiences an issue. Using self-managed S3 buckets also results in a faster time to first invoke for new functions and after function updates, because Lambda no longer needs to copy your zip package to a Lambda-managed S3 bucket.&lt;/p&gt; 
&lt;p&gt;You can use this feature today in all AWS standard regions where Lambda is available, at no additional charge beyond your standard Amazon S3 storage and request costs. Let’s look at some use cases, how it works, and how to use it at scale.&lt;/p&gt; 
&lt;h2 id="use-cases"&gt;Use cases&lt;/h2&gt; 
&lt;p&gt;Here are a few patterns where owning your deployment bucket makes a real difference.&lt;/p&gt; 
&lt;h3 id="cicd-pipelines-and-artifact-management"&gt;CI/CD pipelines and artifact management&lt;/h3&gt; 
&lt;p&gt;With self-managed storage, your CI/CD pipeline uploads once, and Lambda references the same object. One set of lifecycle rules and access controls covers all artifacts, and rollbacks mean pointing the function to a previous S3 object version.&lt;/p&gt; 
&lt;h3 id="multi-account-and-multi-team-architectures"&gt;Multi-account and multi-team architectures&lt;/h3&gt; 
&lt;p&gt;Organizations using AWS Organizations often separate workloads into multiple accounts: a development account, a staging account, and a production account. They centralize shared resources in a tooling or shared-services account.&lt;/p&gt; 
&lt;p&gt;Self-managed buckets integrate naturally with this pattern:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Store all deployment artifacts in a central “artifact account” bucket.&lt;/li&gt; 
 &lt;li&gt;Grant cross-account &lt;code&gt;s3:GetObject&lt;/code&gt; access to Lambda execution roles in each workload account through bucket policies.&lt;/li&gt; 
 &lt;li&gt;Maintain a single inventory of what code is deployed where, managed by your platform or DevOps team.&lt;/li&gt; 
 &lt;li&gt;Enforce consistent encryption, versioning, and retention policies from one place.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="disaster-recovery-and-business-continuity"&gt;Disaster recovery and business continuity&lt;/h3&gt; 
&lt;p&gt;Because your deployment artifacts live in a bucket you own, you can use the built-in replication features of S3, Cross-Region Replication (CRR) or Same-Region Replication (SRR), to maintain copies of your code artifacts in backup locations. Combined with S3 Versioning and Object Lock, this gives you a durable, tamper-proof code archive that supports rapid recovery if a deployment is accidentally corrupted or deleted.&lt;/p&gt; 
&lt;h2 id="how-it-worked-before"&gt;How it worked before&lt;/h2&gt; 
&lt;p&gt;When you deploy a Lambda function using a .zip deployment package stored in Amazon S3, the process has traditionally worked like this:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;You upload your .zip deployment package to your S3 bucket.&lt;/li&gt; 
 &lt;li&gt;You call &lt;code&gt;CreateFunction&lt;/code&gt; or &lt;code&gt;UpdateFunctionCode&lt;/code&gt;, specifying the S3 bucket and S3 key.&lt;/li&gt; 
 &lt;li&gt;Lambda copies the .zip artifact from your bucket into an internal, service-managed bucket.&lt;/li&gt; 
 &lt;li&gt;Lambda uses this copy to create the optimized version of your function that runs at invocation time.&lt;/li&gt; 
 &lt;li&gt;The copied artifact counts toward your account’s 75 GB code storage quota.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/15/ComputeBlog-2618-1.png" alt="Diagram showing standard Lambda deployment flow where Lambda copies the zip package to an internal bucket" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 1 — Standard Lambda deployment&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;This model is straightforward and works well for most workloads. However, it creates three friction points at scale:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Storage quota pressure:&lt;/strong&gt; Every deployment package copy counts toward your account’s 75 GB total code storage limit. Organizations with hundreds of functions and multiple published versions can exhaust this quota.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;No control over stored artifacts:&lt;/strong&gt; You cannot configure encryption (beyond the service default), access logging, lifecycle policies, Object Lock, or compliance tags on the internal bucket.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Redundant storage:&lt;/strong&gt; Your original artifact remains in your bucket while a copy lives in the Lambda bucket used for provisioning new instances of your Lambda function.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="whats-new-reference-mode"&gt;What’s new: REFERENCE mode&lt;/h2&gt; 
&lt;p&gt;This launch introduced a new function configuration setting, &lt;code&gt;S3ObjectStorageMode&lt;/code&gt;. The default value is &lt;code&gt;COPY&lt;/code&gt;, which provides the existing behavior described in the preceding section. To enable self-managed S3 buckets, set &lt;code&gt;S3ObjectStorageMode&lt;/code&gt; to &lt;code&gt;REFERENCE&lt;/code&gt; when creating or updating a function. In this mode, Lambda no longer copies your deployment package. Instead, it stores a reference to your S3 object and reads the code directly from your bucket when needed. If you do not specify &lt;code&gt;S3ObjectStorageMode&lt;/code&gt;, Lambda still takes a copy by default.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/15/ComputeBlog-2618-2.png" alt="Diagram showing Lambda deployment with self-managed S3 storage where Lambda references the object directly" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 2 — Lambda deployment with self-managed storage&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;This gives you:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;No quota consumption.&lt;/strong&gt; Deployment packages in your bucket don’t count against the 75 GB Function and layer storage account limit.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Improved performance.&lt;/strong&gt; Lambda no longer copies the code to an internal bucket, so function creation and updates are faster.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Full security and compliance control.&lt;/strong&gt; Apply your own bucket policies, encryption, Object Lock, versioning, access logging, and compliance tags.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Single source of truth.&lt;/strong&gt; Your S3 object is the canonical artifact with no additional copies and no drift.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Disaster recovery options.&lt;/strong&gt; Use S3 Cross-Region Replication to maintain fallback copies in a secondary Region.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt; 
&lt;p&gt;To use this feature, specify the &lt;code&gt;S3ObjectStorageMode&lt;/code&gt; parameter when creating or updating your function.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Creating a new function (AWS CLI):&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda create-function \
  --function-name my-function \
  --runtime python3.13 \
  --role arn:aws:iam::123456789012:role/my-lambda-role \
  --handler app.handler \
  --code S3Bucket=amzn-s3-demo-bucket,S3Key=deployments/my-function.zip,S3ObjectVersion=abc123,S3ObjectStorageMode=REFERENCE&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Updating an existing function:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda update-function-code \
  --function-name my-function \
  --s3-bucket amzn-s3-demo-bucket \
  --s3-key deployments/my-function.zip \
  --s3-object-version def456 \
  --s3-object-storage-mode REFERENCE&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/15/ComputeBlog-2618-3.png" alt="AWS Identity and Access Management permissions required for self-managed code storage" width="800"&gt;&lt;/p&gt; 
&lt;h3 id="aws-identity-and-access-management-iam-permissions"&gt;AWS Identity and Access Management (IAM) permissions&lt;/h3&gt; 
&lt;p&gt;Lambda needs permission to read the deployment package from your bucket. You can grant access through an S3 bucket policy.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;S3 bucket policy&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "LambdaSelfManagedCodeAccess",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/deployments/my-function.zip",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function"
        }
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;We recommend including the &lt;code&gt;aws:SourceArn&lt;/code&gt; condition key scoped to your specific function ARN to allow for least-privileged access. Note the &lt;code&gt;Resource&lt;/code&gt; is scoped to the exact S3 key rather than a wildcard prefix. This follows least-privilege and matches how the &lt;code&gt;aws:SourceArn&lt;/code&gt; condition locks down which function can access which object.&lt;/p&gt; 
&lt;h3 id="bucket-requirements"&gt;Bucket requirements&lt;/h3&gt; 
&lt;p&gt;Your S3 bucket must meet the following requirements:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Versioning (required).&lt;/strong&gt; You must enable S3 versioning to make sure that Lambda references a specific, immutable artifact and to protect against accidental overwrites.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Encryption.&lt;/strong&gt; The following encryption types are supported: SSE-S3, SSE-KMS (including customer-managed KMS keys), and DSSE-KMS. If you use SSE-KMS, the Lambda principal must have &lt;code&gt;kms:Decrypt&lt;/code&gt; permission on the key.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Object Lock.&lt;/strong&gt; Supported. You can apply Object Lock in Compliance or Governance mode to prevent accidental deletion of deployment artifacts.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Access logging.&lt;/strong&gt; You can enable S3 server access logging or AWS CloudTrail data events to audit every time Lambda reads your code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="what-happens-when-the-object-is-unavailable"&gt;What happens when the object is unavailable&lt;/h3&gt; 
&lt;p&gt;Lambda periodically accesses the source object from your S3 bucket to reoptimize your function code. You must maintain access to the source object for your function to remain active.&lt;/p&gt; 
&lt;p&gt;If Lambda loses access to the source object for a function, the function transitions to the &lt;strong&gt;Inactive&lt;/strong&gt; state. To restore the function, restore access to the source object and then update the function.&lt;/p&gt; 
&lt;h3 id="performance-considerations"&gt;Performance considerations&lt;/h3&gt; 
&lt;p&gt;Lambda functions with self-managed code storage behave the same as standard Lambda functions with one difference during function creation and update. Lambda does not copy your deployment package to a Lambda-managed S3 bucket. In our testing with a 200MB Python 3.13 function, functions using self-managed storage showed function creation times approximately 5s less than the default &lt;code&gt;COPY&lt;/code&gt; mode. Reading directly from your S3 bucket without an intermediate copy step can provide a modest advantage, particularly for larger deployment packages.&lt;/p&gt; 
&lt;h2 id="getting-started-with-infrastructure-as-code"&gt;Getting started with infrastructure as code&lt;/h2&gt; 
&lt;p&gt;Self-managed code storage can be implemented using infrastructure-as-code tooling with either the &lt;a href="https://aws.amazon.com/cli/" target="_blank" rel="noopener"&gt;AWS CLI&lt;/a&gt; or &lt;a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener"&gt;AWS CloudFormation&lt;/a&gt; today.&lt;/p&gt; 
&lt;h3 id="aws-cli"&gt;AWS CLI&lt;/h3&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-bash"&gt;aws lambda create-function \
  --function-name my-function \
  --runtime python3.13 \
  --role arn:aws:iam::123456789012:role/my-lambda-role \
  --handler app.handler \
  --code S3Bucket=amzn-s3-demo-bucket,S3Key=deployments/my-function.zip,S3ObjectVersion=abc123,S3ObjectStorageMode=REFERENCE \
  --region us-east-1&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h3 id="aws-cloudformation"&gt;AWS CloudFormation&lt;/h3&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-yaml"&gt;MyFunction:
  Type: AWS::Lambda::Function
  Properties:
    FunctionName: my-function
    Runtime: python3.13
    Handler: app.handler
    Role: !GetAtt MyLambdaRole.Arn
    Code:
      S3Bucket: amzn-s3-demo-bucket
      S3Key: deployments/my-function.zip
      S3ObjectVersion: abc123
      S3ObjectStorageMode: REFERENCE&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;h2 id="using-it-at-scale"&gt;Using it at scale&lt;/h2&gt; 
&lt;p&gt;Once you adopt self-managed S3 buckets for your Lambda deployment packages, your artifact bucket grows over time as you deploy new versions of your functions. This section covers strategies for managing that growth efficiently, keeping your versions organized, and planning for cross-Region deployments.&lt;/p&gt; 
&lt;h3 id="managing-artifact-lifecycle-with-s3-lifecycle-policies"&gt;Managing artifact lifecycle with S3 lifecycle policies&lt;/h3&gt; 
&lt;p&gt;Every time you update a function’s code, S3 creates a new object version in your bucket. The previous objects don’t disappear. They accumulate. Without a cleanup strategy, your storage grows indefinitely and old artifacts clutter your bucket.&lt;/p&gt; 
&lt;p&gt;S3 Lifecycle policies let you automate this entirely. You define rules that transition or delete objects based on age, and S3 executes them on your behalf: no scripts, no &lt;code&gt;cron&lt;/code&gt; jobs, no manual intervention.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Strategy 1: Archive old versions to Glacier&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If compliance or audit requirements mandate that you retain all historical deployment packages, but you rarely need to access them, transition old object versions to a lower-cost storage class:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Rules": [
    {
      "ID": "ArchiveOldDeploymentPackages",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "deployments/"
      },
      "NoncurrentVersionTransitions": [
        {
          "NoncurrentDays": 30,
          "StorageClass": "GLACIER_FLEXIBLE_RETRIEVAL"
        }
      ]
    }
  ]
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This rule transitions any non-current object version to S3 Glacier Flexible Retrieval after 30 days. Your active deployment packages remain in S3 Standard for fast access, while historical versions move to archival storage at a fraction of the cost.&lt;/p&gt; 
&lt;p&gt;For artifacts you need to retain for years but will rarely access again, consider a tiered approach: moving to Glacier Flexible Retrieval first, then to Deep Archive:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;"NoncurrentVersionTransitions": [
  {
    "NoncurrentDays": 30,
    "StorageClass": "GLACIER_FLEXIBLE_RETRIEVAL"
  },
  {
    "NoncurrentDays": 365,
    "StorageClass": "DEEP_ARCHIVE"
  }
]&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Strategy 2: Delete old versions you no longer need&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If you don’t have a compliance requirement to retain every historical artifact, you can expire old versions outright:&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-json"&gt;{
  "Rules": [
    {
      "ID": "DeleteOldDeploymentPackages",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "deployments/"
      },
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 14,
        "NewerNoncurrentVersions": 2
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;This rule keeps the 2 most recent non-current versions of each object (giving you a rollback path) and deletes anything older than 14 days beyond that. This aligns well with a deployment strategy where you want the ability to quickly roll back to your previous one or two releases, but don’t need to retain anything older.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/15/ComputeBlog-2618-4.png" alt="Diagram showing the relationship between S3 object versions and Lambda function versions" width="800"&gt;&lt;/p&gt; 
&lt;h3 id="tracking-object-and-function-versions"&gt;Tracking object and function versions&lt;/h3&gt; 
&lt;p&gt;With &lt;code&gt;REFERENCE&lt;/code&gt; mode, there is a direct relationship between your S3 object version and your Lambda function version. We recommend the following practices:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Tag your objects&lt;/strong&gt; with metadata from your CI/CD pipeline (commit SHA, build ID, pipeline run ID) so you can trace any deployed function back to the exact source that produced it.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Document the mapping&lt;/strong&gt; between Lambda function versions (or aliases) and S3 object version IDs. This makes rollbacks straightforward: update the function to reference the previous object version.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 id="cross-account-considerations"&gt;Cross-account considerations&lt;/h3&gt; 
&lt;p&gt;How you organize your artifact buckets across AWS accounts depends on your operational model:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Centralized artifact account:&lt;/strong&gt; A single bucket in a shared-services or tooling account, with bucket policies granting cross-account &lt;code&gt;s3:GetObject&lt;/code&gt; access to Lambda execution roles in workload accounts. This gives your platform team a single inventory of all deployment artifacts with consistent lifecycle, encryption, and access policies.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Per-account buckets:&lt;/strong&gt; Each workload account owns its own artifact bucket. Requires less effort to set up, but harder to enforce consistent governance across many accounts.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Either pattern works with self-managed storage. Choose based on how your organization balances centralized control against team autonomy.&lt;/p&gt; 
&lt;h3 id="cross-region-considerations"&gt;Cross-Region considerations&lt;/h3&gt; 
&lt;p&gt;With &lt;code&gt;REFERENCE&lt;/code&gt; mode, your S3 object is the authoritative copy for your function. Self-managed code storage supports cross-Region function creation within a partition for all default Regions (non-opt-in Regions). You can store your code packages in one Region and deploy your functions in another. This makes cross-Region planning critical. There are four factors to balance:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Disaster recovery&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;This is the most critical consideration. Because your S3 object is the single source of truth in &lt;code&gt;REFERENCE&lt;/code&gt; mode, you do not want all your deployment artifacts in a single Region with no fallback. A recommended pattern:&lt;/p&gt; 
&lt;ol type="1"&gt; 
 &lt;li&gt;&lt;strong&gt;Primary Region:&lt;/strong&gt; Your main artifact bucket where CI/CD pipelines deposit new deployment packages.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Fallback Region:&lt;/strong&gt; A secondary bucket populated via S3 Cross-Region Replication (CRR). If your primary Region becomes unavailable, you can update your Lambda functions to reference the replicated objects in the fallback Region.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Enable &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-time-control.html" target="_blank" rel="noopener"&gt;S3 Replication Time Control (RTC)&lt;/a&gt; if you need a guaranteed SLA (15 minutes) for replication completion.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Weigh replication + storage costs against per-deploy cross-Region data transfer. If you deploy frequently, storing replicated copies in each target Region is usually cheaper. For infrequent deployments, a one-time transfer may suffice.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Governance and data residency&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Some organizations, particularly in regulated industries, have strict requirements about where code artifacts can reside. Before configuring cross-Region replication, confirm that your data is permitted to leave its current Region. Certain regulatory frameworks (for example, data sovereignty laws, FedRAMP boundaries) may restrict replication to specific Region pairs.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If your workload requires fast function creation and activation times, for example, in a CI/CD pipeline where deployment speed is critical, keep your S3 objects in the same Region where you are creating your Lambda functions. Cross-Region reads add latency to the initial code download, which directly impacts how quickly a new function version becomes active after deployment.&lt;/p&gt; 
&lt;p&gt;For workloads where creation speed is less critical (for example, batch processing functions that are updated infrequently), the latency of a cross-Region read might be acceptable and can simplify your architecture.&lt;/p&gt; 
&lt;h2 id="things-to-know"&gt;Things to know&lt;/h2&gt; 
&lt;p&gt;Before adopting self-managed S3 buckets for your Lambda functions, keep the following in mind:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Availability:&lt;/strong&gt; You can use this feature today in all AWS standard regions where Lambda is supported.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Pricing:&lt;/strong&gt; There is no additional Lambda charge. You pay standard S3 costs for storage, and any cross-Region data transfer.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Maximum deployment package size:&lt;/strong&gt; The existing limits apply: 250 MB unzipped.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Supported runtimes:&lt;/strong&gt; All Lambda runtimes that support .zip deployment packages are compatible. Container image deployments are not affected by this feature.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Migration:&lt;/strong&gt; You can switch an existing function from service-managed to self-managed storage by calling &lt;code&gt;UpdateFunctionCode&lt;/code&gt; with the &lt;code&gt;--s3-object-storage-mode REFERENCE&lt;/code&gt; parameter. Lambda recreates the function by referencing the object in your S3 bucket and deletes the saved copy.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Reverting:&lt;/strong&gt; You can switch back to service-managed storage at any time by updating the function with &lt;code&gt;--s3-object-storage-mode COPY&lt;/code&gt;. Lambda resumes copying the artifact to its internal bucket.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Object availability is your responsibility:&lt;/strong&gt; In &lt;code&gt;REFERENCE&lt;/code&gt; mode, Lambda depends on your S3 object being accessible. If the object is deleted, the bucket policy changes, or the KMS key is disabled, new invocations requiring a cold start will fail.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;In this post, we showed how self-managed S3 buckets for Lambda give you more capacity, more control, and simpler compliance, all without changing how you write or invoke your functions. Your deployment packages no longer count against account quotas, your security team can apply the same policies to code artifacts that they apply everywhere else, and your disaster recovery story is as strong as the replication capabilities of S3.&lt;/p&gt; 
&lt;p&gt;To get started:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Read the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-self-managed-storage.html" target="_blank" rel="noopener"&gt;Lambda Developer Guide: Self-managed S3 code storage&lt;/a&gt; for full documentation.&lt;/li&gt; 
 &lt;li&gt;Try it in the &lt;a href="https://console.aws.amazon.com/lambda/home" target="_blank" rel="noopener"&gt;AWS Lambda Console&lt;/a&gt;. Choose &lt;strong&gt;Reference Mode&lt;/strong&gt; under &lt;strong&gt;Code storage mode&lt;/strong&gt; when creating your next function.&lt;/li&gt; 
 &lt;li&gt;Review &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-examples.html" target="_blank" rel="noopener"&gt;S3 Lifecycle Configuration examples&lt;/a&gt; to plan your artifact retention strategy.&lt;/li&gt; 
 &lt;li&gt;Explore &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html" target="_blank" rel="noopener"&gt;S3 Cross-Region Replication&lt;/a&gt; for disaster recovery planning.&lt;/li&gt; 
&lt;/ul&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>New: Enhanced AssetState dimension for AWS Outposts capacity metrics on Amazon CloudWatch</title>
		<link>https://aws.amazon.com/blogs/compute/new-enhanced-assetstate-dimension-for-aws-outposts-capacity-metrics-on-amazon-cloudwatch/</link>
		
		<dc:creator><![CDATA[Rachel McElwaine]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 22:52:23 +0000</pubDate>
				<category><![CDATA[Amazon CloudWatch]]></category>
		<category><![CDATA[AWS Outposts]]></category>
		<guid isPermaLink="false">902ae48011d83ef07d15ecbab76ef7775df8728d</guid>

					<description>Today, we are releasing an expanded format of our Amazon CloudWatch dimensions for AWS Outposts capacity metrics. The existing CloudWatch metrics, AvailableInstanceType_Count, UsedInstanceType_Count, InstanceTypeCapacityAvailability, and InstanceTypeCapacityUtilization for Outposts, can now be grouped using the new AssetState dimension with values: Active, Isolated, or Retiring. In this post, we describe what’s changing and how you can use […]</description>
										<content:encoded>&lt;p&gt;Today, we are releasing an expanded format of our Amazon CloudWatch dimensions for AWS Outposts &lt;a href="https://docs.aws.amazon.com/outposts/latest/server-userguide/outposts-cloudwatch-metrics.html" target="_blank" rel="noopener"&gt;capacity metrics&lt;/a&gt;. The existing CloudWatch metrics, &lt;code&gt;AvailableInstanceType_Count&lt;/code&gt;, &lt;code&gt;UsedInstanceType_Count&lt;/code&gt;, &lt;code&gt;InstanceTypeCapacityAvailability&lt;/code&gt;, and &lt;code&gt;InstanceTypeCapacityUtilization&lt;/code&gt; for Outposts, can now be grouped using the new &lt;strong&gt;AssetState dimension&lt;/strong&gt; with values: &lt;a href="https://docs.aws.amazon.com/outposts/latest/APIReference/API_ComputeAttributes.html#outposts-Type-ComputeAttributes-State" target="_blank" rel="noopener"&gt;&lt;strong&gt;Active, Isolated, or Retiring&lt;/strong&gt;&lt;/a&gt;. In this post, we describe what’s changing and how you can use this dimension to improve your capacity monitoring.&lt;/p&gt; 
&lt;h2 id="whats-changing"&gt;What’s changing&lt;/h2&gt; 
&lt;p&gt;Previously, an Outpost could be moved to one of these asset states following an AWS maintenance action, either by an on-site visit or by a remote network update. These state transitions are triggered by control plane operations and previously were not surfaced in customer-facing metrics. This could lead to incorrect or misleading capacity counts.&lt;/p&gt; 
&lt;p&gt;With this enhancement, you can group the metrics by the dimension to distinguish capacity between production-ready resources and capacity temporarily offline for maintenance.&lt;/p&gt; 
&lt;h2 id="introducing-the-new-assetstate-dimension"&gt;Introducing the new AssetState dimension&lt;/h2&gt; 
&lt;p&gt;This new dimension adds more visibility into the state of your first-generation and second-generation Outpost racks and servers. The values show the internal state of the AWS Outposts hardware and describe the current working state of the Outpost. These new values are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;ACTIVE&lt;/strong&gt; – The Outpost is production-ready and can launch instances.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;ISOLATED&lt;/strong&gt; – The server or asset within the Outpost was taken offline and is temporarily unavailable.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;RETIRING&lt;/strong&gt; – The compute asset is not available for use. This state is used when a replacement part is needed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The new AssetState dimension can be used for creating Amazon CloudWatch alarms for better monitoring, visibility, and alerting of AWS Outposts capacity.&lt;/p&gt; 
&lt;h2 id="example-metrics-output"&gt;Example metrics output&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;5 Server/Assets: 4 Active, 1 Isolated, 3 Active used, 1 Isolated used:&lt;/strong&gt;&lt;/p&gt; 
&lt;div class="hide-language"&gt; 
 &lt;pre&gt;&lt;code class="language-plaintext"&gt;AvailableInstanceType_Count | i3en.metal-2tb | count = 1
AvailableInstanceType_Count | i3en.metal-2tb | ACTIVE | count = 1
AvailableInstanceType_Count | i3en.metal-2tb | ISOLATED | count = 0
AvailableInstanceType_Count | i3en.metal-2tb | RETIRING | count = 0

UsedInstanceType_Count | i3en.metal-2tb | count = 4
UsedInstanceType_Count | i3en.metal-2tb | ACTIVE | count = 3
UsedInstanceType_Count | i3en.metal-2tb | ISOLATED | count = 1
UsedInstanceType_Count | i3en.metal-2tb | RETIRING | count = 0

InstanceTypeCapacityAvailability | i3en.metal-2tb | 20%
InstanceTypeCapacityUtilization | i3en.metal-2tb | 80%&lt;/code&gt;&lt;/pre&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/02/ComputeBlog-2604-1.png" alt="Figure 1: Amazon CloudWatch metrics with the AssetState dimension for AWS Outposts." width="800"&gt;&lt;/p&gt; 
&lt;p&gt;You can now accurately monitor your AWS Outposts capacity and set CloudWatch alarms that reflect available capacity with near real-time visibility.&lt;/p&gt; 
&lt;h2 id="integration-with-cloudwatch-on-outposts"&gt;Integration with CloudWatch on Outposts&lt;/h2&gt; 
&lt;p&gt;This enhanced dimension is fully integrated with &lt;strong&gt;CloudWatch on Outposts&lt;/strong&gt;, so you can monitor your local AWS Outposts infrastructure with the same observability tools you use in AWS Regions.&lt;/p&gt; 
&lt;p&gt;With the new AssetState dimension, you can create more precise CloudWatch alarms on your Outpost that trigger only on capacity status changes (&lt;code&gt;ACTIVE&lt;/code&gt;/&lt;code&gt;ISOLATED&lt;/code&gt;/&lt;code&gt;RETIRING&lt;/code&gt;). This is particularly valuable if you run mission-critical workloads on Outposts and need accurate, real-time visibility into your on-premises capacity.&lt;/p&gt; 
&lt;h2 id="availability"&gt;Availability&lt;/h2&gt; 
&lt;p&gt;These new metrics are enabled by default and available to all AWS Outposts customers at no additional cost in all AWS Regions where AWS Outposts is offered.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;The new AssetState dimension gives AWS Outposts customers clear visibility into the different hardware states of &lt;code&gt;Active&lt;/code&gt;, &lt;code&gt;Isolated&lt;/code&gt;, or &lt;code&gt;Retiring&lt;/code&gt;. This visibility helps you maintain accurate capacity counts and create more precise CloudWatch alarms.&lt;/p&gt; 
&lt;p&gt;To learn more about CloudWatch metrics for AWS Outposts, refer to the &lt;a href="https://docs.aws.amazon.com/outposts/latest/userguide/monitor-outposts.html" target="_blank" rel="noopener"&gt;Outposts monitoring documentation&lt;/a&gt;. For information about CloudWatch on Outposts and local monitoring capabilities, visit the &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-on-Outposts.html" target="_blank" rel="noopener"&gt;CloudWatch on Outposts documentation&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing modularized kernel cryptography in Amazon Linux</title>
		<link>https://aws.amazon.com/blogs/compute/introducing-modularized-kernel-cryptography-in-amazon-linux/</link>
		
		<dc:creator><![CDATA[Mahak Arora]]></dc:creator>
		<pubDate>Tue, 14 Jul 2026 19:34:12 +0000</pubDate>
				<category><![CDATA[Compliance]]></category>
		<guid isPermaLink="false">b9395c1196a0438017e55b5318f6ab32956e7987</guid>

					<description>We are introducing modularized kernel cryptography in Amazon Linux 2023, an approach that separates Federal Information Processing Standard (FIPS) 140-3 cryptographic components into an independent kernel module that can be certified once and reused across subsequent kernel versions. In this post, we describe how this modular approach works, what it means for FIPS compliance workflows, […]</description>
										<content:encoded>&lt;p&gt;We are introducing modularized kernel cryptography in &lt;a href="https://aws.amazon.com/linux/amazon-linux-2023/" target="_blank" rel="noopener"&gt;Amazon Linux 2023&lt;/a&gt;, an approach that separates Federal Information Processing Standard &lt;a href="https://csrc.nist.gov/pubs/fips/140-3/final" target="_blank" rel="noopener"&gt;(FIPS) 140-3&lt;/a&gt; cryptographic components into an independent kernel module that can be certified once and reused across subsequent kernel versions. In this post, we describe how this modular approach works, what it means for FIPS compliance workflows, and how customers can prepare for adoption.&lt;/p&gt; 
&lt;p&gt;Previously, when any part of the kernel changed, the entire kernel binary had to go through FIPS re-certification because the cryptographic code was embedded within it. With this modular approach, only the standalone cryptographic module undergoes validation, which means non-cryptographic kernel changes no longer require full re-certification. This can help customers who need both security updates and FIPS-validated cryptography while reducing disruption.&lt;/p&gt; 
&lt;p&gt;FIPS 140-3 validation can be a critical requirement for customers in regulated environments, including federal contractors. Previously, this re-certification process meant customers had to wait 12-18 months for each new kernel version to complete validation before they could adopt it. With the modular approach, once the module is validated it is designed to carry forward across kernel updates, whether minor or major releases, through a streamlined update process rather than repeating the full certification cycle, as long as the module itself remains unchanged. This is particularly relevant as customers face growing pressure to apply security patches rapidly while helping to maintain continuous compliance.&lt;/p&gt; 
&lt;p&gt;The FIPS re-certification process can be time-intensive with unpredictable timelines given current &lt;a href="https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program" target="_blank" rel="noopener"&gt;NIST Cryptographic Module Validation Program (CMVP)&lt;/a&gt; processing volumes. To help address this, we isolate all FIPS-scoped cryptographic algorithms, self-tests, and integrity checks into a single loadable kernel module that defines its own FIPS 140-3 cryptographic boundary with a stable interface to the kernel. This reduces what must be re-validated because instead of certifying the entire kernel binary which contains millions of lines of non-cryptographic code, only the standalone module containing the cryptographic implementation falls within the certification scope. For subsequent kernel versions using an unchanged module, re-validation can follow a more streamlined process rather than requiring a full certification cycle, helping our customers adopt kernel updates without the re-certification delays they previously faced, as long as the certified module itself remains unchanged.&lt;/p&gt; 
&lt;p&gt;We submitted the module for FIPS 140-3 validation. Based on current CMVP processing timelines, validation is expected to complete in 2027. The module interface boundary is designed to remain stable across kernel versions. Changes to the module are required if the kernel internal cryptographic API changes or if new algorithms need to be added to the FIPS scope. In many of these cases, changes can be absorbed by the interface layer without modifying the certified module itself, reducing the need for full re-certification.&lt;/p&gt; 
&lt;h2 id="technical-overview"&gt;Technical overview&lt;/h2&gt; 
&lt;p&gt;The modular capability is included in AL2023 kernel 6.18 and later versions. The module loads automatically at boot with no kernel rebuild or configuration change required. To operate in FIPS mode, follow the enablement guide referenced in the customer guidance section below. This change does not affect other FIPS user-space modules such as OpenSSL, libgcrypt, and NSS.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;The following diagram illustrates the architectural shift:&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/14/ComputeBlog-2556-1.png" alt="Diagram showing kernel cryptography architecture before and after modularization, with the FIPS crypto module separated from the kernel binary" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Figure 1. Kernel cryptography architecture before and after modularization.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;The implementation spans two areas described below. The kernel build process produces the module as a separate artifact, and a boot-time mechanism loads and connects it to the running kernel.&lt;/p&gt; 
&lt;h3 id="a-restructured-kernel-build"&gt;A restructured kernel build&lt;/h3&gt; 
&lt;p&gt;In the standard kernel build, crypto source code is compiled and statically linked together with other non-crypto components that are not in scope for FIPS to produce the final kernel image. With this change, the build process separates the FIPS-relevant cryptographic components from the kernel image by defining customized compilation rules. Crypto components that are FIPS-related and were previously built into the kernel are now automatically collected and linked separately into a standalone crypto kernel module. The new build process requires no changes to existing build workflows.&lt;/p&gt; 
&lt;h3 id="boot-time-module-plug-in-mechanism"&gt;Boot-time module plug-in mechanism&lt;/h3&gt; 
&lt;p&gt;Immediately after kernel boot starts, the crypto kernel module is loaded and initialized. Low-level interfaces such as function addresses are connected back to the kernel binary interface so that the module integrates seamlessly with the running kernel. Once loaded, kernel crypto subsystems and their services behave as if they were built in, with the same algorithmic implementations and call paths. This process was designed to not have a material impact on performance. This loading process is independent of FIPS mode configuration because FIPS mode controls how cryptographic algorithms behave at runtime while modularization determines how they are built and delivered within the kernel. To learn more about the design and implementation, see the &lt;a href="https://lwn.net/SubscriberLink/1073759/95b3d4cd28506836/" target="_blank" rel="noopener"&gt;detailed writeup on LWN.net&lt;/a&gt;.&lt;/p&gt; 
&lt;h2 id="industry-impact-and-benefits"&gt;Industry impact and benefits&lt;/h2&gt; 
&lt;p&gt;Once the module completes validation, modularized kernel cryptography can help customers in regulated industries update kernels more frequently while maintaining their FIPS validation status. Customers who previously faced 12-18 month re-certification delays with each kernel version can instead adopt updates as they are released, whether they operate in financial services, healthcare, government, or any sector requiring FIPS-validated cryptography. This can help customers who want to apply critical security patches without a full certification cycle before deployment.&lt;/p&gt; 
&lt;h2 id="customer-guidance"&gt;Customer guidance&lt;/h2&gt; 
&lt;p&gt;When evaluating kernel options, customers should consider their specific regulatory requirements, the validation status of cryptographic modules, and their system requirements in accordance with all applicable authorization processes.&lt;/p&gt; 
&lt;p&gt;Customers who require a completed FIPS 140-3 certificate should continue using AL2023 kernel 6.1, which maintains active validation through &lt;a href="https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/5369" target="_blank" rel="noopener"&gt;2029-09-22&lt;/a&gt;. The modularized crypto module is included in kernel 6.18 and initializes automatically at boot. The module is designed to not require configuration changes and preserves current behavior for non-FIPS workloads. Customers planning FIPS adoption can begin evaluation and testing ahead of formal certification.&lt;/p&gt; 
&lt;p&gt;Once validation is complete, customers can transition production workloads to kernel 6.18 or later with the validated module by following the &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/fips-mode.html" target="_blank" rel="noopener"&gt;FIPS Mode enablement guide&lt;/a&gt; for configuration.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;To enable FIPS mode on AL2023, refer to our &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/fips-mode.html" target="_blank" rel="noopener"&gt;FIPS Mode enablement guide&lt;/a&gt;. For regular updates and best practices, follow the &lt;a href="https://aws.amazon.com/blogs/security/" target="_blank" rel="noopener"&gt;AWS Security Blog&lt;/a&gt; and FIPS-related FAQs on &lt;a href="https://aws.amazon.com/linux/amazon-linux-2023/faqs/#topic-3" target="_blank" rel="noopener"&gt;Amazon Linux 2023&lt;/a&gt;. You can also reach out to your AWS account team for help finding the resources you need.&lt;/p&gt; 
&lt;p&gt;If you have questions about this post, &lt;a href="https://console.aws.amazon.com/support/home" target="_blank" rel="noopener"&gt;contact AWS Support&lt;/a&gt;.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
		<item>
		<title>Eliminating Java cold starts with AWS Lambda Managed Instances</title>
		<link>https://aws.amazon.com/blogs/compute/eliminating-java-cold-starts-with-aws-lambda-managed-instances/</link>
		
		<dc:creator><![CDATA[Jay Colodner]]></dc:creator>
		<pubDate>Mon, 13 Jul 2026 20:23:19 +0000</pubDate>
				<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">61c4cb8271f5feedd1503a2207b2d5899ffc295f</guid>

					<description>A single cold start can push your Java Lambda function’s response time from milliseconds to seconds, enough to violate your p99 SLA, timeout a downstream service, and page your on-call. The Java Virtual Machine (JVM) performs best in long-running processes. Its Just-In-Time (JIT) compiler progressively optimizes code over thousands of invocations. Standard serverless execution environments […]</description>
										<content:encoded>&lt;p&gt;A single cold start can push your Java Lambda function’s response time from milliseconds to seconds, enough to violate your p99 SLA, timeout a downstream service, and page your on-call. The Java Virtual Machine (JVM) performs best in long-running processes. Its Just-In-Time (JIT) compiler progressively optimizes code over thousands of invocations. Standard serverless execution environments recycle before the JVM reaches peak performance. This creates a tradeoff for latency-sensitive applications between cold-start penalties and runtime optimizations. For production services with p99 service level agreement (SLA) requirements, a single 14-second cold start spike can violate response time guarantees. It triggers downstream timeouts and degrades customer experience.&lt;/p&gt; 
&lt;p&gt;&lt;a href="https://aws.amazon.com/lambda/lambda-managed-instances/" target="_blank" rel="noopener"&gt;AWS Lambda Managed Instances&lt;/a&gt; changes this equation. As a capability of AWS Lambda, Managed Instances runs your functions on managed &lt;a href="https://aws.amazon.com/ec2/" target="_blank" rel="noopener"&gt;Amazon Elastic Compute Cloud (Amazon EC2)&lt;/a&gt; instances in your account and maintains JVM persistence across invocations. Connection pools, class hierarchies, and heap state persist across thousands of requests. This allows the JIT C2 compiler to complete optimizations like method inlining, escape analysis, and loop unrolling. The result: 18 to 30% better median latency and 3 to 30x better tail latency compared to Standard Lambda, as the benchmarks in this post demonstrate.&lt;/p&gt; 
&lt;p&gt;This post benchmarks four Java deployment modes across three workload types using 240,000 requests. The modes compared are Standard Lambda, &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html" target="_blank" rel="noopener"&gt;AWS Lambda SnapStart&lt;/a&gt;, GraalVM Native Image, and Lambda Managed Instances. The workload types are CPU-bound, I/O + computation, and I/O-bound. This post presents benchmark results demonstrating Managed Instances delivering 30% better median latency and removing multi-second cold-start spikes on CPU-bound work after JIT warmup. It explains why these gains occur, maps each deployment mode to specific traffic patterns and cold-start tolerance requirements, and provides a decision framework for selecting the right approach for your workload.&lt;/p&gt; 
&lt;h2 id="benchmarking-setup"&gt;Benchmarking setup&lt;/h2&gt; 
&lt;p&gt;The benchmark runs all four deployment modes with identical Spring Boot 4.0.6 applications on Java 25 and &lt;a href="https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html" target="_blank" rel="noopener"&gt;AWS SDK v2&lt;/a&gt;. This configuration verifies fair comparison across modes. We tested three workloads: UC1 (PDF generation, CPU-bound), UC2 (data aggregation, I/O + computation), and UC3 (API orchestration, I/O-bound). The benchmark sends 240,000 requests using Artillery load testing at 33 RPS. Standard Lambda, SnapStart, and Native Lambda use 1024 MB (1 vCPU). Managed Instances uses c7i.xlarge instances with 2048 MB memory. Concurrency is tuned per workload (UC1=3, UC2=5, UC3=10) based on load testing to avoid thread contention. The benchmark measures p50, p99, and maximum latency across 10 runs of 2,000 requests each, with 5-minute cool-down between runs. The benchmark tracks JIT compilation metrics via Amazon CloudWatch Embedded Metrics Format. You can validate these results against Amazon API Gateway access logs, which confirm a &amp;lt;0.1% error rate. The GitHub repository contains complete source code, &lt;a href="https://aws.amazon.com/serverless/sam/" target="_blank" rel="noopener"&gt;AWS Serverless Application Model (AWS SAM)&lt;/a&gt; templates, load scripts, and raw data. Performance claims in this post reference data from this benchmark methodology.&lt;/p&gt; 
&lt;p&gt;Figure 1 presents the architecture for all four deployment modes running in parallel against shared backend services.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/09/ComputeBlog-2588-1.png" alt="Architecture diagram showing all four Lambda deployment modes (Standard, SnapStart, GraalVM Native, Managed Instances) running in parallel against shared backend services including DynamoDB, S3, SQS, and SNS" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;To reproduce these benchmarks or deploy the sample applications, refer to the GitHub repository. The repository contains complete SAM templates, Artillery load configurations, deployment instructions, and cleanup commands. This post focuses on benchmark results and analysis. The benchmark used the following tools and services:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;An AWS account with permissions to create Lambda functions, &lt;a href="https://aws.amazon.com/dynamodb/" target="_blank" rel="noopener"&gt;Amazon DynamoDB&lt;/a&gt; tables, &lt;a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener"&gt;Amazon Simple Storage Service (Amazon S3)&lt;/a&gt; buckets, &lt;a href="https://aws.amazon.com/sns/" target="_blank" rel="noopener"&gt;Amazon Simple Notification Service (Amazon SNS)&lt;/a&gt; topics, and &lt;a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener"&gt;Amazon Simple Queue Service (Amazon SQS)&lt;/a&gt; queues&lt;/li&gt; 
 &lt;li&gt;Java 25 (Amazon Corretto recommended).&lt;/li&gt; 
 &lt;li&gt;Maven 3.9+.&lt;/li&gt; 
 &lt;li&gt;AWS SAM CLI v1.155 or later.&lt;/li&gt; 
 &lt;li&gt;Docker (for GraalVM native image builds) or alternative.&lt;/li&gt; 
 &lt;li&gt;&lt;a href="https://www.artillery.io/" target="_blank" rel="noopener"&gt;Artillery&lt;/a&gt; for load testing.&lt;/li&gt; 
 &lt;li&gt;The &lt;a href="https://github.com/aws-samples/sample-aws-lambda-managed-instances/tree/main/examples/performance/java-lambda-optimization" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt; with complete source code and SAM templates&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 id="observing-max-latency"&gt;Observing max latency&lt;/h2&gt; 
&lt;p&gt;Managed Instances removes the extreme tail spikes characteristic of cold starts. Managed Instances delivers 27x faster maximum latency on CPU-bound workloads (UC1: 489 ms vs.&amp;nbsp;13,270 ms Standard). Mixed I/O + compute workloads see a 3x improvement (UC2: 3,644 ms vs.&amp;nbsp;11,174 ms Standard). I/O-bound workloads improve 30x (UC3: 309 ms vs.&amp;nbsp;9,237 ms Standard). We measured all results using the methodology described in Benchmarking setup.&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/09/ComputeBlog-2588-2.png" alt="Bar chart comparing maximum latency across Standard Lambda, SnapStart, GraalVM Native, and Managed Instances for three workload types" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;The Standard Lambda 13-second maximum on UC1 represents a full cold start. That cold start includes JVM boot, Spring context initialization, &lt;a href="https://aws.amazon.com/dynamodb/" target="_blank" rel="noopener"&gt;Amazon DynamoDB&lt;/a&gt; client setup, and the first PDF render. SnapStart reduces this to under 3 seconds by restoring from a &lt;a href="https://firecracker-microvm.github.io/" target="_blank" rel="noopener"&gt;Firecracker microVM&lt;/a&gt; snapshot. However, the restore process plus re-initialization of resources that cannot be checkpointed (network connections, random number generators) still adds latency. GraalVM Native starts in under 2 seconds because the ahead-of-time (AOT) compiled binary skips JVM boot entirely. The Managed Instances maximum of 487 ms is not a cold start; it’s the slowest warm request across 20,000 invocations. For production SLAs, a 14-second cold start spike on Standard Lambda violates most requirements, while Managed Instances removes that spike entirely.&lt;/p&gt; 
&lt;h2 id="observing-median-latency-p50"&gt;Observing median latency (p50)&lt;/h2&gt; 
&lt;p&gt;Lambda Managed Instances delivered the lowest median latency across all three workloads. Results demonstrate 30% faster median latency on CPU-bound workloads (UC1: 97 ms vs.&amp;nbsp;139 ms Standard). Mixed I/O + compute achieves a 19% improvement (UC2: 184 ms vs.&amp;nbsp;228 ms Standard). I/O-bound workloads improve 18% (UC3: 76 ms vs.&amp;nbsp;93 ms Standard).&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/09/ComputeBlog-2588-3.png" alt="Bar chart comparing median (p50) latency across Standard Lambda, SnapStart, GraalVM Native, and Managed Instances for three workload types" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;The improvement scales with CPU intensity because the JIT C2 compiler on persistent Managed Instances optimizes hot code paths that short-lived serverless environments never reach. On CPU-bound workloads (UC1), the JIT compiler has more opportunity to optimize tight loops in PDF rendering. On I/O-bound workloads (UC3), network latency to Amazon DynamoDB, &lt;a href="https://aws.amazon.com/sqs/" target="_blank" rel="noopener"&gt;Amazon SQS&lt;/a&gt;, and &lt;a href="https://aws.amazon.com/sns/" target="_blank" rel="noopener"&gt;Amazon SNS&lt;/a&gt; dominates the request duration, so JIT optimization provides smaller gains.&lt;/p&gt; 
&lt;h2 id="observing-tail-latency-p99"&gt;Observing tail latency (p99)&lt;/h2&gt; 
&lt;p&gt;Managed Instances showed even larger improvements at the tail of the latency distribution. The p99 improves 36% on CPU-bound workloads (UC1: 225 ms vs.&amp;nbsp;353 ms Standard). Mixed I/O + compute achieves a 41% improvement (UC2: 1,883 ms vs.&amp;nbsp;3,201 ms Standard). I/O-bound workloads improve 27% (UC3: 193 ms vs.&amp;nbsp;265 ms Standard).&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2026/07/09/ComputeBlog-2588-4.png" alt="Bar chart comparing p99 tail latency across Standard Lambda, SnapStart, GraalVM Native, and Managed Instances for three workload types" width="800"&gt;&lt;/p&gt; 
&lt;p&gt;UC2 showed the largest p99 improvement (41%) because data aggregation combines DynamoDB queries, returning hundreds of records with in-memory statistical computation and Amazon S3 uploads. Standard Lambda environments that haven’t fully warmed their JIT produce significantly slower responses at the tail. The persistent JIT optimization (-Xms512m -Xmx1408m) with G1 garbage collection (GC) and explicit heap sizing on Managed Instances both contribute to tighter tail latency distribution. For services with SLAs on p99 response time, this reliability improvement matters more than median performance. For workloads with significant heap pressure, tuning -XX:MaxGCPauseMillis and monitoring GC logs can further tighten tail latency.&lt;/p&gt; 
&lt;h2 id="why-lambda-managed-instances-is-faster-jit-compilation"&gt;Why Lambda Managed Instances is faster: JIT compilation&lt;/h2&gt; 
&lt;p&gt;The JVM’s Just-In-Time compiler works in tiers. The C1 compiler performs initial compilation quickly with basic optimizations. The C2 compiler profiles execution over hundreds of invocations and then applies aggressive optimizations: method inlining (eliminating function call overhead), escape analysis (allocating objects on the stack instead of the heap), loop unrolling (reducing branch overhead), and vectorization (processing multiple data elements in a single CPU instruction).&lt;/p&gt; 
&lt;p&gt;The following table presents JIT warmup progression using java.lang.management.&lt;/p&gt; 
&lt;p&gt;CompilationMXBean emitted through Amazon CloudWatch Embedded Metrics Format. We collected this data from a 1,500-request sustained load test on UC1 (PDF generation):&lt;/p&gt; 
&lt;table border="1px" cellpadding="10px" width="100%"&gt; 
 &lt;tbody&gt;
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Invocation&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Avg Latency&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;What’s Happening&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;First requests (application init)&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;1&lt;/td&gt; 
   &lt;td&gt;~2,400ms&lt;/td&gt; 
   &lt;td&gt;JVM boot, spring context creation, SDK client setup&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Early requests (C1 compiled)&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;2-100&lt;/td&gt; 
   &lt;td&gt;~145ms&lt;/td&gt; 
   &lt;td&gt;C1 compiler active. App is functional, but not optimized&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Steady state (C2 optimized)&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;1000+&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;~38ms&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;C2 optimizations completed&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt;
&lt;/table&gt; 
&lt;p&gt;The first invocation includes one-time application start costs: class loading, Spring context initialization, and DynamoDB client construction. These costs are unrelated to JIT compilation and occur on any deployment mode.&lt;/p&gt; 
&lt;p&gt;Once C1 compilation stabilizes during early invocations, latency reaches approximately 145ms. This is the baseline compiled performance. Over the next several hundred invocations, the C2 compiler profiles hot code paths and applies optimizations. By invocation 1,000, latency drops to 38ms. This represents a 3.8x improvement from JIT optimization alone.&lt;/p&gt; 
&lt;p&gt;Standard Lambda environments typically recycle before C2 completes its optimization passes. On Managed Instances, concurrent requests share the same JVM. This accelerates JIT profiling: three concurrent requests generate three times the method invocation data for the C2 compiler to optimize. The C2 compiler profiles execution patterns across all concurrent requests. It identifies hot code paths faster and applies optimizations sooner than single-concurrency environments.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt; CPU-bound workloads see the largest gains (30% faster median latency on UC1) because the JIT compiler has more opportunity to optimize tight loops and method calls. I/O-bound workloads see smaller gains (18% faster on UC3) because network latency to DynamoDB, SQS, and SNS dominates request duration. The JIT compiler still optimizes your code, but the network time remains constant across all deployment modes.&lt;/p&gt; 
&lt;h2 id="choosing-the-right-mode"&gt;Choosing the right mode&lt;/h2&gt; 
&lt;p&gt;No single mode wins in every scenario. The right choice depends on your traffic pattern, cold-start tolerance, team expertise, and operational complexity budget.&lt;/p&gt; 
&lt;p&gt;Lambda Managed Instances is ideal for steady-state traffic patterns above 5 requests per second with low cold-start tolerance (p99 SLA under 500 ms). Best for workloads with predictable, sustained traffic that need low latency with zero cold starts. Managed Instances excels at CPU-bound workloads where JIT optimization compounds.&lt;/p&gt; 
&lt;p&gt;SnapStart works well for variable traffic patterns where cold-start reduction matters. Choose this as the default for Java Lambda functions. SnapStart reduces cold starts with minimal code changes (add CRaC priming). You have no additional infrastructure to manage. Works with the existing Lambda scaling model.&lt;/p&gt; 
&lt;p&gt;GraalVM Native Image works well for bursty traffic patterns with strict cold-start tolerance (sub-second cold starts required). Ideal if your team can invest in AOT compatibility (reflection configuration, build pipeline). This mode offers a smaller memory footprint. Requires testing for SDK compatibility.&lt;/p&gt; 
&lt;p&gt;Standard Lambda is the baseline for low-traffic or burst workloads where cold starts of 6-14 seconds are acceptable. Works well when invocation frequency is low enough that per-request billing is cheaper than fixed instance costs, or when operational simplicity is the top priority.&lt;/p&gt; 
&lt;p&gt;For example, if you run a Spring Boot API handling 100 requests per second with a 400 ms p99 SLA, Lambda Managed Instances reduces your p99 from 353 ms (cutting it close) to 225 ms (comfortable margin) and removes the multi-second cold start spikes that violate your SLA entirely.&lt;/p&gt; 
&lt;table border="1px" cellpadding="10px" width="100%"&gt; 
 &lt;tbody&gt;
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Dimension&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Standard&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;SnapStart&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Native&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;Managed Instances&lt;/strong&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Cold start&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;6-14 s&lt;/td&gt; 
   &lt;td&gt;2-7 s&lt;/td&gt; 
   &lt;td&gt;800 ms – 2 s&lt;/td&gt; 
   &lt;td&gt;None&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Warm p50 (CPU-bound)&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;139 ms&lt;/td&gt; 
   &lt;td&gt;127 ms&lt;/td&gt; 
   &lt;td&gt;107 ms&lt;/td&gt; 
   &lt;td&gt;97 ms&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Tail latency&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Worst&lt;/td&gt; 
   &lt;td&gt;Better&lt;/td&gt; 
   &lt;td&gt;Good&lt;/td&gt; 
   &lt;td&gt;Fastest&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Error rate&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Low&lt;/td&gt; 
   &lt;td&gt;Low&lt;/td&gt; 
   &lt;td&gt;Higher (SDK compat)&lt;/td&gt; 
   &lt;td&gt;Low&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Operational complexity&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Lowest&lt;/td&gt; 
   &lt;td&gt;Low&lt;/td&gt; 
   &lt;td&gt;High (build pipeline)&lt;/td&gt; 
   &lt;td&gt;Medium (VPC, sizing)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Burst scaling&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Fastest&lt;/td&gt; 
   &lt;td&gt;Fastest&lt;/td&gt; 
   &lt;td&gt;Fastest&lt;/td&gt; 
   &lt;td&gt;Slower (capacity provider)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Migration effort&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;None&lt;/td&gt; 
   &lt;td&gt;Low (add CRaC priming)&lt;/td&gt; 
   &lt;td&gt;High (AOT compat, reflection configuration)&lt;/td&gt; 
   &lt;td&gt;Medium (capacity provider, VPC, thread safety)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Memory efficiency&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;Good&lt;/td&gt; 
   &lt;td&gt;Good&lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;Lowest&lt;/p&gt; &lt;p&gt;(125-154 MB)&lt;/p&gt;&lt;/td&gt; 
   &lt;td&gt;Fixed per instance&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt;
&lt;/table&gt; 
&lt;p&gt;Lambda Managed Instances supports Graviton4 (arm64) instances, which offer approximately 20% better price-performance based on AWS published Graviton4 benchmarks. These benchmarks use x86_64 for consistency across all four modes (GraalVM native cross-compilation to arm64 adds complexity). The arm64 parallelization characteristics could shift the performance curves for longer-lived deployment modes like Managed Instances in ways worth exploring in a future post.&lt;/p&gt; 
&lt;h2 id="cost-considerations"&gt;Cost considerations&lt;/h2&gt; 
&lt;p&gt;Lambda Managed Instances uses instance-based pricing rather than per-invocation billing. For steady-state workloads above approximately 9 requests per second, the fixed instance cost is lower than equivalent Standard Lambda GB-second charges. You can use the official pricing calculator to compare Managed Instances and standard Lambda costs.&lt;/p&gt; 
&lt;h2 id="try-it-with-your-runtime-version"&gt;Try it with your runtime version&lt;/h2&gt; 
&lt;p&gt;These benchmarks use Java 25 with Spring Boot 4.0.6. The GitHub repository also includes configurations for Java 21 with Spring Boot 3.x. The repository README walks you through deployment, load testing, and collecting your own metrics.&lt;/p&gt; 
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt; 
&lt;p&gt;This post demonstrates how Lambda Managed Instances solves a fundamental Java-on-serverless mismatch. The JVM’s JIT compiler needs time to optimize hot code paths. Standard Lambda recycles environments before the JVM reaches peak optimization. Managed Instances keeps the JVM alive across invocations, allowing the C2 compiler to reach peak optimization. The benchmarks show the impact. In these benchmarks, Managed Instances delivered 18 to 30% faster p50 latency than Standard Lambda. Tail latency improved 27 to 41% at p99. Maximum response times dropped 3 to 30x on CPU-bound workloads. The 3.8x improvement from JIT optimization alone shows what’s possible when the runtime has time to complete its work.&lt;/p&gt; 
&lt;p&gt;For more information, refer to the Lambda Managed Instances documentation. The GitHub repository contains the complete benchmark code, SAM templates, and deployment instructions. Share your results in the comments and let the community know how Managed Instances performs on your workloads. To delete all benchmark resources and avoid ongoing charges, run the cleanup commands documented in the GitHub repository README.&lt;/p&gt;</content:encoded>
					
		
		
			</item>
	</channel>
</rss>