« Back to Index

Go: Exponential Backoff

View original Gist on GitHub

Tags: #go #backoff #retry #resilience

main.go

package main

import (
	"context"
	"errors"
	"fmt"
	"math"
	"time"
)

func main() {
	if err := doSomething(); err != nil {
		fmt.Println("there was an error:", err)
	}
}

func doSomething() error {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	var (
		// initialBackoff is the initial backoff used for exponential backoff
		initialBackoff = 100 * time.Millisecond
		// is the maximum value to use for exponential backoff
		maxBackoff = 500 * time.Millisecond
		// maxRetries is the number of retries
		maxRetries = 3
	)
	for attempt := range maxRetries {
		// exponential backoff
		backoff := time.Duration(math.Pow(2, float64(attempt+1))) * initialBackoff
		if backoff > maxBackoff {
			backoff = maxBackoff
		}
		fmt.Println(backoff)

		select {
		case <-ctx.Done():
			return errors.New("whoops: timeout")
		case <-time.After(backoff):
			// continue
		}
	}
	return errors.New("unable to perform the task, max retries exceeded")
}