AWS Mobile Blog

Understanding Timeout and Retry Options in the AWS SDK for iOS

by Bob Kinney | on | in S3 | Permalink | Comments |  Share

Version 2 of the AWS Mobile SDK

  • This article and sample apply to Version 1 of the AWS Mobile SDK. If you are building new apps, we recommend you use Version 2. For details, please visit the AWS Mobile SDK page.
  • This content is being maintained for historical reference.

A great mobile app should be resilient to slow or unreliable network connections. Mobile devices utilize a variety of networks, and not all are created equal in terms of throughput and availability. In some situations, it may be appropriate to retry failed service requests, and in others to “fail fast” and notify the end-user. The AWS SDK for iOS offers you some control on how your app communicates with AWS service APIs in the face of a slow or unreliable network connection.

Timeout Values

Each service client in the AWS SDK for iOS supports two different timeout values, timeout and connectionTimeout, and it’s important to understand the difference between them:

  • timeout — the total time in seconds the SDK will wait for a request to complete. This value can be useful if you know your requests should take a short amount of time, but may need to be increased if you are doing larger file transfers with Amazon S3. The default value is 240 seconds (4 minutes).
  • connectionTimeout — the number of seconds the SDK will wait for any piece of data "over the air." Data transfer is broken down into discrete chunks called "packets", and this is how long the SDK will wait for any one packet. If not explicitly set, this value will default to the value of timeout. As this value is applied directly to the NSURLConnection the SDK for iOS uses to communicate with service endpoints, it is subject to the minimum values supported by the iOS SDK. For versions of iOS prior to 6.0, this minimum is 240 seconds; otherwise, it is 60 seconds.

As you can see, these values have different effects but do interact. We strongly recommend that if you need to increase timeout that you make sure you properly restrict connectionTimeout to avoid allowing your connections to sit idle for longer than necessary.

s3 = [[AmazonS3Client alloc] initWithCredentialsProvider:provider];

// Extended timeout because are working with larger files
s3.timeout = 600;

// Shorten connectionTimeout to fail fast (for iOS 6+)
s3.connectionTimeout = 60;

Retrying Failed Requests

If a request fails, it may be desirable to retry the request depending on the class of error that occurred. The AWS SDK for iOS will automatically retry on connection timeouts and certain service exceptions. The specific retry logic can always been seen in the source at our GitHub repo. This retry logic is used only if the request was executed synchronously (see our previous post about synchronous vs. asynchronous requests). For asynchronous requests using AmazonRequestDelegate, you are responsible for implementing your retry logic; in request:didFailWithError: or request:didFailWithServiceException:. You’ll also need to construct a new request object and pass it to the service client to process again. Reviewing the source code of the S3TransferManager in our GitHub repo will give some examples of how to do this.

For synchronous requests, we can control how many retries will occur via the service client’s maxRetries property. Be careful when increasing this value over the default value of 5, particularly if you’ve increased the timeout values for the client.

dynamodb = [[AmazonDynamoDBClient alloc] initWithCredentialsProvider:provider];

// Expect DynamoDB to be fast to respond (for iOS 6+)
dynamodb.timeout = 60; // connectionTimeout = 60 implied

// Increase retries because DynamoDB may throw provisioned throughput exceptions
// See the DynamoDB Developer guide for more information on provisioned throughput
// http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html
dynamodb.maxRetries = 10;

Retries and S3TransferManager

A special feature of the S3TransferManager is that even when operating in asynchronous mode, file and part uploads will be retried. In this context, maxRetries will reflect how many times the S3TransferManager will retry any one request (S3PutObjectRequest, S3InitiateMultipartUploadRequest, S3UploadPartRequest, or S3CompleteMultipartUploadRequest).

We hope this post gives you the information necessary to help build stable and resilient mobile apps with the AWS SDK for iOS. We are eager for feedback and we want to know what other challenges developers face when building cloud-backed mobile apps. Please feel free to leave a comment below or visit our forums to post feedback and questions.

We’re hiring

If you like building mobile applications that use cloud services that our customers use on a daily basis, perhaps you would like to join the AWS Mobile SDK and Tools team. We are hiring Software Developers, Web Developers, and Product Managers.