AJ Stuyvenberg

AJ Stuyvenberg

@ajs.bsky.social

AWS Hero Staff Eng @ Datadog Streaming at: twitch.tv/aj_stuyvenberg Videos at: youtube.com/@astuyve I write about serverless minutia at aaronstuyvenberg.com/

1.9K followers238 following325 posts

The clanker wars have begun:

I asked Claude (Opus 4.6) and Codex (GPT-5.3) to each generate a simple LinkedList implementation in Java. Then I asked Claude to pick the better one. No hesitation: "The Codex version is better" 🤔 gist.github.com/christophetd...

I use AWS a ton but Lambda still astounds me. Throw some code in a function, send 1m requests as fast as you can. It ate up all available file descriptors on my little t3 box and still ran 18k RPS with a p99 of 0.3479s. Not many services can go from 0 to 18k RPS instantaneously with this p99.

Lambda now charges for init time, so it's useful to count sandboxes which are proactively initialized but never receive a request. Here's what happens after a 10k request burst. Hundreds of sandbox shutdowns, along with 22 sandboxes which were spun up but never received a request.

NEW: Lambda can now send up to 200mb payloads using response streaming! I assume this is mostly directed at LLM inference workloads, where chatbots can stream large amounts of data over the wire as it becomes available.

I've long been an advocate for the Lambda Web Adapter project which lets anyone pretty easily ship an app to Lambda without learning about the event model/API. Honestly AWS should simply support this natively.

That said, I'm excited to share that @Datadog's Serverless monitoring product now supports LWA! Thanks to Harold and AWS Labs for collaborating with us on the PRs, and huge thanks to Alex Gallotta for driving this work.

"We run benchmarks continually across all of our competitors, not just queries - even connections, ensuring we don't add any latency at all." @isamlambert Performance is such a competitive advantage which easily slips away if you're not constantly paying attention to it.

Here's another 33% cold start reduction, which comes from deferring expensive decryption calls made to AWS Secrets Manager until the secret is actually needed. Lazy loading is great!

Here's how to visualize a 100% memory allocation improvement! A recent stress test revealed that malloc calls bottlenecked when sending > 100k spans through the API and aggregator pipelines in Lambda.

Here's how to visualize a 100% memory allocation improvement! A recent stress test revealed that malloc calls bottlenecked when sending > 100k spans through the API and aggregator pipelines in Lambda.

By switching to a memory arena, we preallocate a slab of memory and virtually eliminate the linear growth of malloc syscalls, which cuts down kernel mode switches, improving latency. Thank you profiling (and jemalloc)!

NEW: A recent blog post went viral in the AWS ecosystem, about how there's a silent crash in AWS Lambda's NodeJS runtime. Today I'll step you through the actual Lambda runtime code which causes this confusing issue, and walk you through how to safely perform async work in Lambda:

NEW: A recent blog post went viral in the AWS ecosystem, about how there's a silent crash in AWS Lambda's NodeJS runtime. Today I'll step you through the actual Lambda runtime code which causes this confusing issue, and walk you through how to safely perform async work in Lambda:

Lambda's fleet management shutdown algorithm is learning faster! I'm calling this function every 8 or so minutes. At first the gap from invocation to shutdown is about 5-6 minutes, which was the fastest I've observed during previous experiments.

I assume this helps with capacity, especially as so many functions are triggered on schedules for the top of the hour or on a routine call schedule. I've long suspected that I could get faster cold starts/placements by scheduling a function at the 58th minute instead of the top of the hour.

You should care about your p99! By improving the function cold start time, the service on the left performed: 2x faster in RPS and thus, duration. p99 from 1.52s -> .949s The code and functionality is identical, but improving the cold start from 816ms to 301ms made all the difference.

Quick PSA to make sure you're using a DLQ and setting a max receive count for SQS, otherwise you may find yourself looking at a flamegraph like this. Hundreds of attempts, multiple messages in queue and not burning down and average age of message ticking up! Seems common knowledge, but...

Real-time audio processing is an extremely interesting corner of performance engineering. You've gotta process data faster than it streams in, otherwise the work is wasted. The engineering team behind CoScreen just open sourced a new library, dtln-rs, suitable for removing noise from all kinds

datadoghq.comHow we built a real-time, client-side noise suppression library without server dependencies | DatadogLearn how we implemented and open-sourced a noise filter for real-time audio chat without compromising performance. Better yet, try the demo and add it to your own project today.

Monitoring Lambda sandbox shutdowns reveals an interesting scaling behavior After a request spike, Lambda waits ~10m before reaping 2/3rds of sandboxes. 5m later it begins reaping the rest. Presumably this helps smooth latency during retry storms, or if traffic returns!

Here's another huge p99 cliff! One unreasonably effective way to lower the average latency of a service is to minimize the causes of p99 events. Here, we've managed to absolutely crush the Max Post Runtime Duration from ~80ms to 500µs!

View full thread

Which means you have to keep track of all inflight flush requests over the course of multiple invocations. If the sandbox detects that the request rate is slowing, you've gotta drive those requests synchronously and block /next until they're done (or risk losing data!)

Here's another huge p99 cliff! One unreasonably effective way to lower the average latency of a service is to minimize the causes of p99 events. Here, we've managed to absolutely crush the Max Post Runtime Duration from ~80ms to 500µs!

View full thread

How? In short, I cheated. If the invocations are frequent enough (more frequent than the TCP Keep Alive/server timeout), you can drive one flush request asynchronously across multiple invocations and it costs you $0 in billed time. That's not the hard part though.

The hard part is figuring out what to do when function invocation rates slow down and you need to adapt back to flushing data and blocking /next until it completes, because otherwise you'll drop data. Lambda functions can't coordinate so you have to figure this out another way

Here's another huge p99 cliff! One unreasonably effective way to lower the average latency of a service is to minimize the causes of p99 events. Here, we've managed to absolutely crush the Max Post Runtime Duration from ~80ms to 500µs!

This is the result of a new flushing algorithm for our Next-Generation Lambda Extension. As you can see this strategy delivers a nearly ZERO overhead flushing solution to busy Lambda functions. Focusing on those p99 events can deliver huge wins, so keep an eye on what makes your service slow!

PRICE CUT: Lambda slashes the price of cloudwatch logs for high volume. From $.50/gb down to $0.05/gb after 50TB. You've gotta be spending a decent chunk of $$$ on cloudwatch logs for this to help, but still – a price cut is a price cut!

Combining profiler data with claude code feels super powerful. Just drop a pprof file into a project, explain the dimensions of the profile, then let the LLM make suggestions to solve the hot spots. Instant performance boost

NEW: AWS Lambda will now begin billing for the INIT phase for all runtimes (not just custom/container runtimes). Your cold starts cost money now! My hottest take is that AWS should have done this years ago.

Free init time incentivizes abuse such as: 1. crypto mining or scrape websites in 10s of init time with 10gb functions, making it slower for all of us 2. Lambda team wasting time tracking all this down 3. Programming in Java ;)

I'm glad that people can finally make objective decisions about whether to use a container image vs zip based function without having to consider the cost difference. I believe the cost was always marginal but it's just added friction in the decision making process.