Repository navigation
Description
This issue tracks the 2026 retry updates for AWS SDK for Go 2.x. See the announcement blog post for the full story across all AWS SDKs, including how to tell if you are affected.
Status
| Opt-in | Coming in the following weeks. We will update this issue when the release ships. |
| Opt-in flag | AWS_NEW_RETRIES_2026=true |
| Default rollout | No sooner than November 2026 |
What changed
When you set AWS_NEW_RETRIES_2026=true, the retry defaults within standard mode update. The retry mode itself does not change.
If you have explicitly configured max attempts or backoff, your value takes precedence for that setting.
| Setting | Before | After |
|---|---|---|
| Transient (non-throttling) base delay | 1,000 ms | 50 ms |
| Throttling base delay | 1,000 ms | 1,000 ms (unchanged) |
| Max attempts | 3 | 3 (unchanged) |
| Transient retry quota cost | 5 tokens | 14 tokens |
| DynamoDB and DynamoDB Streams | ||
| Transient (non-throttling) base delay | 1,000 ms | 25 ms |
| Throttling base delay | 1,000 ms | 1,000 ms (unchanged) |
| Max attempts | 3 | 4 |
DynamoDB defaults use a shorter base delay to match its low-latency profile. The additional attempt keeps the last retry's maximum backoff comparable to the general default.
Transient errors (such as 500s and connection resets) now use a much shorter backoff than throttling errors (where the service asks you to slow down). For details on backoff timing, error classification, and the retry quota, see Retry behavior in the AWS SDKs. For retry mode selection and configuration options, see Retry behavior in the AWS SDKs.
How to opt in
Once the release ships (we will update this issue), set the environment variable:
export AWS_NEW_RETRIES_2026=trueHow to revert
During the opt-in period, remove the environment variable:
unset AWS_NEW_RETRIES_2026After the default rollout (no sooner than November 2026), the AWS_NEW_RETRIES_2026 flag will be removed. A full revert to the previous behavior is not available because this SDK does not support legacy retry mode. You can override some individual settings:
| Setting | Can revert? | How |
|---|---|---|
| Max attempts | Yes | Set AWS_MAX_ATTEMPTS or configure in code. |
| Base backoff delay | Yes | Set StandardOptions.BaseDelay |
| Per-error-type backoff split | No | Not configurable. |
| Retry quota token costs | Yes | You can set ThrottlingRetryCost for throttle errors and RetryCost for general retry errors |
| Long-polling backoff on depleted quota | No | Not configurable. |
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/retry"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
return retry.AddWithMaxAttempts(retry.NewStandard(), 3)
}))
if err != nil {
// handle error
}
client := dynamodb.NewFromConfig(cfg)
// if you want to override other fields per service
dynamoClient := dynamodb.NewFromConfig(cfg, func(o *dynamodb.Options) {
o.Retryer = retry.NewStandard(func(so *retry.StandardOptions) {
so.BaseDelay = 25 * time.Millisecond
so.ThrottlingRetryCost = 5
so.RetryCost = 14
})
})If full revert is a concern for your use case, please let us know in this issue.
Where you might notice a difference
For most workloads, the change is invisible or strictly better. Transient errors recover faster because the base delay is significantly shorter.
- Retry quota activates sooner for transient errors. Each transient retry costs 14 tokens (previously 5 for most errors). During sustained transient failures (such as 500s and connection resets), the retry quota triggers at a lower failure rate than the previous version of standard mode. Throttling retries cost 5 tokens.
- Long-polling operations now back off when the retry quota is depleted. Operations like
SQS.ReceiveMessageapply a backoff delay before returning an error, even when retries are blocked. Without this, polling loops tighten during outages, spiking client CPU usage and generating additional load that can delay recovery. For details, see long-polling operations.
Overriding specific settings
You do not have to accept all changes as a bundle. If you opt in but want to keep a specific previous value, set it explicitly. Precedence applies per setting.
For example, to use the new backoff timing but keep a higher DynamoDB max attempts:
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/retry"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
return retry.AddWithMaxAttempts(retry.NewStandard(), 9)
}))
if err != nil {
// handle error
}
client := dynamodb.NewFromConfig(cfg)For the full list of configurable settings and their precedence, see Retry behavior in the AWS SDKs.
Feedback
If you encounter unexpected behavior or have questions, comment on this issue. Your feedback during the opt-in period directly shapes when and how we make this the default.
Activity
vasilisnasopoulos commentedon Oct 25, 2026
Thanks for opening the opt-in window. One question about how the retry quota behaves in large fleets of low-volume clients
(Lambda, containers), measured against the 2026 defaults.
I drove the real
retry.Standardfrom v1.47.4 (token bucket, costs, backoff), in the same order asaws/retry/middleware.go,in a simulation: 1,000 req/s total, spread over N clients, 30-second full outage (every attempt fails), one SDK client per caller.
With a 50% failure rate instead of 100%, the quota blocked no retries at all from about 600 clients up, in both modes (~1.75x).
So the quota only engages for a client that sends roughly 30+ (transient) or 100+ (throttling) requests within the incident. The 2026
change moves that point by about 3x for transient errors and leaves throttling where it was. This matches the documented scope
("a single SDK client instance … not shared across processes or hosts"), so I'm not reporting a bug.
I then looked at
x-amz-retry-afteras the fleet-level lever (same setup, 10,000 clients, 2026 mode). The SDK clamps the server valueto [backoff, backoff + 5 s] (
adjustForRetryAfterHeader,middleware.go:526-556):For a 30-second outage, the service can bring the fleet down from about 3x to about 2.5x, whatever value it sends, because of the 5-second cap.
For a short outage it works well during the outage, but every deferred retry lands in the first few seconds after recovery.
Two questions:
x-amz-retry-afterthe intended mechanism there?x-amz-retry-aftera deliberate bound (latency?), and is it expected to be enough for longer incidents?Limits: failures are random and independent of load (no overload feedback); one seed; DynamoDB's 4-attempt profile not modelled.