Why Retries Matter in Serverless Applications
Serverless architectures often interact with AWS services that may face intermittent outages, or experience latency spikes. Without proper retry strategies, these transient failures will significantly impact your application's availability and performance.

On top of that: Traditionally, servers under heavy load would gradually slow down until becoming unresponsive. However, in cloud-based, especially serverless environments, managed services also enforce rate limits.
And if that's not enough: throttling exceptions can occur when services need time to autoscale in response to sudden increases in demand. For instance, DynamoDB's on-demand scaling can experience delays, sometimes several minutes, when adjusting read/write capacities significantly.
Retrying becomes are a powerful strategy for managing these scenarios effectively.
Once you reach the maximum retry count, consider further measures such as implementing dead letter queues (DLQs) to handle persistent failures gracefully.

AWS SDK Default Retry Behavior
It's crucial to be proactive about retries. Understand your SDKs default settings and what happens if you exceed the maximum retry count. If you don't like the defaults you can change those to your needs.

AWS SDK comes with preset retry behaviors enabled by default for all service calls. This value is specific to your SDK (Javascript, Java, Go, etc.). Check your specific SDK guide for its default. This built-in behavior ensures a reasonable balance between robustness and efficiency, making your application resilient without additional configuration.
AWS SDK Retry Modes
AWS SDK provides built-in retry mechanisms with different configurable modes:
- Standard (Recommended): For general use, includes exponential backoff with jitter to handle typical scenarios effectively.
- Adaptive: (Experimental) Dynamically adjusts retry timing based on observed latency and errors.
- Legacy: Older, simpler retry logic with limited capabilities, typically avoided for new implementations.
To set the retry mode explicitly in AWS SDK for Javascript v3:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({
retryMode: "adaptive", // options: 'standard', 'adaptive', 'legacy'
});
Customizing Retry Behavior (AWS SDK JavaScript V3)
While AWS SDK has sensible defaults, it's beneficial to customize retries to match your use cases. See your SDKs documentation for other examples than Javascript here.
Set Maximum Retry Attempts
Control the maximum number of retry attempts explicitly:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({
maxAttempts: 5
});
Custom Retry Backoff Logic
You can implement your own retry strategy by customizing the backoff delay:
...
import {ConfiguredRetryStrategy} from '@smithy/util-retry';
const maxAttempts = 4;
const backoffFunction = (attempt: number) => 100 + attempt * 1000;
const retryStrategy = new ConfiguredRetryStrategy(
maxAttempts,
backoffFunction
);
const client = new DynamoDBClient({
retryStrategy
});
...
Important Considerations
When implementing retries, always consider:
- Idempotency: Ensure operations can safely execute multiple times without unintended side-effects.
- Monitoring & Logging: Track retries for better observability, debugging, and tuning.
- Dead Letter Queues (DLQs): Capture events that exhaust retries for later manual intervention or analysis.
Example of idempotent DynamoDB write operation:
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({});
...
const putCommand = new PutItemCommand({
TableName: "ExampleTable",
Item: {
id: { S: generatedId },
data: { S: databody },
},
ConditionExpression: "attribute_not_exists(id)", // ensures idempotency
});
try {
await client.send(putCommand);
} catch (error) {
...
}
Conclusion
Considering AWS SDK retry behaviors is crucial for building resilient and reliable serverless applications. Utilize provided retry modes, customize strategies as needed, and always design your application logic with idempotency and monitoring in mind.