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

<channel>
	<title>theburningmonk.com</title>
	<atom:link href="https://theburningmonk.com/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Learn to build production-ready serverless applications on AWS</description>
	<lastBuildDate>Fri, 06 Feb 2026 01:57:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>

<image>
	<url>https://theburningmonk.com/wp-content/uploads/2018/03/favicon-150x150.png</url>
	<title>theburningmonk.com</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The anti-polling pattern for Step Functions</title>
		<link>https://theburningmonk.com/2026/02/the-anti-polling-pattern-for-step-functions/</link>
		
		<dc:creator><![CDATA[Yan Cui]]></dc:creator>
		<pubDate>Fri, 06 Feb 2026 01:36:17 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Step Functions]]></category>
		<category><![CDATA[Durable Function]]></category>
		<guid isPermaLink="false">https://theburningmonk.com/?p=15889</guid>

					<description><![CDATA[<p>Step Functions is often used to poll long-running processes, e.g. when starting a new data migration task with Amazon Database Migration.</p>
<p>There's usually a Wait -> Poll -> Choice loop that runs until the task is complete (or failed).</p>
<p>Polling is often the default solution because it’s easy, not because it’s good.</p>
<p>If you can get an event (or a callback), you can stop spinning your state machine and start treating "waiting" as a first-class step. Less noise, fewer transitions, lower cost.</p>
<p>The post <a href="https://theburningmonk.com/2026/02/the-anti-polling-pattern-for-step-functions/">The anti-polling pattern for Step Functions</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">Step Functions is often used to poll long-running processes, e.g. when starting a new data migration task with Amazon Database Migration.</span></p>
<p class="ck-paragraph" data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlN0ZXAlMjBGdW5jdGlvbnMlMjBpcyUyMG9mdGVuJTIwdXNlZCUyMHRvJTIwcG9sbCUyMGxvbmctcnVubmluZyUyMHByb2Nlc3NlcyUyQyUyMGUuZy4lMjB3aGVuJTIwc3RhcnRpbmclMjBhJTIwbmV3JTIwZGF0YSUyMG1pZ3JhdGlvbiUyMHRhc2slMjB3aXRoJTIwQW1hem9uJTIwRGF0YWJhc2UlMjBNaWdyYXRpb24uJTIyJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlRoZXJlJ3MlMjB1c3VhbGx5JTIwYSUyMFdhaXQlMjAtJTNFJTIwUG9sbCUyMC0lM0UlMjBDaG9pY2UlMjBsb29wJTIwdGhhdCUyMHJ1bnMlMjB1bnRpbCUyMHRoZSUyMHRhc2slMjBpcyUyMGNvbXBsZXRlJTIwKG9yJTIwZmFpbGVkKSUyQyUyMGxpa2UlMjB0aGUlMjBvbmUlMjBiZWxvdy4lMjIlN0QlNUQlN0QlNUQlN0QlNUQ="><span data-slate-node="text">There&#8217;s usually a Wait -&gt; Poll -&gt; Choice loop that runs until the task is complete (or failed), like the one below.</span></p>
<p id="HTXKpoV"><img fetchpriority="high" decoding="async" class="alignnone wp-image-15890" src="https://theburningmonk.com/wp-content/uploads/2026/02/img_698544e3e4bcf.png" alt="" width="500" height="550" srcset="https://theburningmonk.com/wp-content/uploads/2026/02/img_698544e3e4bcf.png 828w, https://theburningmonk.com/wp-content/uploads/2026/02/img_698544e3e4bcf-273x300.png 273w, https://theburningmonk.com/wp-content/uploads/2026/02/img_698544e3e4bcf-779x856.png 779w" sizes="(max-width: 500px) 100vw, 500px" /></p>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">Polling is inefficient and can add unnecessary cost as standard workflows are charged based on the number of state transitions.</span></p>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">There is an event-driven alternative to this approach.</span></p>
<p class="ck-paragraph" data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlBvbGxpbmclMjBpcyUyMGluZWZmaWNpZW50JTIwYW5kJTIwY2FuJTIwYWRkJTIwdW5uZWNlc3NhcnklMjBjb3N0JTIwYXMlMjBzdGFuZGFyZCUyMHdvcmtmbG93cyUyMGFyZSUyMGNoYXJnZWQlMjBiYXNlZCUyMG9uJTIwdGhlJTIwbnVtYmVyJTIwb2YlMjBzdGF0ZSUyMHRyYW5zaXRpb25zLiUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGVyZSUyMGlzJTIwYW4lMjBldmVudC1kcml2ZW4lMjBhbHRlcm5hdGl2ZSUyMHRvJTIwdGhpcyUyMGFwcHJvYWNoLiUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJIZXJlJ3MlMjB0aGUlMjBoaWdoJTIwbGV2ZWwlMjBhcHByb2FjaCUzQSUyMiU3RCU1RCU3RCU1RCU3RCU1RA=="><span data-slate-node="text">Here&#8217;s the high level approach:</span></p>
<p id="NukwqQy"><img decoding="async" class="alignnone wp-image-15891" src="https://theburningmonk.com/wp-content/uploads/2026/02/img_698544ff0c2cd.png" alt="" width="700" height="426" srcset="https://theburningmonk.com/wp-content/uploads/2026/02/img_698544ff0c2cd.png 1024w, https://theburningmonk.com/wp-content/uploads/2026/02/img_698544ff0c2cd-300x183.png 300w, https://theburningmonk.com/wp-content/uploads/2026/02/img_698544ff0c2cd-779x474.png 779w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<ol class="ck-ordered-list" data-slate-node="element">
<li data-slate-node="element"><span data-slate-node="element">To start the data migration, the state machine calls a Lambda function with a task token (required for callback). This pauses the state machine execution.</span></li>
<li data-slate-node="element"><span data-slate-node="element">The Lambda function calls the Database Migration service to start the data migration.</span></li>
<li data-slate-node="element"><span data-slate-node="element">The function saves the data migration ARN (hash key) and the callback token in DynamoDB, along with other relevant information (created date, etc.)</span></li>
<li data-slate-node="element"><span data-slate-node="element">The Database Migration service publishes &#8220;StateChange&#8221; events to the default EventBridge event bus (see docs <a class="ck-link" href="https://docs.aws.amazon.com/dms/latest/userguide/CHAP_EventBridge.html" target="_blank" rel="noopener" data-slate-node="element" data-slate-inline="true">here</a>). A Lambda function subscribes to this event and waits for a replication task to finish or fail.</span></li>
<li data-slate-node="element"><span data-slate-node="element">When triggered, the function extracts the data migration ARN from the event payload and retrieves the Step Functions task token from DynamoDB.</span></li>
<li data-slate-node="element"><span data-slate-node="element">It can use the task token to send a success or failure signal back to the state machine execution. From here, the state machine can proceed with the rest of its steps.</span></li>
</ol>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">This is a more efficient but also more complex approach. There are more moving parts involved, but it&#8217;s simple to implement.</span></p>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">But what if you&#8217;re calling a 3rd party API that do not support events?</span></p>
<p class="ck-paragraph" data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMm9yZGVyZWQtbGlzdCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbSUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbS1jaGlsZCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlRvJTIwc3RhcnQlMjB0aGUlMjBkYXRhJTIwbWlncmF0aW9uJTJDJTIwdGhlJTIwc3RhdGUlMjBtYWNoaW5lJTIwY2FsbHMlMjBhJTIwTGFtYmRhJTIwZnVuY3Rpb24lMjB3aXRoJTIwYSUyMHRhc2slMjB0b2tlbiUyMChyZXF1aXJlZCUyMGZvciUyMGNhbGxiYWNrKS4lMjBUaGlzJTIwcGF1c2VzJTIwdGhlJTIwc3RhdGUlMjBtYWNoaW5lJTIwZXhlY3V0aW9uLiUyMiU3RCU1RCU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJsaXN0LWl0ZW0lMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnR5cGUlMjIlM0ElMjJsaXN0LWl0ZW0tY2hpbGQlMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGUlMjBMYW1iZGElMjBmdW5jdGlvbiUyMGNhbGxzJTIwdGhlJTIwRGF0YWJhc2UlMjBNaWdyYXRpb24lMjBzZXJ2aWNlJTIwdG8lMjBzdGFydCUyMHRoZSUyMGRhdGElMjBtaWdyYXRpb24uJTIyJTdEJTVEJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbSUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbS1jaGlsZCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlRoZSUyMGZ1bmN0aW9uJTIwc2F2ZXMlMjB0aGUlMjBkYXRhJTIwbWlncmF0aW9uJTIwQVJOJTIwKGhhc2glMjBrZXkpJTIwYW5kJTIwdGhlJTIwY2FsbGJhY2slMjB0b2tlbiUyMGluJTIwRHluYW1vREIlMkMlMjBhbG9uZyUyMHdpdGglMjBvdGhlciUyMHJlbGV2YW50JTIwaW5mb3JtYXRpb24lMjAoY3JlYXRlZCUyMGRhdGUlMkMlMjBldGMuKSUyMiU3RCU1RCU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJsaXN0LWl0ZW0lMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnR5cGUlMjIlM0ElMjJsaXN0LWl0ZW0tY2hpbGQlMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGUlMjBEYXRhYmFzZSUyME1pZ3JhdGlvbiUyMHNlcnZpY2UlMjBwdWJsaXNoZXMlMjAlNUMlMjJTdGF0ZUNoYW5nZSU1QyUyMiUyMGV2ZW50cyUyMHRvJTIwdGhlJTIwZGVmYXVsdCUyMEV2ZW50QnJpZGdlJTIwZXZlbnQlMjBidXMlMjAoc2VlJTIwZG9jcyUyMCUyMiU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJsaW5rJTIyJTJDJTIyaHJlZiUyMiUzQSUyMmh0dHBzJTNBJTJGJTJGZG9jcy5hd3MuYW1hem9uLmNvbSUyRmRtcyUyRmxhdGVzdCUyRnVzZXJndWlkZSUyRkNIQVBfRXZlbnRCcmlkZ2UuaHRtbCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMmhlcmUlMjIlN0QlNUQlN0QlMkMlN0IlMjJ0ZXh0JTIyJTNBJTIyKS4lMjBBJTIwTGFtYmRhJTIwZnVuY3Rpb24lMjBzdWJzY3JpYmVzJTIwdG8lMjB0aGlzJTIwZXZlbnQlMjBhbmQlMjB3YWl0cyUyMGZvciUyMGElMjByZXBsaWNhdGlvbiUyMHRhc2slMjB0byUyMGZpbmlzaCUyMG9yJTIwZmFpbC4lMjIlN0QlNUQlN0QlNUQlN0QlMkMlN0IlMjJ0eXBlJTIyJTNBJTIybGlzdC1pdGVtJTIyJTJDJTIyY2hpbGRyZW4lMjIlM0ElNUIlN0IlMjJ0eXBlJTIyJTNBJTIybGlzdC1pdGVtLWNoaWxkJTIyJTJDJTIyY2hpbGRyZW4lMjIlM0ElNUIlN0IlMjJ0ZXh0JTIyJTNBJTIyV2hlbiUyMHRyaWdnZXJlZCUyQyUyMHRoZSUyMGZ1bmN0aW9uJTIwZXh0cmFjdHMlMjB0aGUlMjBkYXRhJTIwbWlncmF0aW9uJTIwQVJOJTIwZnJvbSUyMHRoZSUyMGV2ZW50JTIwcGF5bG9hZCUyMGFuZCUyMHJldHJpZXZlcyUyMHRoZSUyMFN0ZXAlMjBGdW5jdGlvbnMlMjB0YXNrJTIwdG9rZW4lMjBmcm9tJTIwRHluYW1vREIuJTIyJTdEJTVEJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbSUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMmxpc3QtaXRlbS1jaGlsZCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMkl0JTIwY2FuJTIwdXNlJTIwdGhlJTIwdGFzayUyMHRva2VuJTIwdG8lMjBzZW5kJTIwYSUyMHN1Y2Nlc3MlMjBvciUyMGZhaWx1cmUlMjBzaWduYWwlMjBiYWNrJTIwdG8lMjB0aGUlMjBzdGF0ZSUyMG1hY2hpbmUlMjBleGVjdXRpb24uJTIwRnJvbSUyMGhlcmUlMkMlMjB0aGUlMjBzdGF0ZSUyMG1hY2hpbmUlMjBjYW4lMjBwcm9jZWVkJTIwd2l0aCUyMHRoZSUyMHJlc3QlMjBvZiUyMGl0cyUyMHN0ZXBzLiUyMiU3RCU1RCU3RCU1RCU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGlzJTIwaXMlMjBhJTIwbW9yZSUyMGVmZmljaWVudCUyMGJ1dCUyMGFsc28lMjBtb3JlJTIwY29tcGxleCUyMGFwcHJvYWNoLiUyMFRoZXJlJTIwYXJlJTIwbW9yZSUyMG1vdmluZyUyMHBhcnRzJTIwaW52b2x2ZWQlMkMlMjBidXQlMjBpdCdzJTIwc2ltcGxlJTIwdG8lMjBpbXBsZW1lbnQuJTIyJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMkJ1dCUyMHdoYXQlMjBpZiUyMHlvdSdyZSUyMGNhbGxpbmclMjBhJTIwM3JkJTIwcGFydHklMjBBUEklMjB0aGF0JTIwZG8lMjBub3QlMjBzdXBwb3J0JTIwZXZlbnRzJTNGJTIyJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMllvdSUyMGNhbiUyMGFkYXB0JTIwdGhpcyUyMGFwcHJvYWNoJTIwdG8lMjB3b3JrJTIwd2l0aCUyMGFueSUyMHNlcnZpY2UlMjB0aGF0JTIwYWNjZXB0JTIwYSUyMGNhbGxiYWNrJTIwVVJMLiUyMFdoZW4lMjB0aGUlMjAzcmQlMjBwYXJ0eSUyMHNlcnZpY2UlMjBtYWtlcyUyMHRoZSUyMGNhbGxiYWNrJTJDJTIweW91ciUyMEFQSSUyMGhhbmRsZXIlMjB3aWxsJTIwbG9vayUyMHVwJTIwdGhlJTIwdGFzayUyMHRva2VuJTIwYW5kJTIwbWFrZSUyMHRoZSUyMGNhbGxiYWNrJTIwdG8lMjBTdGVwJTIwRnVuY3Rpb25zLiUyMEV2ZXJ5dGhpbmclMjBlbHNlJTIwc3RheXMlMjB0aGUlMjBzYW1lJTIwYXMlMjBiZWZvcmUuJTIyJTdEJTVEJTdEJTVEJTdEJTVE"><span data-slate-node="text">You can adapt this approach to work with any service that accept a callback URL. When the 3rd party service makes the callback, your API handler will look up the task token and make the callback to Step Functions. Everything else stays the same as before.</span></p>
<p id="dpGEYqv"><img decoding="async" class="alignnone wp-image-15892" src="https://theburningmonk.com/wp-content/uploads/2026/02/img_6985452041aad.png" alt="" width="700" height="418" srcset="https://theburningmonk.com/wp-content/uploads/2026/02/img_6985452041aad.png 1024w, https://theburningmonk.com/wp-content/uploads/2026/02/img_6985452041aad-300x179.png 300w, https://theburningmonk.com/wp-content/uploads/2026/02/img_6985452041aad-779x466.png 779w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">What&#8217;s more, both the polling and event-driven approach can be implemented with the new Lambda Durable Functions too!</span></p>
<p class="ck-paragraph" data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMldoYXQncyUyMG1vcmUlMkMlMjBib3RoJTIwdGhlJTIwcG9sbGluZyUyMGFuZCUyMGV2ZW50LWRyaXZlbiUyMGFwcHJvYWNoJTIwY2FuJTIwYmUlMjBpbXBsZW1lbnRlZCUyMHdpdGglMjB0aGUlMjBuZXclMjBMYW1iZGElMjBEdXJhYmxlJTIwRnVuY3Rpb25zJTIwdG9vISUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGUlMjAlMjIlN0QlMkMlN0IlMjJib2xkJTIyJTNBdHJ1ZSUyQyUyMnRleHQlMjIlM0ElMjJ3YWl0Rm9yQ29uZGl0aW9uJTIyJTdEJTJDJTdCJTIydGV4dCUyMiUzQSUyMiUyMG9wZXJhdGlvbiUyMGlzJTIwcGVyZmVjdCUyMGZvciUyMGltcGxlbWVudGluZyUyMHRoZSUyMHBvbGxpbmclMjBsb29wJTIwaW4lMjBqdXN0JTIwYSUyMGZldyUyMGxpbmVzJTJDJTIwbGlrZSUyMHRoaXMlM0ElMjIlN0QlNUQlN0QlNUQlN0QlNUQ="><span data-slate-node="text">The </span><span data-slate-node="text"><strong data-slate-leaf="true">waitForCondition</strong></span><span data-slate-node="text"> operation is perfect for implementing the polling loop in just a few lines, like this:</span></p>
<pre class="graf graf--pre graf--preV2" spellcheck="false" data-code-block-mode="2" data-code-block-lang="javascript"><span class="pre--content"><span class="hljs-keyword">const</span> job = <span class="hljs-keyword">await</span> <span class="hljs-title function_">startDataMigrationJob</span>();

<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> context.<span class="hljs-title function_">waitForCondition</span>(
  <span class="hljs-keyword">async</span> (job, ctx) =&gt; {
    <span class="hljs-keyword">const</span> status = <span class="hljs-keyword">await</span> <span class="hljs-title function_">checkJobStatus</span>(job.<span class="hljs-property">arn</span>);
    <span class="hljs-keyword">return</span> { ...job, status };
  },
  {
    <span class="hljs-attr">initialState</span>: { job, <span class="hljs-attr">status</span>: <span class="hljs-literal">null</span> },
    <span class="hljs-attr">waitStrategy</span>: <span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> 
      state.<span class="hljs-property">status</span> === <span class="hljs-string">'Stopped'</span> || state.<span class="hljs-property">status</span> === <span class="hljs-string">'Failed'</span> 
        ? { <span class="hljs-attr">shouldContinue</span>: <span class="hljs-literal">false</span> }
        : { <span class="hljs-attr">shouldContinue</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">delay</span>: { <span class="hljs-attr">seconds</span>: <span class="hljs-number">30</span> } }
  }
);</span></pre>
<p data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMldoYXQncyUyMG1vcmUlMkMlMjBib3RoJTIwdGhlJTIwcG9sbGluZyUyMGFuZCUyMGV2ZW50LWRyaXZlbiUyMGFwcHJvYWNoJTIwY2FuJTIwYmUlMjBpbXBsZW1lbnRlZCUyMHdpdGglMjB0aGUlMjBuZXclMjBMYW1iZGElMjBEdXJhYmxlJTIwRnVuY3Rpb25zJTIwdG9vISUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJUaGUlMjAlMjIlN0QlMkMlN0IlMjJib2xkJTIyJTNBdHJ1ZSUyQyUyMnRleHQlMjIlM0ElMjJ3YWl0Rm9yQ29uZGl0aW9uJTIyJTdEJTJDJTdCJTIydGV4dCUyMiUzQSUyMiUyMG9wZXJhdGlvbiUyMGlzJTIwcGVyZmVjdCUyMGZvciUyMGltcGxlbWVudGluZyUyMHRoZSUyMHBvbGxpbmclMjBsb29wJTIwaW4lMjBqdXN0JTIwYSUyMGZldyUyMGxpbmVzJTJDJTIwbGlrZSUyMHRoaXMlM0ElMjIlN0QlNUQlN0QlNUQlN0QlNUQ="><span data-slate-node="text">Similarly, the </span><span data-slate-node="text"><strong data-slate-leaf="true">waitForCallback</strong></span><span data-slate-node="text" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlNpbWlsYXJseSUyQyUyMHRoZSUyMCUyMiU3RCUyQyU3QiUyMmJvbGQlMjIlM0F0cnVlJTJDJTIydGV4dCUyMiUzQSUyMndhaXRGb3JDYWxsYmFjayUyMiU3RCUyQyU3QiUyMnRleHQlMjIlM0ElMjIlMjBvcGVyYXRpb24lMjBtYWtlcyUyMGltcGxlbWVudGluZyUyMHRoZSUyMGV2ZW50LWRyaXZlbiUyMGFwcHJvYWNoJTIwdHJpdmlhbC4lMjBJbnN0ZWFkJTIwb2YlMjBhJTIwdGFzayUyMHRva2VuJTJDJTIwd2UlMjBoYXZlJTIwdG8lMjBzdG9yZSUyMGElMjBjYWxsYmFjayUyMElELiUyMEFzJTIwYmVmb3JlJTJDJTIwdGhlJTIwY2FsbGJhY2slMjBjYW4lMjBiZSUyMHRyaWdnZXJlZCUyMGJ5JTIwYW4lMjBldmVudCUyMG9yJTIwYnklMjBhJTIwM3JkJTIwcGFydHklMjBzZXJ2aWNlJTIwdmlhJTIwYSUyMGNhbGxiYWNrJTIwVVJMLiUyMiU3RCU1RCU3RCU1RCU3RCU1RA=="> operation makes implementing the event-driven approach trivial. Instead of a task token, we have to store a callback ID. As before, the callback can be triggered by an event or by a 3rd party service via a callback URL.</span></p>
<pre class="graf graf--pre">const job = await startDataMigrationJob();

const result = await context.waitForCallback(
  "wait for data migration to finish",
  async (callbackId, ctx) =&gt; {
    // save the callback ID against job ARN
    await saveJobDetails(job.arn, callbackId)

    // when the StateChange event is fired
    // another function will fetch the callback ID
    // and send a success/failure signal to the
    // durable execution
  }
);</pre>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">Polling is the default because it’s easy, not because it’s good.</span></p>
<p class="ck-paragraph" data-slate-node="element"><span data-slate-node="text">If you can get an event (or a callback), you can stop spinning your state machine and start treating &#8220;waiting&#8221; as a first-class step. Less noise, fewer transitions, lower cost.</span></p>
<p class="ck-paragraph" data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlBvbGxpbmclMjBpcyUyMHRoZSUyMGRlZmF1bHQlMjBiZWNhdXNlJTIwaXQlRTIlODAlOTlzJTIwZWFzeSUyQyUyMG5vdCUyMGJlY2F1c2UlMjBpdCVFMiU4MCU5OXMlMjBnb29kLiUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJJZiUyMHlvdSUyMGNhbiUyMGdldCUyMGFuJTIwZXZlbnQlMjAob3IlMjBhJTIwY2FsbGJhY2spJTJDJTIweW91JTIwY2FuJTIwc3RvcCUyMHNwaW5uaW5nJTIweW91ciUyMHN0YXRlJTIwbWFjaGluZSUyMGFuZCUyMHN0YXJ0JTIwdHJlYXRpbmclMjAlNUMlMjJ3YWl0aW5nJTVDJTIyJTIwYXMlMjBhJTIwZmlyc3QtY2xhc3MlMjBzdGVwLiUyMExlc3MlMjBub2lzZSUyQyUyMGZld2VyJTIwdHJhbnNpdGlvbnMlMkMlMjBsb3dlciUyMGNvc3QuJTIyJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlRoYW5rJTIweW91JTIwdG8lMjBQYXRyaWNrJTIwZm9yJTIwYnJpbmdpbmclMjB0aGlzJTIwdXAlMjBpbiUyMG91ciUyMGxhc3QlMjBRJTI2QSUyMHNlc3Npb24uJTIwSWYlMjB5b3UlMjB3YW50JTIwdG8lMjBsZXZlbCUyMHVwJTIweW91ciUyMEFXUyUyMGdhbWUlMkMlMjBjaGVjayUyMG91dCUyMG15JTIwJTIyJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmxpbmslMjIlMkMlMjJocmVmJTIyJTNBJTIyaHR0cHMlM0ElMkYlMkZwcm9kdWN0aW9ucmVhZHlzZXJ2ZXJsZXNzLmNvbSUyRiUzRnV0bV9jYW1wYWlnbiUzRHBvbGxpbmctdG8tZXZlbnQtZHJpdmVuJTI2dXRtX3NvdXJjZSUzRG5ld3NsZXR0ZXIlMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJQcm9kdWN0aW9uLVJlYWR5JTIwU2VydmVybGVzcyUyMHdvcmtzaG9wJTIyJTdEJTVEJTdEJTJDJTdCJTIydGV4dCUyMiUzQSUyMi4lMjBUaGUlMjBuZXh0JTIwY29ob3J0JTIwc3RhcnRzJTIwb24lMjBBcHJpbCUyMDEzdGglMkMlMjBhbmQlMjB0aGUlMjBlYXJseSUyMGJpcmQlMjB0aWNrZXRzJTIwKDMwJTI1JTIwb2ZmKSUyMGlzJTIwYXZhaWxhYmxlJTIwdW50aWwlMjBNYXJjaCUyMDE2dGguJTIyJTdEJTVEJTdEJTVEJTdEJTVE"><span data-slate-node="text">Thank you to Patrick for bringing this up in our last Q&amp;A session. If you want to level up your AWS game, check out my </span><a class="ck-link" href="https://productionreadyserverless.com/?utm_campaign=polling-to-event-driven&amp;utm_source=blog" target="_blank" rel="noopener" data-slate-node="element" data-slate-inline="true"><span data-slate-node="text">Production-Ready Serverless workshop</span></a><span data-slate-node="text">. The next cohort starts on April 13th, and the early bird tickets (30% off) is available until March 16th.</span></p>
<p data-slate-node="element" data-slate-fragment="JTVCJTdCJTIydHlwZSUyMiUzQSUyMmRvY3VtZW50JTIyJTJDJTIydGhlbWUlMjIlM0ElN0IlMjJkb2N1bWVudCUyMiUzQSU3QiUyMmJhY2tncm91bmRDb2xvciUyMiUzQSUyMiUyM0ZGRkZGRiUyMiU3RCU3RCUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlBvbGxpbmclMjBpcyUyMHRoZSUyMGRlZmF1bHQlMjBiZWNhdXNlJTIwaXQlRTIlODAlOTlzJTIwZWFzeSUyQyUyMG5vdCUyMGJlY2F1c2UlMjBpdCVFMiU4MCU5OXMlMjBnb29kLiUyMiU3RCU1RCU3RCUyQyU3QiUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJJZiUyMHlvdSUyMGNhbiUyMGdldCUyMGFuJTIwZXZlbnQlMjAob3IlMjBhJTIwY2FsbGJhY2spJTJDJTIweW91JTIwY2FuJTIwc3RvcCUyMHNwaW5uaW5nJTIweW91ciUyMHN0YXRlJTIwbWFjaGluZSUyMGFuZCUyMHN0YXJ0JTIwdHJlYXRpbmclMjAlNUMlMjJ3YWl0aW5nJTVDJTIyJTIwYXMlMjBhJTIwZmlyc3QtY2xhc3MlMjBzdGVwLiUyMExlc3MlMjBub2lzZSUyQyUyMGZld2VyJTIwdHJhbnNpdGlvbnMlMkMlMjBsb3dlciUyMGNvc3QuJTIyJTdEJTVEJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMlRoYW5rJTIweW91JTIwdG8lMjBQYXRyaWNrJTIwZm9yJTIwYnJpbmdpbmclMjB0aGlzJTIwdXAlMjBpbiUyMG91ciUyMGxhc3QlMjBRJTI2QSUyMHNlc3Npb24uJTIwSWYlMjB5b3UlMjB3YW50JTIwdG8lMjBsZXZlbCUyMHVwJTIweW91ciUyMEFXUyUyMGdhbWUlMkMlMjBjaGVjayUyMG91dCUyMG15JTIwJTIyJTdEJTJDJTdCJTIydHlwZSUyMiUzQSUyMmxpbmslMjIlMkMlMjJocmVmJTIyJTNBJTIyaHR0cHMlM0ElMkYlMkZwcm9kdWN0aW9ucmVhZHlzZXJ2ZXJsZXNzLmNvbSUyRiUzRnV0bV9jYW1wYWlnbiUzRHBvbGxpbmctdG8tZXZlbnQtZHJpdmVuJTI2dXRtX3NvdXJjZSUzRG5ld3NsZXR0ZXIlMjIlMkMlMjJjaGlsZHJlbiUyMiUzQSU1QiU3QiUyMnRleHQlMjIlM0ElMjJQcm9kdWN0aW9uLVJlYWR5JTIwU2VydmVybGVzcyUyMHdvcmtzaG9wJTIyJTdEJTVEJTdEJTJDJTdCJTIydGV4dCUyMiUzQSUyMi4lMjBUaGUlMjBuZXh0JTIwY29ob3J0JTIwc3RhcnRzJTIwb24lMjBBcHJpbCUyMDEzdGglMkMlMjBhbmQlMjB0aGUlMjBlYXJseSUyMGJpcmQlMjB0aWNrZXRzJTIwKDMwJTI1JTIwb2ZmKSUyMGlzJTIwYXZhaWxhYmxlJTIwdW50aWwlMjBNYXJjaCUyMDE2dGguJTIyJTdEJTVEJTdEJTVEJTdEJTVE"><h3 class="crp-list-title">Related Posts</h3><div class="crp-list"><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/">The biggest re:Invent 2025 serverless announcements</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2024/08/whats-the-best-way-to-do-fan-out-fan-in-serverlessly-in-2024/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2024/08/fanout-fanin-serverlessly-2024-feature-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2024/08/fanout-fanin-serverlessly-2024-feature-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2024/08/fanout-fanin-serverlessly-2024-feature-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2024/08/fanout-fanin-serverlessly-2024-feature.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2024/08/whats-the-best-way-to-do-fan-out-fan-in-serverlessly-in-2024/">What's the best way to do fan-out/fan-in serverlessly in 2024?</a></div></div></div></p>
<p>The post <a href="https://theburningmonk.com/2026/02/the-anti-polling-pattern-for-step-functions/">The anti-polling pattern for Step Functions</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The biggest re:Invent 2025 serverless announcements</title>
		<link>https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/</link>
		
		<dc:creator><![CDATA[Yan Cui]]></dc:creator>
		<pubDate>Mon, 08 Dec 2025 17:15:26 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Lambda]]></category>
		<guid isPermaLink="false">https://theburningmonk.com/?p=15872</guid>

					<description><![CDATA[<p>Here are the biggest serverless announcements at re:Invent 2025.</p>
<p>The post <a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/">The biggest re:Invent 2025 serverless announcements</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Two weeks ago, I gave you the biggest serverless announcements pre-re:Invent (see <a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/" target="_blank" rel="noopener">here</a>). So here are the biggest serverless announcements during re:Invent 2025.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda Managed Instances</h3>
<p><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/introducing-aws-lambda-managed-instances-serverless-simplicity-with-ec2-flexibility/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/">Here’s the official announcement</a>.</p>
<p>A common pushback against Lambda is that &#8220;it&#8217;s expensive at scale&#8221; because:</p>
<p>1) Each execution environment can only process one request at a time, wasting available CPU cycles while you wait for IO response.</p>
<p>2) Paying for execution time is less efficient when handling thousands of requests per second, especially given the above.</p>
<p>Lambda Managed Instances address these concerns.</p>
<p>You keep the same programming model with Lambda and the same event triggers.</p>
<p>But instead of your function running in a shared pool of bare metal EC2 instances, you can now instruct AWS to use EC2 instances from your account instead. Importantly, <strong>AWS still manages these EC2 instances for you, including OS patching, load balancing and auto-scaling.</strong></p>
<p>It gives you more control and flexibility, e.g. what instance types to use (but no GPU instances) and the memory-to-CPU ratio.</p>
<p>See <a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/" target="_blank" rel="noopener">this post</a> for my more in-depth coverage of this new feature.</p>
<p>&nbsp;</p>
<h3>Lambda Durable Functions</h3>
<p><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/build-multi-step-applications-and-ai-workflows-with-aws-lambda-durable-functions/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/">Here’s the official announcement</a>.</p>
<p>This is my favourite announce from re:Invent 2025 :-)</p>
<p>Lambda Durable Functions use a replay mechanism similar to <a href="https://www.youtube.com/watch?v=5n84BypaeV8" target="_blank" rel="noopener">how reState works</a> and how I implemented <a href="https://theburningmonk.com/2025/03/how-to-implement-durable-execution-for-lambda-without-frameworks/" target="_blank" rel="noopener">durable execution on Lambda for a client project</a>.</p>
<p>The basic idea is simple &#8211; you can add checkpoints along the execution and the Lambda service will re-invoke your function from the start and skip over previously executed checkpoints when:</p>
<ul>
<li>The initial invocation timed out.</li>
<li>You called <em>context.wait</em> to pause the current invocation.</li>
<li>You used <em>context.invoke</em> to invoke another function and wait for its response (which suspends the current invocation).</li>
<li>You created a callback and awaiting its response.</li>
</ul>
<p>Here&#8217;s a handy visualization from the <a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener">official documentation</a>.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-15873" src="https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works.png" alt="" width="700" height="680" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works-300x292.png 300w, https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works-779x757.png 779w, https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works-1536x1493.png 1536w, https://theburningmonk.com/wp-content/uploads/2025/12/how_durable_works-2048x1990.png 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p><em>(source: <a href="https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" target="_blank" rel="noopener">https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html</a>)</em></p>
<p>In addition to the usual Lambda function timeout (max 15 mins), Durable Functions also have a &#8220;execution timeout&#8221; for the total duration of a durable execution which can span over multiple invocations. The <strong>max execution timeout is 1 year</strong>.</p>
<p>Durable functions can be invoked both synchronously and asynchronously.</p>
<p>However, for synchronous invocations, the max execution timeout is limited to 15 mins. Whereas asynchronous invocations can have execution timeout of up to 1 year.</p>
<p><strong>Durable functions also work with all event source mappings</strong>. But ESM-triggered invocations are also limited to a max execution duration of 15 mins.</p>
<p>Additionally, Durable Functions support DLQs, but they <strong>DO NOT support Lambda destinations</strong>.</p>
<p>Similar to Step Functions, Durable Functions also supports exactly-once processing, if you provide an &#8220;DurableExecutionName&#8221; when invoking a durable function.</p>
<p>Durable Functions blur the line between Lambda and Step Functions. I&#8217;m still organizing my thoughts on how to choose between them, but off the top of my head, these are areas where I think Step Functions wins over Lambda Durable Functions:</p>
<ul>
<li>Visualization: being able to design and visualize the workflow as well as its executions. This is especially useful when working with non-technical stakeholders.</li>
<li>Parallel processing: the <em>context.parallel</em> function of the Durable execution SDK does not actually guarantee parallel processing. In Node.js, it&#8217;s essentially a wrapper around <em>promise.all</em>, which gives you concurrency, not parallelism. So if you need to process large amounts of data in parallel, e.g. as part of a map-reduce task, then you want Step Function&#8217;s Parallel state.</li>
</ul>
<p>The replay mechanic also has some interesting failure modes and gotchas. More on that in another post! Or, you can learn all about them in my next <a class="ck-link" href="https://productionreadyserverless.com/?utm_campaign=biggest-serverless-reinvent&amp;utm_source=blog" target="_blank" rel="noopener noreferrer">Production-Ready Serverless</a> workshop ;-)</p>
<p>&nbsp;</p>
<h3>S3 Vectors goes GA with better scale and performance</h3>
<p><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/amazon-s3-vectors-now-generally-available-with-increased-scale-and-performance/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/">Here’s the official announcement</a>.</p>
<p>&nbsp;</p>
<h3>S3 Tables support intelligent-tiering and replication</h3>
<p><a href="https://aws.amazon.com/blogs/aws/announcing-replication-support-and-intelligent-tiering-for-amazon-s3-tables/" target="_blank" rel="noopener">Here&#8217;s the official announcement</a>.</p>
<p>&nbsp;</p>
<h3>CloudFront supports mutual TLS authentication</h3>
<p><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/11/amazon-cloudfront-mutual-tls-authentication/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/">Here’s the official announcement</a>.</p>
<p>&nbsp;</p>
<p>And a lot of AI-related announcements, such as Nova 2 models.</p>
<h3 class="crp-list-title">Related Posts</h3><div class="crp-list"><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/">The biggest pre:invent serverless announcements you may have missed</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/">What you need to know about Lambda Managed Instances</a></div></div></div>
<p>The post <a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/">The biggest re:Invent 2025 serverless announcements</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What you need to know about Lambda Managed Instances</title>
		<link>https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/</link>
		
		<dc:creator><![CDATA[Yan Cui]]></dc:creator>
		<pubDate>Mon, 08 Dec 2025 13:34:10 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Serverless]]></category>
		<guid isPermaLink="false">https://theburningmonk.com/?p=15858</guid>

					<description><![CDATA[<p>In this post, let's take a deep dive into Lambda Managed Instances, and understand<br />
* Why you should care<br />
* Important considerations<br />
* When to use it</p>
<p>The post <a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/">What you need to know about Lambda Managed Instances</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Like London buses, we&#8217;ve waited years for true innovations to the Lambda platform and two came at the same time!</p>
<ul class="unordered_list">
<li class="list_item"><a class="ck-link" href="https://aws.amazon.com/blogs/aws/introducing-aws-lambda-managed-instances-serverless-simplicity-with-ec2-flexibility/" target="_blank" rel="noopener noreferrer">Lambda Managed Instances</a></li>
<li class="list_item"><a class="ck-link" href="https://aws.amazon.com/blogs/aws/build-multi-step-applications-and-ai-workflows-with-aws-lambda-durable-functions/" target="_blank" rel="noopener noreferrer">Lambda Durable Functions</a></li>
</ul>
<p>I will be updating the <a class="ck-link" href="https://productionreadyserverless.com/?utm_campaign=lambda-innovations&amp;utm_source=blog" target="_blank" rel="noopener noreferrer">Production-Ready Serverless</a> workshop to cover these new features in the January cohort.</p>
<p>In this post, let&#8217;s take a closer look at Lambda Managed Instances, why you should care and when to use it.</p>
<h3>Introducing Lambda Managed Instances</h3>
<p>A common pushback against Lambda is that &#8220;it&#8217;s expensive at scale&#8221; because:</p>
<p>1) Each execution environment can only process one request at a time, wasting available CPU cycles while you wait for IO response.</p>
<p>2) Paying for execution time is less efficient when handling thousands of requests per second, especially given the above.</p>
<p>Lambda Managed Instances address these concerns.</p>
<p>You keep the same programming model with Lambda and the same event triggers.</p>
<p>But instead of your function running in a shared pool of bare metal EC2 instances, you can now instruct AWS to use EC2 instances from your account instead.</p>
<p><strong>Importantly, AWS still manages these EC2 instances for you, including OS patching, load balancing and auto-scaling.</strong></p>
<p>With managed instances, you have more control over HOW the Lambda service should manage these EC2 instances.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-15859" src="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-01.png" alt="" width="700" height="771" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-01.png 929w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-01-272x300.png 272w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-01-779x859.png 779w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>For example, what CPU architecture and instance types to use.</p>
<p>You can choose specific instance types that works best for your workload, and <strong>use EC2 saving plans on these instances</strong>.</p>
<p><em>Note:<strong> GPU instances are NOT supported</strong>.</em></p>
<p>Similarly, you can let Lambda choose the scaling threshold or provide a target CPU utilization level you wish to maintain.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-15860" src="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-02.png" alt="" width="600" height="209" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-02.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-02-300x105.png 300w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-02-779x272.png 779w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>When creating a function using managed instances, you can also set the memory size and the memory-to-CPU ratio.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-15861" src="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-03.png" alt="" width="600" height="252" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-03.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-03-300x126.png 300w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-03-779x328.png 779w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>This lets you tailor the execution environment based on your workload. For example, for basic CRUD APIs, a 2-to-1 ratio is fine. But for memory intensive workloads you might choose a higher memory-to-cpu ratio.</p>
<h3>Important considerations</h3>
<h4><strong>Execution environments can handle multiple concurrent requests</strong></h4>
<p>This allows better utilization of the available CPU cycles. This is important for keeping cost in check when running at scale.</p>
<p>But it also means your code need to be thread-safe. For example, you need to be more careful when using and modifying global variables, because another concurrent request might have also modified them.</p>
<h4><strong>Paying for uptime instead of execution time</strong></h4>
<p>You no longer pay for execution time, but instead, you pay for a combination of:</p>
<ul class="unordered_list">
<li class="list_item">No. of Lambda requests &#8211; $0.20 per million.</li>
<li class="list_item">The EC2 cost.</li>
<li class="list_item">15% premium on the EC2 cost.</li>
</ul>
<p>As mentioned before, you can use existing EC2 saving plans on the managed EC2 instances.</p>
<h4><strong>No cold starts but slower scaling</strong></h4>
<p>Because execution environments are reused and can handle multiple concurrent requests, there are no more cold starts.</p>
<p>However, when exceeding the capacity of the EC2 fleet, requests are throttled until the system is able to scale up the fleet.</p>
<p>Regular Lambda functions can scale rapidly by tapping into a large, shared pool of EC2 instances. With managed instances, it takes tens of seconds to launch new EC2 instances. As such, it&#8217;s not a good fit when you have large, unpredictable spikes in traffic.</p>
<h3>When to use it</h3>
<p>Considering the above, here are the reasons I&#8217;d consider using managed instances:</p>
<ul class="unordered_list">
<li class="list_item"><strong>Cost-efficiency at scale</strong>, when you have a consistent high throughput.</li>
<li class="list_item"><strong>Predictable performance</strong>. Managed instances is more effective at eliminating cold starts than Provisioned Concurrency.</li>
<li class="list_item"><strong>More control over execution environment</strong>. More choices of instance types, memory-to-CPU ratio, etc.</li>
</ul>
<p>However, for most of us, who aren&#8217;t handling thousands, or even hundreds of requests per second consistently, it&#8217;s better to stay with the default compute mode for Lambda.</p>
<p>Also, if you have a very bursty traffic and you can deal with a bit of cold starts, then you&#8217;re also better off staying with regular functions.</p>
<p>Regardless, I&#8217;m glad that there&#8217;s another option we can upgrade to, should the needs arise. And after all the relentless focus on AI, it&#8217;s good to see AWS going back to and innovating on its core services.</p>
<p>&nbsp;</p>
<h3 class="crp-list-title">Related Posts</h3><div class="crp-list"><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2025/11/preinvent-serverless-001.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/">The biggest pre:invent serverless announcements you may have missed</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/">The biggest re:Invent 2025 serverless announcements</a></div></div></div>
<p>The post <a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/">What you need to know about Lambda Managed Instances</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The biggest pre:invent serverless announcements you may have missed</title>
		<link>https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/</link>
		
		<dc:creator><![CDATA[Yan Cui]]></dc:creator>
		<pubDate>Mon, 24 Nov 2025 19:57:01 +0000</pubDate>
				<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[CloudFront]]></category>
		<category><![CDATA[DynamoDB]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Step Functions]]></category>
		<guid isPermaLink="false">https://theburningmonk.com/?p=15848</guid>

					<description><![CDATA[<p>Here are the best pre:Invent serverless announcements, featuring:<br />
* API Gateway integration with ALB (without NLB)<br />
* API Gateway supports response streaming<br />
* DynamoDB supports multi-attribute composite keys<br />
* ALB adds built-in JWT verification<br />
* Step Functions adds mocking support to its TestState API<br />
* S3 supports Attribute-Based Access Control (ABAC)<br />
* Lambda doesn’t need NAT Gateway anymore!<br />
* Lambda supports native tenant isolation<br />
* Lambda adds provisioned mode for SQS ESM<br />
* Lambda ups max payload size for async invocations to 1MB<br />
* Lambda supports Python 3.14<br />
* Lambda’s Rust support goes GA<br />
* CloudFront introduces flat rate price plan</p>
<p>The post <a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/">The biggest pre:invent serverless announcements you may have missed</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="graf graf--p">re:Invent is almost upon us. A number of significant features have already been announced ahead of the main event.</p>
<p class="graf graf--p">Here is a list of the serverless-related announcements so far that you should know about.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">API Gateway integration with ALB (without NLB)</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">This is one of those things that everyone assumed just works, but never did. Until now, if you want to connect API Gateway to an ALB, you have to first go through an NLB.</p>
<p id="fBPIJDY"><img loading="lazy" decoding="async" class="alignnone wp-image-15849" src="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7c37a53e.png" alt="" width="484" height="135" srcset="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7c37a53e.png 760w, https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7c37a53e-300x84.png 300w" sizes="auto, (max-width: 484px) 100vw, 484px" /></p>
<p class="graf graf--p">With the introduction of VPC Link v2, you can now skip the NLB and connect API Gateway directly with ALB.</p>
<p id="LMfGVsz"><img loading="lazy" decoding="async" class="alignnone wp-image-15850" src="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7db02f7d.png" alt="" width="344" height="139" srcset="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7db02f7d.png 554w, https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b7db02f7d-300x121.png 300w" sizes="auto, (max-width: 344px) 100vw, 344px" /></p>
<p class="graf graf--p">Fewer moving parts, less things that can break, less cost and a big win all around. It’s how it <em class="markup--em markup--p-em">should</em> work all along, and I’m glad we’re finally here!</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">API Gateway supports response streaming</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/compute/building-responsive-apis-with-amazon-api-gateway-response-streaming/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/building-responsive-apis-with-amazon-api-gateway-response-streaming/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">API Gateway now supports response streaming and works with Lambda’s response streaming capability.</p>
<p class="graf graf--p">Before this, if you wanted to do response streaming with Lambda, you had to use Function URLs and build Lambdaliths.</p>
<p class="graf graf--p">There are a couple of things worth noting:</p>
<p class="graf graf--p">1. Response streaming is only enabled for REST APIs, not HTTP APIs. It appears that the API Gateway team has abandoned the dream of HTTP APIs.</p>
<p class="graf graf--p">2. You can stream responses for up to 15 mins, which aligns with Lambda’s 15 mins timeout. You can exceed API Gateway’s 29s integration timeout without requesting a limit raise (which comes with reduced scalability).</p>
<p class="graf graf--p">2.1 But there is also an idle timeout of 5 mins for regional &amp; private endpoints, and 30s for edge-optimised endpoints.</p>
<p class="graf graf--p">3. For each streamed response, the first 10mb has no bandwidth restriction. After that, the response is restricted to 2MB/s.</p>
<p class="graf graf--p">See the developer guide <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode.html" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode.html">here</a> for more details.</p>
<p>&nbsp;</p>
<h3 class="graf graf--p">DynamoDB supports multi-attribute composite keys</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/11/amazon-dynamodb-multi-attribute-composite-keys-global-secondary-indexes/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/about-aws/whats-new/2025/11/amazon-dynamodb-multi-attribute-composite-keys-global-secondary-indexes/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">For me, this is the biggest pre:Invent announcement so far.</p>
<p class="graf graf--p">Multi-attribute GSI for DynamoDB is a huge win! No more building your own composite keys for GSIs and having to backfill every time you need a new composite key.</p>
<p class="graf graf--p">Now you just include the separate attributes in the key schema and add them to your queries, and voila!</p>
<p class="graf graf--p">Read the developer guide <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.MultiAttributeKeys" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.MultiAttributeKeys">here</a> for more details.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">ALB adds built-in JWT verification</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/11/application-load-balancer-jwt-verification/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/about-aws/whats-new/2025/11/application-load-balancer-jwt-verification/">Here’s the official announcement</a>.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Step Functions adds mocking support to its TestState API</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-step-functions-local-testing-teststate-api/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-step-functions-local-testing-teststate-api/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">Step Function’s TestState API now supports mocking so you can test ASL in isolation.</p>
<p class="graf graf--p">The TestState API was useful at launch but it didn’t fit neatly into a typical development workflow where we tend to:<br />
1. design and work on the state machine, ie. the ASL.<br />
2. fill in the implementation of the required Lambda functions.</p>
<p class="graf graf--p">Without mocking, it was not possible to test the ASL in isolation. Which in practice, meant delaying discovery of problems in the state machine design until AFTER you’ve implemented everything.</p>
<p class="graf graf--p">Now we can test the ASL in isolation and make sure the various settings, including data transformations, are correct, before spending time on the Lambda functions (and then test them separately).</p>
<p class="graf graf--p">As I <a class="markup--anchor markup--p-anchor" href="https://lumigo.io/blog/does-step-functions-new-teststate-api-make-end-to-end-tests-obsolete/" target="_blank" rel="noopener" data-href="https://lumigo.io/blog/does-step-functions-new-teststate-api-make-end-to-end-tests-obsolete/">said previously</a>, the TestState API is not a replacement for end-to-end tests where you exercise the state machine and execute it from beginning to end. But it’s a great way to test the individual parts in more detail, especially for execution paths that are difficult to reach on an end-to-end test (eg. error/timeout paths).</p>
<p class="graf graf--p">See the developer guide <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/step-functions/latest/dg/test-state-isolation.html#mocking-service-integrations" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/step-functions/latest/dg/test-state-isolation.html#mocking-service-integrations">here</a> on how to use the new mocking capability.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">S3 supports Attribute-Based Access Control (ABAC)</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/introducing-attribute-based-access-control-for-amazon-s3-general-purpose-buckets/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/aws/introducing-attribute-based-access-control-for-amazon-s3-general-purpose-buckets/">Here’s the official announcement</a>.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda doesn’t need NAT Gateway anymore!</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/compute/aws-lambda-networking-over-ipv6/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/aws-lambda-networking-over-ipv6/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">With IPv6 support, Lambda functions inside a VPC no longer needs a NAT Gateway to access the internet (or other AWS services).</p>
<p class="graf graf--p">Instead, you can use the egress-only internet gateway, which only charges the standard EC2 data transfer cost and has no uptime cost.</p>
<p class="graf graf--p">It’s egress-only and does not allow attackers to reach your infrastructure from the internet.</p>
<p class="graf graf--p">This is another huge win and a great quality of life improvement.</p>
<p id="sMYRREe"><img loading="lazy" decoding="async" class="alignnone wp-image-15851" src="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b83716a1e.png" alt="" width="1024" height="432" srcset="https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b83716a1e.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b83716a1e-300x127.png 300w, https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b83716a1e-779x329.png 779w, https://theburningmonk.com/wp-content/uploads/2025/11/img_6924b83716a1e-1536x648.png 1536w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<h3></h3>
<h3 class="graf graf--h3">Lambda supports native tenant isolation</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/streamlined-multi-tenant-application-development-with-tenant-isolation-mode-in-aws-lambda/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/aws/streamlined-multi-tenant-application-development-with-tenant-isolation-mode-in-aws-lambda/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">Lambda now accepts a “TenantId” attribute in the <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html">Invoke request</a>.</p>
<p class="graf graf--p">By providing a tenant ID in the invocation, you ensure that each tenant’s requests are processed by a separate execution environment.</p>
<p class="graf graf--p">This is useful when you have strict isolation requirements. However, it’s only part of the solution. You still need to ensure data access patterns do not break tenant boundary, e.g. a tenant cannot access another tenant’s data.</p>
<p class="graf graf--p">I have written about multi-tenant design multiple times on this blog.</p>
<ul class="postList">
<li class="graf graf--li"><a class="markup--anchor markup--li-anchor" href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/" target="_blank" rel="noopener" data-href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/">How to secure multi-tenant applications with AppSync and Cognito</a></li>
<li class="graf graf--li"><a class="markup--anchor markup--li-anchor" href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/" target="_blank" rel="noopener" data-href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/">Group-based auth with AppSync Lambda authoriser</a></li>
<li class="graf graf--li"><a class="markup--anchor markup--li-anchor" href="https://theburningmonk.com/2020/08/how-to-model-hierarchical-access-with-appsync/" target="_blank" rel="noopener" data-href="https://theburningmonk.com/2020/08/how-to-model-hierarchical-access-with-appsync/">How to model hierarchical access with AppSync</a></li>
<li class="graf graf--li"><a class="markup--anchor markup--li-anchor" href="https://theburningmonk.com/2024/08/fine-grained-access-control-in-api-gateway-with-cognito-groups-lambda-authorizer/" target="_blank" rel="noopener" data-href="https://theburningmonk.com/2024/08/fine-grained-access-control-in-api-gateway-with-cognito-groups-lambda-authorizer/">Fine-grained access control in API Gateway with Cognito groups &amp; Lambda authorizer</a></li>
</ul>
<p class="graf graf--p">This new capability compliments the approach I outlined in these posts.</p>
<p class="graf graf--p">However, it’s worth noting that it will significantly impact your concurrency needs.</p>
<p class="graf graf--p">You’d need higher account level concurrency limit to handle the same amount of request previously because you cannot reuse execution environments across multiple tenants.</p>
<p class="graf graf--p">This will also impact your ability to scale quickly during a large spike.</p>
<p class="graf graf--p">A Lambda function can scale from 0 to 1000 concurrent executions instantly. Thereafter, it can add a further 1000 concurrent executions every 10 seconds.</p>
<p class="graf graf--p">If the execution environments are tenant specific, then, during a large scaling event, you will need many more concurrent executions to serve the same amount of requests.</p>
<p class="graf graf--p">It’s an interesting launch, but most of you don’t need to use it.</p>
<p class="graf graf--p">Lastly, Anton Aleksandrov has an <a class="markup--anchor markup--p-anchor" href="https://github.com/aws-samples/sample-lambda-tenant-isolation/blob/main/lib/sample-lambda-tenant-isolation-stack.js#L45-L51" target="_blank" rel="noopener" data-href="https://github.com/aws-samples/sample-lambda-tenant-isolation/blob/main/lib/sample-lambda-tenant-isolation-stack.js#L45-L51">example in CDK</a> on how to integrate API Gateway with Lambda to pass the tenant ID (resolved by a Lambda authorizer) in the proxy request to Lambda.</p>
<p class="graf graf--p"><strong class="markup--strong markup--p-strong">You should never accept tenant ID from the caller!</strong></p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda adds provisioned mode for SQS ESM</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/aws/aws-lambda-enhances-sqs-processing-with-new-provisioned-mode-3x-faster-scaling-16x-higher-capacity/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/aws/aws-lambda-enhances-sqs-processing-with-new-provisioned-mode-3x-faster-scaling-16x-higher-capacity/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">If you have a very spiky load and need to process millions of SQS messages quickly, you can now have up to 20,000 ESM event pollers &amp; auto-scale the no. of pollers at 1,000 per minute.</p>
<p class="graf graf--p">This new provisioned mode is useful for some specific use cases. For example, if you have a very spiky traffic and strict processing time requirement.</p>
<p class="graf graf--p">It comes at a price of ~$6.66 per poller per month (min 2 pollers).</p>
<p class="graf graf--p">For most of us, the free ESM SQS pollers is more than sufficient and there’s no need to pay extra.</p>
<p class="graf graf--p">But this new capability is great for addressing edge cases.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda ups max payload size for async invocations to 1MB</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/10/aws-lambda-payload-size-256-kb-1-mb-invocations/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/about-aws/whats-new/2025/10/aws-lambda-payload-size-256-kb-1-mb-invocations/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">But don’t get too excited just yet!</p>
<p class="graf graf--p">This is only useful when you trigger an async invocation via the Lambda Invoke API (by setting <code class="markup--code markup--p-code">InvocationType</code> to <code class="markup--code markup--p-code">Event</code>). Because the max message size for both SNS and EventBridge (the most common async event sources for Lambda) is still 256kb.</p>
<p class="graf graf--p">SQS raised its max payload size to 1MB a while back, but SQS triggers Lambda via ESM and is not impacted by this announcement.</p>
<p class="graf graf--p">Also, payload size beyond 256kb are charged as 1 additional request for each 64kb chunk. If you send a 1MB payload, then it counts as 13 invocation requests:</p>
<ul class="postList">
<li class="graf graf--li">256kb as 1 request</li>
<li class="graf graf--li">(1024 – 256) / 64 = 12 additional requests</li>
</ul>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda supports Python 3.14</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/compute/python-3-14-runtime-now-available-in-aws-lambda/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/compute/python-3-14-runtime-now-available-in-aws-lambda/">Here’s the official announcement</a>.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Lambda’s Rust support goes GA</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-lambda-rust/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-lambda-rust/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">This one has more hype than substance.</p>
<p class="graf graf--p">There are no new capabilities, the only thing that changed here is that the <a class="markup--anchor markup--p-anchor" href="https://crates.io/crates/lambda_runtime" target="_blank" rel="noopener" data-href="https://crates.io/crates/lambda_runtime">lambda_runtime</a> crate was marked as GA.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">CloudFront introduces flat rate price plan</h3>
<p class="graf graf--p"><a class="markup--anchor markup--p-anchor" href="https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-flat-rate-pricing-plans-with-no-overages/" target="_blank" rel="noopener" data-href="https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-flat-rate-pricing-plans-with-no-overages/">Here’s the official announcement</a>.</p>
<p class="graf graf--p">You can now get CloudFront and a bunch of associated services (WAF, Route53, CloudFront functions, logging, etc.) for a flat monthly fee.</p>
<p class="graf graf--p">Pay-per-use pricing removes waste, but teams often dislike it because it’s difficult to budget and it can result in sudden spikes, whether it’s from a successful launch or a DOS attack.</p>
<p class="graf graf--p">This sounds tempting, but there are some nuances you must consider.</p>
<ul class="postList">
<li class="graf graf--li">Lambda@Edge functions are not supported on the flat-rate plan, only CloudFront functions are.</li>
<li class="graf graf--li">When you go over the usage quota for your tier, you can be throttled.</li>
</ul>
<p class="graf graf--p">So the trade-off looks like this:</p>
<ul class="postList">
<li class="graf graf--li">Below quota -&gt; you waste money.</li>
<li class="graf graf--li">Above quota -&gt; you risk throttling.</li>
</ul>
<p class="graf graf--p">This is fine for personal projects or non-critical apps where downtime is not costly and you care more avoiding a nasty billing surprise.</p>
<p class="graf graf--p">But it’s a bad deal if availability and elasticity matter more to you than certainty around budget, which describes most business critical systems.</p>
<p class="graf graf--p">Also, the free tier in the flat rate plan gives you only 100GB of free data transfer for CloudFront. Whereas the free tier for the pay-per-use plan gives you 1TB of free data transfer.</p>
<p class="graf graf--p">So if you only care about CloudFront, and not the related services, then you might be better off sticking with the pay-per-use plan.</p>
<p class="graf graf--p">What’s most interesting about this launch is that, it’s the closest thing AWS has offered to a direct spending cap. Here are my thoughts on the <a class="markup--anchor markup--p-anchor" href="https://theburningmonk.com/2023/04/the-skys-the-limit-debating-the-benefits-of-aws-spending-restrictions/" target="_blank" rel="noopener" data-href="https://theburningmonk.com/2023/04/the-skys-the-limit-debating-the-benefits-of-aws-spending-restrictions/">pros &amp; cons of a spending cap</a>.</p>
<p>&nbsp;</p>
<h3 class="graf graf--h3">Wrap up</h3>
<p class="graf graf--p">There has been over 150 announcements in the last few weeks! These are just the ones I find most interesting and relevant to serverless.</p>
<p class="graf graf--p">I’m excited for re:Invent this year and hoping to see a couple of big announcements around Lambda and Step Functions. It’s a shame I won’t be there in person this year, but I wish everyone a good time in Vegas next week!</p>
<p>&nbsp;</p>
<h3 class="crp-list-title">Related Posts</h3><div class="crp-list"><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2021/04/building-a-custom-iam-system-has-made-me-appreciate-aws-iam-even-more/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 126px; height: auto;" width="126" height="72" src="https://theburningmonk.com/wp-content/uploads/2021/04/Screenshot-2023-04-04-at-21.48.16-300x171.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2021/04/Screenshot-2023-04-04-at-21.48.16-300x171.png 300w, https://theburningmonk.com/wp-content/uploads/2021/04/Screenshot-2023-04-04-at-21.48.16.png 1024w, https://theburningmonk.com/wp-content/uploads/2021/04/Screenshot-2023-04-04-at-21.48.16-1536x878.png 1536w" sizes="auto, (max-width: 126px) 100vw, 126px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2021/04/building-a-custom-iam-system-has-made-me-appreciate-aws-iam-even-more/">Building a custom IAM system has made me appreciate AWS IAM even more</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2024/09/fine-grained-access-control-in-api-gateway-with-cognito-access-tokens-and-scopes/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2024/09/cognito-access-token-feature-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2024/09/cognito-access-token-feature-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2024/09/cognito-access-token-feature-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2024/09/cognito-access-token-feature.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2024/09/fine-grained-access-control-in-api-gateway-with-cognito-access-tokens-and-scopes/">Fine-grained access control in API Gateway with Cognito access token and scopes</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2024/08/fine-grained-access-control-in-api-gateway-with-cognito-groups-lambda-authorizer/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2024/08/authorization-with-cognito-and-lambda-feature-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2024/08/authorization-with-cognito-and-lambda-feature-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2024/08/authorization-with-cognito-and-lambda-feature-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2024/08/authorization-with-cognito-and-lambda-feature.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2024/08/fine-grained-access-control-in-api-gateway-with-cognito-groups-lambda-authorizer/">Fine-grained access control in API Gateway with Cognito groups & Lambda authorizer</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/">Group-based auth with AppSync Lambda authoriser</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2020/08/how-to-model-hierarchical-access-with-appsync/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2020/08/appsync-hierarchy.title_-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2020/08/appsync-hierarchy.title_-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2020/08/appsync-hierarchy.title_-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2020/08/appsync-hierarchy.title_.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2020/08/how-to-model-hierarchical-access-with-appsync/">How to model hierarchical access with AppSync</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05.png 1024w, https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-1536x866.png 1536w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/">How to secure multi-tenant applications with AppSync and Cognito</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2025/12/serverless-at-reinvent-title.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/12/the-biggest-reinvent-2025-serverless-announcements/">The biggest re:Invent 2025 serverless announcements</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2025/12/lambda-managed-instances-title.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2025/12/what-you-need-to-know-about-lambda-managed-instances/">What you need to know about Lambda Managed Instances</a></div></div></div>
<p>The post <a href="https://theburningmonk.com/2025/11/the-biggest-preinvent-serverless-announcements-you-may-have-missed-2025/">The biggest pre:invent serverless announcements you may have missed</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AppSync: how to implement unauthenticated operations</title>
		<link>https://theburningmonk.com/2025/07/appsync-how-to-implement-unauthenticated-operations/</link>
		
		<dc:creator><![CDATA[Yan Cui]]></dc:creator>
		<pubDate>Sun, 06 Jul 2025 23:18:10 +0000</pubDate>
				<category><![CDATA[AppSync]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Serverless]]></category>
		<guid isPermaLink="false">https://theburningmonk.com/?p=15819</guid>

					<description><![CDATA[<p>AppSync doesn’t allow unauthenticated API calls.</p>
<p>To allow users to call your API without first authenticating themselves, you must mimic the behaviour using one of the available authorization methods.</p>
<p>In this post, let’s look at three ways to implement unauthenticated GraphQL operations with AppSync and their pros &#038; cons.</p>
<p>The post <a href="https://theburningmonk.com/2025/07/appsync-how-to-implement-unauthenticated-operations/">AppSync: how to implement unauthenticated operations</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="graf graf--p">AppSync doesn’t allow unauthenticated API calls. To allow users to call your API without first authenticating themselves, you must mimic the behaviour using one of the available <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html">authorization methods</a> [1].</p>
<p class="graf graf--p">In this post, let’s look at three ways to implement unauthenticated GraphQL operations with AppSync and their pros &amp; cons.</p>
<h3 class="graf graf--h3">API Keys</h3>
<p class="graf graf--p">To use API keys, you need to:</p>
<ol class="postList">
<li class="graf graf--li">Add an API Key in AppSync.</li>
<li class="graf graf--li">Pass the API Key in the <code class="markup--code markup--li-code">x-api-key</code> header.</li>
</ol>
<p class="graf graf--p">That’s it! It’s the easiest and most common way to implement unauthenticated GraphQL operations in AppSync.</p>
<p class="graf graf--p">However, AppSync API keys has a max expiry of 365 days. You can extend this by a further 365 days with the <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateApiKey.html" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateApiKey.html">UpdateApiKey API</a> [2]. There is no limit to how many times you can extend an API key’s expiry date.</p>
<p class="graf graf--p">In practice, it means you need a cron job to keep extending your API key’s expiry. It’s a manageable nuisance.</p>
<p class="graf graf--p">Finally, there’s no extra charge for using API keys.</p>
<h3 class="graf graf--h3">Lambda authorizer</h3>
<p class="graf graf--p">With a Lambda authorizer, the caller must provide a non-empty string in the <code class="markup--code markup--p-code">authorization</code> header. Instead of API keys, you can pass along a shared secret in the <code class="markup--code markup--p-code">authorization</code> header.</p>
<p class="graf graf--p">This gives you more control over the lifecycle of the shared secret (compared to using API keys).</p>
<p class="graf graf--p">You can also support more than one shared secrets with different levels of access. For example, different shared secrets for different clients, like this:</p>
<pre class="graf graf--pre graf--preV2" spellcheck="false" data-code-block-mode="2" data-code-block-lang="javascript"><span class="pre--content"><span class="hljs-keyword">const</span> <span class="hljs-variable constant_">SHARED_SECRETS</span> = {
  <span class="hljs-attr">mobile</span>: <span class="hljs-string">"..."</span>,
  <span class="hljs-attr">web</span>: <span class="hljs-string">"..."</span>
}

<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">handler</span> = <span class="hljs-keyword">async</span> (event) =&gt; {
  <span class="hljs-keyword">if</span> (event.<span class="hljs-property">authorizationToken</span> === <span class="hljs-variable constant_">SHARED_SECRETS</span>.<span class="hljs-property">mobile</span>) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-string">"isAuthorized"</span>: true,
      <span class="hljs-string">"deniedFields"</span>: [ 
        <span class="hljs-comment">//... deny web client-only fields</span>
      ]
    }
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (event.<span class="hljs-property">authorizationToken</span> === <span class="hljs-variable constant_">SHARED_SECRETS</span>.<span class="hljs-property">web</span>) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-string">"isAuthorized"</span>: true,
      <span class="hljs-string">"deniedFields"</span>: [ 
        <span class="hljs-comment">//... deny mobile client-only fields</span>
      ]
    }
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-string">"isAuthorized"</span>: <span class="hljs-literal">false</span>
    }
  }
}</span></pre>
<p class="graf graf--p">This is easy to implement, and you can cache authorization results for up to an hour. Furthermore, you can eliminate invalid authorization headers using the <code class="markup--code markup--p-code">IdentityValidationExpression</code>.</p>
<p id="XejTUJM"><img loading="lazy" decoding="async" class="alignnone wp-image-15820" src="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03a38ebe5.png" alt="" width="700" height="290" srcset="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03a38ebe5.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03a38ebe5-300x124.png 300w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03a38ebe5-779x322.png 779w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03a38ebe5-1536x636.png 1536w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p class="graf graf--p">It’s a regex that allows AppSync to reject invalid <code class="markup--code markup--p-code">authorization</code> tokens without needing to invoke your Lambda authorizer. Of course, you won’t pay for these unauthorized requests.</p>
<p class="graf graf--p">However, even with caching, there will still be additional charges involved for the Lambda authorizer. There is also a performance hit because of Lambda cold starts, especially if caching means the function will not be invoked frequently.</p>
<h3 class="graf graf--h3">AWS IAM</h3>
<p class="graf graf--p">Lastly, you can use Cognito Identity Pool to issue temporary IAM credentials for unauthenticated clients. The client can then use these temporary IAM credentials to call AppSync.</p>
<p id="XCpSSSa"><img loading="lazy" decoding="async" class="alignnone wp-image-15821" src="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03ceb2253.png" alt="" width="500" height="313" srcset="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03ceb2253.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03ceb2253-300x188.png 300w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03ceb2253-779x488.png 779w" sizes="auto, (max-width: 500px) 100vw, 500px" /></p>
<p class="graf graf--p">Cognito Identity Pool is free to use, but the GetCredentialsForIdentity API call has a default throughput limit of 200 reqs/s.</p>
<p id="GtLNupq"><img loading="lazy" decoding="async" class="alignnone wp-image-15822" src="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03e7e928a.png" alt="" width="700" height="181" srcset="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03e7e928a.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03e7e928a-300x78.png 300w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03e7e928a-779x202.png 779w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b03e7e928a-1536x397.png 1536w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p class="graf graf--p">Luckily, this is a soft limit and can be raised through the Service Quotas console or a support ticket.</p>
<h3 class="graf graf--h3">Conclusions</h3>
<p class="graf graf--p">You can enable unauthenticated GraphQL operations in AppSync through three main approaches.</p>
<ol class="postList">
<li class="graf graf--li"><strong class="markup--strong markup--li-strong">API Keys</strong>: east to set up and free to use, but requires periodic key renewal and offers limited control over individual clients.</li>
<li class="graf graf--li"><strong class="markup--strong markup--li-strong">Lambda Authorizer (with shared secrets): </strong>offers more fine-grained access control at the expense of extra Lambda costs and potential latency from cold starts.</li>
<li class="graf graf--li"><strong class="markup--strong markup--li-strong">AWS IAM via Cognito Identity Pool</strong>: leverages temporary AWS credentials for fine-grained access control. Free to use, (can be) highly scalability, though initial throughput limits and setup complexity may be a hurdle for simple use cases.</li>
</ol>
<p class="graf graf--p">Here is a side-by-side comparison of their pros and cons:</p>
<p id="EkfkdND"><img loading="lazy" decoding="async" width="1024" height="422" class="alignnone size-full wp-image-15823 " src="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b040a8894e.png" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2025/07/img_686b040a8894e.png 1024w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b040a8894e-300x124.png 300w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b040a8894e-779x321.png 779w, https://theburningmonk.com/wp-content/uploads/2025/07/img_686b040a8894e-1536x634.png 1536w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<h3 class="graf graf--h3">Links</h3>
<p class="graf graf--p">[1] <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#api-key-authorization" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#api-key-authorization">Configuring authorization and authentication to secure your GraphQL APIs</a></p>
<p class="graf graf--p">[2] <a class="markup--anchor markup--p-anchor" href="https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateApiKey.html" target="_blank" rel="noopener" data-href="https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateApiKey.html">UpdateApiKey API</a></p>
<h3 class="crp-list-title">Related Posts</h3><div class="crp-list"><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2021/09/appsync-lambda-authorizer.title_.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2021/09/group-based-auth-with-appsync-lambda-authoriser/">Group-based auth with AppSync Lambda authoriser</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2020/11/how-i-built-a-social-network-in-4-weeks-with-graphql-and-serverless/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2020/11/social-network-4-weeks.title_-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2020/11/social-network-4-weeks.title_-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2020/11/social-network-4-weeks.title_-779x438.png 779w, https://theburningmonk.com/wp-content/uploads/2020/11/social-network-4-weeks.title_.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2020/11/how-i-built-a-social-network-in-4-weeks-with-graphql-and-serverless/">How I built a social network in 4 weeks with GraphQL and serverless</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2023/12/direct-access-for-frontend-apps-to-aws-services/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2023/12/assets._042-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2023/12/assets._042-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2023/12/assets._042.png 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2023/12/direct-access-for-frontend-apps-to-aws-services/">How to Securely let Frontend Apps to Directly Access AWS services</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2024/12/how-to-invalidate-cognito-issued-jwt-tokens/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2024/12/invalidate-cognito-tokens-300x169.jpg" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2024/12/invalidate-cognito-tokens-300x169.jpg 300w, https://theburningmonk.com/wp-content/uploads/2024/12/invalidate-cognito-tokens-779x438.jpg 779w, https://theburningmonk.com/wp-content/uploads/2024/12/invalidate-cognito-tokens.jpg 1024w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2024/12/how-to-invalidate-cognito-issued-jwt-tokens/">How to invalidate Cognito-issued JWT tokens</a></div></div><div class="crp-list-item crp-list-item-image-left crp-list-item-has-image"><div class="crp-list-item-image"><a href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/"><img loading="lazy" decoding="async" data-pin-nopin="true" style="max-width: 128px; height: auto;" width="128" height="72" src="https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-300x169.png" class="attachment-128x72 size-128x72 wp-post-image" alt="" srcset="https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-300x169.png 300w, https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05.png 1024w, https://theburningmonk.com/wp-content/uploads/2021/03/Screenshot-2023-04-04-at-20.54.05-1536x866.png 1536w" sizes="auto, (max-width: 128px) 100vw, 128px" /></a></div><div class="crp-list-item-title"><a href="https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/">How to secure multi-tenant applications with AppSync and Cognito</a></div></div></div>
<p>The post <a href="https://theburningmonk.com/2025/07/appsync-how-to-implement-unauthenticated-operations/">AppSync: how to implement unauthenticated operations</a> appeared first on <a href="https://theburningmonk.com">theburningmonk.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
