retry vs p-retry vs promise-retry vs async-retry vs retry-axios
JavaScript Retry Libraries Comparison
1 Year
retryp-retrypromise-retryasync-retryretry-axiosSimilar Packages:
What's JavaScript Retry Libraries?

Retry libraries in JavaScript provide mechanisms to handle transient failures in asynchronous operations by automatically retrying them a specified number of times before failing. These libraries are particularly useful for network requests, database operations, or any other operations that may fail intermittently. They help improve the resilience of applications by managing retries systematically, allowing developers to focus on core logic without worrying about error handling for transient issues.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
retry41,243,4711,243-194 years agoMIT
p-retry16,863,12183313.2 kB174 months agoMIT
promise-retry15,687,979315-115 years agoMIT
async-retry10,574,7231,865-304 years agoMIT
retry-axios918,85349536.4 kB34a year agoApache-2.0
Feature Comparison: retry vs p-retry vs promise-retry vs async-retry vs retry-axios

Retry Strategy

  • retry:

    retry offers a simple API for retries with options for both synchronous and asynchronous functions. You can customize the retry count and delay, making it adaptable to various use cases.

  • p-retry:

    p-retry supports exponential backoff by default, meaning that the delay between retries increases exponentially with each failed attempt. This is particularly useful for reducing load on services that may be temporarily overwhelmed.

  • promise-retry:

    promise-retry provides a straightforward retry mechanism where you can define the number of retries and a delay function. It allows for flexibility in defining how retries should be handled without enforcing a specific strategy.

  • async-retry:

    async-retry allows you to define a custom retry strategy, including the number of retries and delay between attempts. You can specify a delay function that can vary based on the attempt number, enabling more sophisticated retry logic.

  • retry-axios:

    retry-axios integrates retry logic directly into Axios requests, allowing you to specify retry options such as the number of retries and delay directly in the Axios configuration.

Ease of Use

  • retry:

    retry has a slightly more complex API due to its support for both synchronous and asynchronous functions, but it remains accessible for developers who need a versatile solution.

  • p-retry:

    p-retry is also user-friendly, especially for those familiar with promises. Its API is clean and concise, making it easy to use in modern JavaScript applications that leverage async/await.

  • promise-retry:

    promise-retry is easy to use and integrates well with existing promise-based code. Its simplicity allows developers to add retry functionality with minimal effort, making it a good choice for quick implementations.

  • async-retry:

    async-retry is designed to be simple and intuitive, making it easy to integrate into existing codebases. Its API is straightforward, allowing developers to quickly implement retry logic without extensive boilerplate code.

  • retry-axios:

    retry-axios is very easy to use for those already using Axios, as it requires minimal configuration to add retry capabilities to HTTP requests.

Customizability

  • retry:

    retry is highly customizable, allowing developers to define their own retry conditions and strategies, making it suitable for a wide range of applications.

  • p-retry:

    p-retry offers built-in options for customizing retry behavior, including the ability to set conditions for retries and adjust backoff strategies, providing flexibility for developers.

  • promise-retry:

    promise-retry allows customization of retry counts and delays, but it does not enforce a specific strategy, giving developers the freedom to implement their own logic as needed.

  • async-retry:

    async-retry allows for extensive customization of retry logic, including dynamic delays and conditions for retrying, making it suitable for complex use cases where default behavior may not suffice.

  • retry-axios:

    retry-axios allows customization of retry options directly in the Axios request configuration, making it easy to tailor retry behavior for specific API calls.

Integration

  • retry:

    retry can be used in both synchronous and asynchronous contexts, making it versatile for different types of applications, including those that do not rely solely on promises.

  • p-retry:

    p-retry is designed for promise-based workflows, making it a great fit for modern JavaScript applications that utilize async/await, ensuring seamless integration with existing code.

  • promise-retry:

    promise-retry is also designed for promise-based workflows, allowing it to fit naturally into applications that rely heavily on promises and async/await syntax.

  • async-retry:

    async-retry can be used independently and integrates well with any asynchronous code, making it versatile for various applications beyond just HTTP requests.

  • retry-axios:

    retry-axios is specifically tailored for use with Axios, making it the best choice for developers already using Axios for HTTP requests, ensuring smooth integration.

Community and Maintenance

  • retry:

    retry has been around for a while and is actively maintained, making it a stable choice for developers needing a general-purpose retry solution.

  • p-retry:

    p-retry is also actively maintained, with a focus on modern JavaScript practices, making it a reliable choice for developers looking for a robust solution.

  • promise-retry:

    promise-retry is well-maintained and has a solid user base, providing confidence in its reliability and continued support.

  • async-retry:

    async-retry is actively maintained and has a growing community, ensuring that it stays up-to-date with the latest JavaScript features and best practices.

  • retry-axios:

    retry-axios is actively maintained and benefits from the popularity of Axios, ensuring that it remains compatible with the latest versions of Axios and JavaScript.

How to Choose: retry vs p-retry vs promise-retry vs async-retry vs retry-axios
  • retry:

    Use retry if you require a more general-purpose retry mechanism that can handle both synchronous and asynchronous functions. This package is versatile and can be used in various contexts, including both Node.js and browser environments.

  • p-retry:

    Opt for p-retry if you prefer a promise-based approach with built-in support for exponential backoff. This package is ideal for handling retries in modern JavaScript applications that heavily utilize promises and async/await syntax.

  • promise-retry:

    Select promise-retry if you need a straightforward promise-based retry mechanism that allows for custom retry strategies. It is suitable for scenarios where you want to control the retry behavior explicitly without additional complexity.

  • async-retry:

    Choose async-retry if you need a simple and flexible retry mechanism that supports both promises and callbacks. It allows for custom retry delays and is particularly useful for Node.js applications where you want to handle asynchronous operations gracefully.

  • retry-axios:

    Choose retry-axios if you are specifically working with Axios for HTTP requests and want to add retry functionality seamlessly. This package integrates directly with Axios, providing a simple way to add retry logic to your API calls.

README for retry

Build Status codecov

retry

Abstraction for exponential and custom retry strategies for failed operations.

Installation

npm install retry

Current Status

This module has been tested and is ready to be used.

Tutorial

The example below will retry a potentially failing dns.resolve operation 10 times using an exponential backoff strategy. With the default settings, this means the last attempt is made after 17 minutes and 3 seconds.

var dns = require('dns');
var retry = require('retry');

function faultTolerantResolve(address, cb) {
  var operation = retry.operation();

  operation.attempt(function(currentAttempt) {
    dns.resolve(address, function(err, addresses) {
      if (operation.retry(err)) {
        return;
      }

      cb(err ? operation.mainError() : null, addresses);
    });
  });
}

faultTolerantResolve('nodejs.org', function(err, addresses) {
  console.log(err, addresses);
});

Of course you can also configure the factors that go into the exponential backoff. See the API documentation below for all available settings. currentAttempt is an int representing the number of attempts so far.

var operation = retry.operation({
  retries: 5,
  factor: 3,
  minTimeout: 1 * 1000,
  maxTimeout: 60 * 1000,
  randomize: true,
});

API

retry.operation([options])

Creates a new RetryOperation object. options is the same as retry.timeouts()'s options, with three additions:

  • forever: Whether to retry forever, defaults to false.
  • unref: Whether to unref the setTimeout's, defaults to false.
  • maxRetryTime: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is Infinity.

retry.timeouts([options])

Returns an array of timeouts. All time options and return values are in milliseconds. If options is an array, a copy of that array is returned.

options is a JS object that can contain any of the following keys:

  • retries: The maximum amount of times to retry the operation. Default is 10. Seting this to 1 means do it once, then retry it once.
  • factor: The exponential factor to use. Default is 2.
  • minTimeout: The number of milliseconds before starting the first retry. Default is 1000.
  • maxTimeout: The maximum number of milliseconds between two retries. Default is Infinity.
  • randomize: Randomizes the timeouts by multiplying with a factor between 1 to 2. Default is false.

The formula used to calculate the individual timeouts is:

Math.min(random * minTimeout * Math.pow(factor, attempt), maxTimeout)

Have a look at this article for a better explanation of approach.

If you want to tune your factor / times settings to attempt the last retry after a certain amount of time, you can use wolfram alpha. For example in order to tune for 10 attempts in 5 minutes, you can use this equation:

screenshot

Explaining the various values from left to right:

  • k = 0 ... 9: The retries value (10)
  • 1000: The minTimeout value in ms (1000)
  • x^k: No need to change this, x will be your resulting factor
  • 5 * 60 * 1000: The desired total amount of time for retrying in ms (5 minutes)

To make this a little easier for you, use wolfram alpha to do the calculations:

http://www.wolframalpha.com/input/?i=Sum%5B1000*x^k%2C+{k%2C+0%2C+9}%5D+%3D+5+*+60+*+1000

retry.createTimeout(attempt, opts)

Returns a new timeout (integer in milliseconds) based on the given parameters.

attempt is an integer representing for which retry the timeout should be calculated. If your retry operation was executed 4 times you had one attempt and 3 retries. If you then want to calculate a new timeout, you should set attempt to 4 (attempts are zero-indexed).

opts can include factor, minTimeout, randomize (boolean) and maxTimeout. They are documented above.

retry.createTimeout() is used internally by retry.timeouts() and is public for you to be able to create your own timeouts for reinserting an item, see issue #13.

retry.wrap(obj, [options], [methodNames])

Wrap all functions of the obj with retry. Optionally you can pass operation options and an array of method names which need to be wrapped.

retry.wrap(obj)

retry.wrap(obj, ['method1', 'method2'])

retry.wrap(obj, {retries: 3})

retry.wrap(obj, {retries: 3}, ['method1', 'method2'])

The options object can take any options that the usual call to retry.operation can take.

new RetryOperation(timeouts, [options])

Creates a new RetryOperation where timeouts is an array where each value is a timeout given in milliseconds.

Available options:

  • forever: Whether to retry forever, defaults to false.
  • unref: Wether to unref the setTimeout's, defaults to false.

If forever is true, the following changes happen:

  • RetryOperation.errors() will only output an array of one item: the last error.
  • RetryOperation will repeatedly use the timeouts array. Once all of its timeouts have been used up, it restarts with the first timeout, then uses the second and so on.

retryOperation.errors()

Returns an array of all errors that have been passed to retryOperation.retry() so far. The returning array has the errors ordered chronologically based on when they were passed to retryOperation.retry(), which means the first passed error is at index zero and the last is at the last index.

retryOperation.mainError()

A reference to the error object that occured most frequently. Errors are compared using the error.message property.

If multiple error messages occured the same amount of time, the last error object with that message is returned.

If no errors occured so far, the value is null.

retryOperation.attempt(fn, timeoutOps)

Defines the function fn that is to be retried and executes it for the first time right away. The fn function can receive an optional currentAttempt callback that represents the number of attempts to execute fn so far.

Optionally defines timeoutOps which is an object having a property timeout in miliseconds and a property cb callback function. Whenever your retry operation takes longer than timeout to execute, the timeout callback function cb is called.

retryOperation.try(fn)

This is an alias for retryOperation.attempt(fn). This is deprecated. Please use retryOperation.attempt(fn) instead.

retryOperation.start(fn)

This is an alias for retryOperation.attempt(fn). This is deprecated. Please use retryOperation.attempt(fn) instead.

retryOperation.retry(error)

Returns false when no error value is given, or the maximum amount of retries has been reached.

Otherwise it returns true, and retries the operation after the timeout for the current attempt number.

retryOperation.stop()

Allows you to stop the operation being retried. Useful for aborting the operation on a fatal error etc.

retryOperation.reset()

Resets the internal state of the operation object, so that you can call attempt() again as if this was a new operation object.

retryOperation.attempts()

Returns an int representing the number of attempts it took to call fn before it was successful.

License

retry is licensed under the MIT license.

Changelog

0.10.0 Adding stop functionality, thanks to @maxnachlinger.

0.9.0 Adding unref functionality, thanks to @satazor.

0.8.0 Implementing retry.wrap.

0.7.0 Some bug fixes and made retry.createTimeout() public. Fixed issues #10, #12, and #13.

0.6.0 Introduced optional timeOps parameter for the attempt() function which is an object having a property timeout in milliseconds and a property cb callback function. Whenever your retry operation takes longer than timeout to execute, the timeout callback function cb is called.

0.5.0 Some minor refactoring.

0.4.0 Changed retryOperation.try() to retryOperation.attempt(). Deprecated the aliases start() and try() for it.

0.3.0 Added retryOperation.start() which is an alias for retryOperation.try().

0.2.0 Added attempts() function and parameter to retryOperation.try() representing the number of attempts it took to call fn().