How does Exponential Backoff work?

Avinash Kumar
Bobble Engineering
Published in
3 min readMar 18, 2023

--

Exponential Backoff is a popular technique used to handle HTTP requests that fail due to network issues or server errors. When an HTTP request fails, the traditional approach is to simply retry the request after a certain interval of time. However, this can result in multiple failed requests and may even overload the server.

To address this issue, we can use the Exponential Backoff technique in the HTTP Interceptor. In this blog, we will explore how to implement Exponential Backoff in the HTTP Interceptor in Android.

What is an HTTP Interceptor?

An HTTP Interceptor is an object that intercepts outgoing HTTP requests and incoming HTTP responses. It is used to add or remove headers, modify request or response data, or perform other actions before the request or response is sent or received.

How does Exponential Backoff work?

Exponential Backoff is a technique that increases the waiting time between retries exponentially. This means that the waiting time between each retry is multiplied by a factor that increases with each retry. For example, the first retry may wait for 1 second, the second retry may wait for 2 seconds, the third retry may wait for 4 seconds, and so on.

This technique reduces the number of failed requests and prevents server overload by gradually increasing the waiting time between retries.

How to implement Exponential Backoff in the HTTP Interceptor in Android?

To implement Exponential Backoff in the HTTP Interceptor in Android, we can use the okhttp3.Interceptor interface. This interface intercepts outgoing HTTP requests and incoming HTTP responses. Here is a sample code snippet:

class ExponentialBackoffInterceptor : Interceptor {
private var retryCount = 0

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()

var waitingTimeForClient = System.currentTimeMillis - lastNetworkCall
val waitTime = (Math.pow(2.0, retryCount.toDouble()) * 1000).toLong()

if (waitingTimeForClient < waitTime && retryCount < MAX_RETRY) {
throw IOException("ExponentialBackoffInterceptorIOException ${waitTime}ms")
}

var response = chain.proceed(request)

if (response.isSuccessful) {
Log.d(TAG, "Api call: Successful")
lastNetworkCall = System.currentTimeMillis()
retryCount = 0 // resetting to 0
} else {
Log.d(TAG, "Api call: Not Successful")
lastNetworkCall = System.currentTimeMillis()
retryCount += 1 // Increment every time
}

return response
}
}

In this code, we first create an instance of the Interceptor interface and implement the intercept() method. We then create a variable waitintTimeForClient to keep track of how much time client have to wait for more for the next API call.

Inside the intercept() method, we first get the current HTTP request using chain.request(). We then execute the request using chain.proceed(request) and storing the response in the response variable.

If the request fails, we update the lateNetworkCall time and calculate the waiting time using the formula (Math.pow(2.0, retryCount.toDouble()) * 1000).toLong(). We then wait for the calculated time by throwing our custom error using throw IOException(message) which let the request on hold until the wait time is completed and proceed request using chain.proceed(request).

We repeat this process whenever client makes an API request until the request is successful or we have reached the maximum number of retries defined by the MAX_RETRIES variable. We then reset the retryCount to 0 after a successful request and return the final response.

Conclusion

In this blog, we have explored how to implement a simple flow of Exponential Backoff in the HTTP Interceptor in Android. This technique helps prevent server overload and reduces the number of failed requests by gradually increasing the waiting time between retries. You can further customize it as per your need.

By using the code snippet provided above, you can easily implement Exponential Backoff in your own Android application.

--

--