API Error Retries

This section describes how to handle client and server errors.

[Note]Note

For information on specific error messages, see API Error Codes

Client Errors

Do not retry client errors. Client errors indicate that Amazon SimpleDB found a problem with the client request and the application should address the issue before submitting the request again.

SOAP client errors are indicated by the Client prefix and REST client errors are indicated by a 4xx HTTP response code.

Server Errors

For server errors, you should retry the requests.

SOAP server errors are indicated by the Server prefix and REST server errors are indicated by a 5xx HTTP response code.

Retries and Exponential Backoff

Building applications that work well in a networked environment with unpredictable latencies opens a new set of potential error conditions when compared to typical desktop or client-server applications. Invoking requests to a web service such as Amazon SimpleDB, whether over the Internet or from an Amazon EC2 instance within the Amazon cloud, requires application designers to consider issues such as network connectivity, request timeouts, and remote errors due to overload or throttling. There are numerous components on the network, such as DNS servers, switches, load-balancers, and others that could generate errors anywhere in the life of a given request.

After a request arrives at the service, Amazon SimpleDB uses the following standard HTTP error codes to communicate server and overload errors through the REST interface.

  • HTTP 500 - Internal Server Error

  • HTTP 503 - Service Unavailable (system overload message)

The following is a list of error codes that Amazon SimpleDB uses to communicate server and overload errors through the SOAP interface.

  • Server.InternalError - Internal Server Error (equivalent to HTTP 500 error)

  • Server.ServiceUnavailable - Service is currently unavailable (equivalent to HTTP 503 error)

The usual technique for dealing with these error responses in a networked environment is to implement retries in the client application layer, regardless of whether those errors come from the service itself or any component on the network between Amazon SimpleDB and client application. This technique increases the reliability of the applications and reduces operational costs for the developer.

In addition to simple retries, we recommend using an exponential backoff algorithm for better flow control. The concept behind exponential backoff is to use progressively longer waits between retries for consecutive error responses. For example, up to 400 milliseconds before the first retry, up to 1600 milliseconds before the second, up to 6400 milliseconds before third, and so on.

Following is a sample exponential backoff algorithm in Java.

 currentRetry = 0
 DO
   status = execute Amazon SimpleDB request
   IF status = success OR status = client error (4xx)
     set retry to false
     process the response or client error as appropriate
   ELSE
     set retry to true
     currentRetry = currentRetry + 1
     wait for a random delay between 0 and (4^currentRetry * 100) milliseconds
   END-IF
 WHILE (retry = true AND currentRetry < MaxNumberOfRetries)

Following is a snippet of Java code that implements the exponential backoff.

 boolean shouldRetry = true;
 int retries = 0;
 do {
   try {
    /* Submit request to Amazon SimpleDB*/
     if (status == HttpStatus.SC_OK) {
       shouldRetry = false;
      /* Process successful response from Amazon SimpleDB */
     } else {
       if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR
	      || status == HttpStatus.SC_SERVICE_UNAVAILABLE) {
	 shouldRetry = true;
	 long delay = (long) (Math.random() * (Math.pow(4, retries++) * 100L));
	 try {
	   Thread.sleep(delay);
	 } catch (InterruptedException iex){
	   log.error("Caught InterruptedException exception", iex);
	 }
       } else {
	 shouldRetry = false;
	/* Process 4xx (Client) error */
       }
     }
   } catch (IOException ioe) {
     log.error("Caught IOException exception", ioe);
   } catch (Exception e) {
     log.error("Caught Exception", e);
   } finally {
     /* Perform clean-up as necessary */
   }
 } while (shouldRetry && retries < MAX_NUMBER_OF_RETRIES);

To download a complete Java code sample that implements the exponential backoff algorithm, go to the Amazon sample libraries.