Skip to content

re:Invent 2025 - Best practices for serverless developers

8 minute read
Content level: Advanced
0

Serverless architectures evolve through real growing pains. This session follows five years of architectural transformation, from a 40-order-per-month local startup to a global operation processing 3.8 million orders annually, extracting practical principles that apply to developers at every stage of growth.

Building production serverless applications means making decisions that compound over time. A function that starts as 200 lines handling a single use case gradually absorbs more responsibilities until a single bug can take down an entire system. Julian Wood, Principal Serverless Developer Advocate at AWS, walked re:Invent 2025 attendees through how teams at this scale overcame cascading failures, runaway costs, and architectural complexity using AWS Lambda and the broader serverless toolkit. In this post, we'll cover how to right-size functions, shift to asynchronous patterns, eliminate unnecessary compute, and optimize Lambda performance for workloads that genuinely require it.

Start with the right boundaries, not the right count

One of the first mistakes developers make with serverless is treating function count as a measure of architectural maturity. Julian illustrated this through Amelie, a fictional patisserie owner whose single Lambda function handling orders, validation, notifications, and analytics grew into a deployment and debugging nightmare. A single bug in the notification logic brought down all order processing during a holiday rush. The lesson is not to split aggressively, but to draw clear boundaries around business domains first.

Julian's guidance is to keep functions cohesive until growth actually causes pain, and to organize Lambda functions, AWS CloudFormation stacks, and code repositories by business domain. This approach allows different teams to independently choose their runtime and tooling. An inventory team might prefer Python for data-heavy workloads while a customer experience team uses TypeScript across the front end and backend. Domain-driven organization, where each team owns its own data and infrastructure, creates the team autonomy that makes serverless genuinely scalable. Lambda allocates CPU power proportionally to memory configuration, and package size directly impacts cold start times, so right-sizing functions for their actual workload (not convenience) reduces both cost and latency.

Frameworks belong in this foundation. Whether you choose AWS SAM, AWS CDK, or a third-party tool, infrastructure as code is non-negotiable for managing serverless applications at scale. And resist the temptation to create one repository per function. A single repository organizing multiple services by domain is far more manageable.

Prefer asynchronous, event-driven patterns

The second major theme is the shift from synchronous to asynchronous architectures, and Julian was direct about it: async should be your default. Synchronous chains are fragile. When a payment API slows down, every downstream step waits, customer orders stall, and timeout limits start to feel very close. Amelie's team saw 23% of orders abandoned during peak hours because the architecture forced customers to wait while every step completed sequentially.

The solution is to decouple services using Amazon EventBridge for event-driven communication between domains, Amazon SQS for durable message buffering, and AWS Step Functions for workflow orchestration within a domain. The customer receives an immediate confirmation while downstream services (payment, inventory, kitchen notifications) process asynchronously. AWS AppSync Events can push real-time status updates back to the client as each stage completes, giving you both speed and visibility.

Lambda's Event Source Mapping (ESM) is one of the most powerful mechanisms in this model. The Lambda service polls SQS and other sources automatically, batches records for efficient processing, and provides built-in filtering so you only process the messages your function actually needs. Julian shared that Amelie's team reduced costs on one ESM by 92% simply by applying message filtering. For high-throughput scenarios, the newly announced SQS provisioned mode lets you pre-provision event pollers to handle sudden traffic spikes with precise throughput controls.

When configuring SQS with Lambda, Julian recommended setting the visibility timeout to at least six times the Lambda function timeout, using a redrive policy with three to five attempts, and configuring a dead-letter queue (DLQ) to capture messages that fail repeatedly. The max concurrency setting on the ESM controls how fast Lambda consumes from the queue, which prevents overwhelming downstream databases or third-party APIs.

Step Functions supports both standard workflows (long-running, auditable processes up to one year) and express workflows (synchronous or asynchronous, up to five minutes, optimized for high throughput at lower cost). Combining them delivers the best of both: use standard workflows for the overall process lifecycle and nested express workflows for the real-time components that need sub-second responses. Many of Amelie's workflows dropped to roughly one-twentieth of the previous per-execution cost by switching applicable state machines to express workflows.

Do less, then optimize what remains

A recurring theme throughout the session is that the best Lambda function is often the one you do not write. By 2024, Amelie's team had 42 Lambda functions, many of which simply transformed data or routed messages between services. Cold starts, deployment complexity, and compute costs for these passthrough functions were entirely unnecessary.

Step Functions' direct AWS SDK integrations allow state machines to call Amazon DynamoDB, Amazon SNS, SQS, and thousands of other actions without Lambda as a proxy. EventBridge Pipes provide built-in filtering and transformation between event sources and targets, handling format conversions and data enrichment without custom code. Amazon API Gateway can connect directly to DynamoDB and SQS, eliminating Lambda from read-heavy or write-heavy paths entirely. Reducing 42 functions to 10 cut Amelie's processing time from six seconds to 400 milliseconds and saved $1,500 per month.

A notable announcement at re:Invent 2025 is Lambda Durable Functions, which extends this thinking into Lambda itself. Durable Functions introduces checkpointing and resume capabilities directly inside a Lambda function, allowing long-running workflows written in your preferred programming language to suspend and resume without paying for idle wait time. Idempotency is built into the checkpointing model, and workflows can run for up to a year. For teams whose workflows contain substantial custom code and who prefer managing logic in code rather than in a state machine definition, this is a compelling new option that complements Step Functions.

For the Lambda functions that do require custom compute, performance optimization follows a clear priority order. Memory right-sizing has the biggest impact at the lowest implementation effort. Lambda allocates CPU proportionally to memory, so an underpowered function processing a batch of records may actually cost more than a higher-memory function that finishes faster. The open-source Lambda Power Tuning tool automates this by running your function at multiple memory configurations and visualizing the cost and performance tradeoffs.

Cold start optimization matters most for latency-sensitive, synchronous workloads. Lambda SnapStart captures a snapshot of the initialized execution environment at publish time and resumes from it on invoke, typically in under one second with no additional cost. This is particularly valuable for Java, Python workloads with large ML framework imports, and .NET applications. Provisioned Concurrency prewarms execution environments in advance for predictable traffic patterns where sub-100-millisecond startup latency is a hard requirement. Pairing it with Application Auto Scaling to ramp up before known traffic peaks and scale down afterwards keeps costs controlled. Note that SnapStart and Provisioned Concurrency cannot be used on the same function version.

Also announced at re:Invent 2025, Lambda Managed Instances gives you access to the full EC2 instance family with Lambda's operational model, running in your VPC. For high-scale, steady-state workloads where burstability is less critical, Managed Instances can integrate with EC2 pricing plans such as Reserved Instances for significant cost reductions.

Powertools for AWS Lambda provides structured logging, embedded metrics, distributed tracing, and idempotency utilities for Python, TypeScript, Java, and .NET. The Embedded Metrics Format (EMF) writes both searchable logs and Amazon CloudWatch metrics in a single log entry, making it cheaper and faster than publishing custom metrics separately. Include business context such as order IDs and customer identifiers in your logs rather than as metric dimensions to keep CloudWatch costs predictable.

Key takeaways

Julian walked through five years of evolution from a single Lambda function handling 40 orders per month to a globally distributed architecture processing 3.8 million orders per year. The principles that enabled this growth hold at every scale.

Start with cohesive, domain-aligned functions and resist premature splitting. Default to asynchronous, event-driven patterns and use EventBridge, SQS, and Step Functions to decouple services so failures stay isolated. Remove Lambda from paths that do not require custom logic by using direct service integrations and EventBridge Pipes. For the functions that remain, right-size memory first, then address cold starts in latency-sensitive paths with SnapStart or Provisioned Concurrency. Instrument with business context, not just technical metrics. And treat every architecture decision as a cost decision: review and optimize continuously.

New capabilities announced at re:Invent 2025 (Lambda Durable Functions, Lambda Managed Instances, and SQS provisioned mode) expand what is possible, but the fundamentals remain the same. Minimize unnecessary compute, prefer event-driven decoupling, and use AWS managed services to handle the undifferentiated heavy lifting wherever possible.


Watch the full session recording on YouTube: AWS re:Invent 2025 - Best practices for serverless developers (CNS403)

AWS
EXPERT

published 7 months ago432 views