#1
Many applications need to perform tasks that should not block the main request, such as sending emails, processing files, or generating reports. Instead of executing these tasks immediately, they can be placed in a task queue and processed asynchronously by background workers.
Redis provides fast data structures that make it ideal for building distributed task queues. This article explains how to implement a simple task queue using Redis and Spring Boot.

1. What Is a Task Queue

A task queue separates job creation from job processing.
Workflow:
Client Request → Application → Redis Queue → Worker Service
  1. Application adds a task to Redis.
  2. Worker processes tasks from the queue.
  3. Results are handled asynchronously.
Benefits:
  • Faster API responses
  • Better scalability
  • Reliable background processing

2. Using Redis Lists as a Queue

Redis Lists support queue operations such as push and pop. Common operations:
LPUSH  → Add task to queue
RPOP   → Remove task from queue
Queue structure:
task-queue
 ├── task1
 ├── task2
 └── task3

3. Creating a Task Producer

The producer adds tasks to the Redis queue.
Example service:
@Service
public class TaskProducer {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String QUEUE = "task-queue";

    public void addTask(String task) {
        redisTemplate.opsForList().leftPush(QUEUE, task);
    }
}
Example task:
send-email:user123
generate-report:order456

4. Creating a Worker to Process Tasks

Workers continuously pull tasks from the queue.
@Service
public class TaskWorker {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String QUEUE = "task-queue";

    @Scheduled(fixedDelay = 2000)
    public void processTasks() {

        String task = redisTemplate.opsForList().rightPop(QUEUE);

        if (task != null) {
            System.out.println("Processing task: " + task);
        }
    }
}
This worker checks the queue every two seconds.

5. Blocking Queue Processing

A better approach is using blocking operations, which wait for tasks instead of polling.
Example:
ListOperations<String, String> ops = redisTemplate.opsForList();

String task = ops.rightPop("task-queue", 10, TimeUnit.SECONDS);
The worker waits up to 10 seconds for a task before checking again.
Benefits:
  • Lower CPU usage
  • Faster task processing

6. Adding Tasks via REST API

Create an endpoint to enqueue tasks.
@RestController
@RequestMapping("/tasks")
public class TaskController {

    @Autowired
    private TaskProducer producer;

    @PostMapping
    public String addTask(@RequestParam String task) {
        producer.addTask(task);
        return "Task added";
    }
}
Example request:
POST /tasks?task=send-email:user123

7. Scaling Workers

Redis queues allow multiple workers to process tasks simultaneously.
Example:
Redis Queue
   ↓
Worker 1
Worker 2
Worker 3
Each worker pulls different tasks from the queue, increasing throughput.

8. Handling Failed Tasks

If a worker crashes during processing, the task may be lost.
A common solution is retry queues:
task-queue
retry-queue
failed-queue
Failed tasks move to a retry queue for later processing.
#ads

image quote pre code