Why Fast‑Retry Outperforms Spring‑Retry for Million‑Task Scenarios

Fast‑Retry is a high‑performance asynchronous retry framework that can handle millions of tasks with far lower latency than traditional synchronous retry libraries like Spring‑Retry or Guava‑Retry, thanks to its non‑blocking design, customizable retry logic, and support for both programmatic and annotation‑based usage.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Fast‑Retry Outperforms Spring‑Retry for Million‑Task Scenarios

Introduction

When a system needs to poll and retry identity information for one million users, using single‑task synchronous retry frameworks such as Spring‑Retry or Guava‑Retry will take an impractically long time, even with many machines or threads; Fast‑Retry was created for exactly this scenario.

What is Fast‑Retry

Fast‑Retry is a high‑performance multi‑task retry framework that supports asynchronous retry for millions of tasks. It offers both programmatic and annotation‑based APIs and allows custom result‑retry logic. Unlike Spring‑Retry and Guava‑Retry, which are synchronous and consume a thread per retry, Fast‑Retry performs retries asynchronously, dramatically increasing throughput.

Performance Comparison

The benchmark uses an 8‑thread fixed pool, each task polls five times with a 2‑second interval (total 10 seconds per task). The expected total time is calculated as:

Test thread pool: 8 fixed threads

Single task logic: 5 polls, 2 seconds between retries, total 10 seconds

Estimated formula: total time ≈ (task count / concurrency) × single‑task time

Task Count | Fast‑Retry | Spring‑Retry | Guava‑Retry
-----------|------------|--------------|------------
1          | 10.0 s     | 10.0 s       | 10.0 s
10         | 10.066 s   | 20.092 s     | 20.078 s
50         | 10.061 s   | 70.186 s     | 70.168 s
100        | 10.077 s   | 130.33 s     | 130.31 s
500        | 10.154 s   | 631.420 s    | 631.53 s
1 000      | 10.237 s   | 1254.78 s    | 1256.28 s
5 000      | 10.482 s   | 6250 s (estimated) | 6250 s (estimated)
10 000     | 10.686 s   | 12520 s (estimated) | 12520 s (estimated)
100 000    | 13.71 s    | 125000 s (estimated) | 125000 s (estimated)
1 000 000  | 58.05 s    | 1250000 s (estimated) | 1250000 s (estimated)

The results show that even with one million tasks, Fast‑Retry finishes in about 58 seconds, while Spring‑Retry and Guava‑Retry would take over a million seconds, demonstrating a massive performance advantage.

Quick Start

Adding the Dependency

<dependency>
    <groupId>io.github.burukeyou</groupId>
    <artifactId>fast-retry-all</artifactId>
    <version>0.2.0</version>
</dependency>

Using a Retry Queue

ExecutorService executorService = Executors.newFixedThreadPool(8);
RetryQueue queue = new FastRetryQueue(executorService);
RetryTask<String> task = new RetryTask<String>() {
    int result = 0;
    @Override
    public long waitRetryTime() { return 2000; }
    @Override
    public boolean retry() { return ++result < 5; }
    @Override
    public String getResult() { return result + ""; }
};
CompletableFuture<String> future = queue.submit(task);
log.info("Task finished, result:{}", future.get());

Using FastRetryBuilder

RetryResultPolicy<String> resultPolicy = result -> result.equals("444");
FastRetryer<String> retryer = FastRetryBuilder.<String>builder()
        .attemptMaxTimes(3)
        .waitRetryTime(3, TimeUnit.SECONDS)
        .retryIfException(true)
        .retryIfExceptionOfType(TimeoutException.class)
        .exceptionRecover(true)
        .resultPolicy(resultPolicy)
        .build();
CompletableFuture<String> future = retryer.submit(() -> {
    log.info("retry");
    if (0 < 10) {
        throw new TimeoutException("test");
    }
    return "444";
});
String o = future.get();
log.info("Result {}", o);

Using @FastRetry Annotation

@FastRetry(retryWait = @RetryWait(delay = 2))
public String retryTask() {
    return "success";
}

@FastRetry(retryWait = @RetryWait(delay = 2))
public CompletableFuture<String> retryTask() {
    return CompletableFuture.completedFuture("success");
}

Custom Retry Annotation

If a more business‑specific annotation is needed, define a new annotation, mark it with @FastRetry, specify a custom factory, and implement AnnotationRetryTaskFactory. The default implementation is FastRetryAnnotationRetryTaskFactory.

Usage Recommendations

Regardless of the construction method, prefer asynchronous retry (returning CompletableFuture) and use whenComplete to handle the result.

Comparison Case: Weather Service

A weather‑fetching service that may need up to 100 retries per city is implemented with both Fast‑Retry and Spring‑Retry. When fetching weather for 1 000 cities, Spring‑Retry takes about 1 250 seconds, while Fast‑Retry completes in roughly 10 seconds.

// Fast‑Retry method
@FastRetry(maxAttempts = 100, retryWait = @RetryWait(delay = 2, timeUnit = TimeUnit.SECONDS))
public CompletableFuture<WeatherResult> getFutureWeatherForCompare(String cityName) {
    log.info("Fast‑Retry attempt:{} city:{}", ++index, cityName);
    WeatherResult weather = WeatherServer.getWeather(cityName);
    if (weather == null) {
        throw new RuntimeException("simulate exception for retry");
    }
    return FastRetryBuilder.of(weather);
}

// Spring‑Retry method
@Retryable(maxAttempts = 100, backoff = @Backoff(delay = 2000))
public WeatherResult getSpringWeatherForCompare(String cityName) {
    log.info("Spring‑Retry attempt:{} city:{}", ++index, cityName);
    WeatherResult weather = WeatherServer.getWeather(cityName);
    if (weather == null) {
        throw new RuntimeException("simulate exception for retry");
    }
    return weather;
}

Project Link

https://github.com/burukeYou/fast-retry

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaPerformanceSpringAsyncfast-retry
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.