Retries and Timeouts

The AWS SDK for Go V2 enables you to configure the retry behavior of requests to HTTP services. By default, service clients use retry.Standard as their default retryer. If the default configuration or behavior does not meet your application requirements, you can adjust the retryer configuration or provide your own retryer implementation.

The AWS SDK for Go V2 provides a aws.Retryer interface that defines the set of methods required by a retry implementation to implement. The SDK provides two implementations for retries: retry.Standard and aws.NoOpRetryer.

Standard Retryer

The retry.Standard retryer is the default aws.Retryer implementation used by SDK clients. The standard retryer is a rate limited retryer with a configurable number of max attempts, and the ability to tune the request back off policy.

The following table defines the default values for this retryer:

Property Default
Max Number of Attempts 3
Max Back Off Delay 20 seconds

When a retryable error occurs while invoking your request, the standard retryer will use it’s provided configuration to delay and subsequently retry the request. Retries add to the overall latency of your request, and you must configure retryer if the default configuration does not meet your application requirements.

See the retry package documentation for details on what errors are considered as retryable by the standard retryer implementation.

NopRetryer

The aws.NopRetryer is a aws.Retyer implementation that is provided if you wish to disable all retry attempts. When invoking a service client operation, this retryer will only allow the request to be attempted once, and any resulting error will be returned to the calling application.

Customizing Behavior

The SDK provides a set of helper utilities that wrap an aws.Retryer implementation, and returns the provided retryer wrapped with the desired retry behavior. You can override the default retryer for all clients, per client, or per operation depending on your applications requirements. To see additional examples showing how to do this see the retry package documentation examples.

Limiting the max number of attempts

You use retry.AddWithMaxAttempts to wrap an aws.Retryer implementation to set the max number attempts to your desired value. Setting max attempts to zero will allow the SDK to retry all retryable errors until the request succeeds, or a non-retryable error is returned.

For example, you can the following code to wrap the standard client retryer with a maximum of five attempts:

import "context"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
	return retry.AddWithMaxAttempts(retry.NewStandard(), 5)
}))
if err != nil {
	return err
}

client := s3.NewFromConfig(cfg)

Limiting the max back off delay

You use retry.AddWithMaxBackoffDelay to wrap an aws.Retryer implementation and limit the max back off delay that is allowed to occur between retrying a failed request.

For example, you can the following code to wrap the standard client retryer with a desired max delay of five seconds:

import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
	return retry.AddWithMaxBackoffDelay(retry.NewStandard(), time.Second*5)
}))
if err != nil {
	return err
}

client := s3.NewFromConfig(cfg)

Retry additional API error codes

You use retry.AddWithErrorCodes to wrap an aws.Retryer implementation and include additional API error codes that should be considered retryable.

For example, you can the following code to wrap the standard client retryer to include the Amazon S3 NoSuchBucketException exception as retryable.

import "context"
import "time"
import "github.com/aws/aws-sdk-go-v2/aws/retry"
import "github.com/aws/aws-sdk-go-v2/config"
import "github.com/aws/aws-sdk-go-v2/service/s3"
import "github.com/aws/aws-sdk-go-v2/service/s3/types"

// ...

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer {
	return retry.AddWithErrorCodes(retry.NewStandard(), (*types.NoSuchBucketException)(nil).ErrorCode())
}))
if err != nil {
	return err
}

client := s3.NewFromConfig(cfg)

Timeouts

You use the context package to set timeouts or deadlines when invoking a service client operation. Use the context.WithDeadline to wrap your applications context and set a deadline to a specific time by which the invoked operation must be completed. To set a timeout after a certain time.Duration use context.WithTimeout. The SDK passes the provided context.Context to the HTTP transport client when invoking a service API. If the context passed to the SDK is cancelled or becomes cancelled while invoking the operation, the SDK will not retry the request further and will return to the calling application. You must handle context cancellation appropriately in your application in cases where the context provided to the SDK has become cancelled.

Setting a timeout

The following example shows how to set a timeout for a service client operation.

import "context"
import "time"

// ...

ctx := context.TODO() // or appropriate context.Context value for your application

client := s3.NewFromConfig(cfg)

resp, err := client.GetObject(context.WithTimeout(ctx, 5*time.Second), &s3.GetObjectInput{
	// input parameters
})
if err != nil {
	// handle error
}