A production-grade background job processing system built with Spring Boot and Redis Streams — designed for ordered, fault-tolerant, duplicate-free job execution.
This project implements a distributed job queue using Redis Streams as the messaging backbone. Clients submit jobs via a REST API; a producer enqueues them into a Redis Stream; a worker consumer processes them sequentially and acknowledges completion.
| Guarantee | Mechanism |
|---|---|
| Ordered execution | Redis Stream FIFO semantics |
| Persistence across restarts | Redis Stream log durability |
| Worker failure recovery | Consumer group re-delivery |
| Duplicate prevention | Job ID deduplication in JobService |
- Client sends a
POSTrequest with a job payload - JobController receives and delegates to
JobService - JobService validates the job and checks for duplicates
- JobProducer publishes the job to the Redis Stream via
XADD - JobConsumer reads jobs from the stream via
XREADGROUP - Worker processes each job sequentially
- Completed jobs are acknowledged (
XACK) and cleared from the pending list
| Layer | Technology |
|---|---|
| Language | Java |
| Framework | Spring Boot |
| Queue / Messaging | Redis Streams (Valkey compatible) |
| Database | Redis / Valkey |
| Containerization | Docker |
| Build Tool | Maven |
redis-stream-example/
└── src/main/java/com/example/redisstream/
├── controller/
│ └── JobController.java # REST API — add, list, health
├── service/
│ └── JobService.java # Validation + deduplication logic
├── producer/
│ └── JobProducer.java # Publishes jobs to Redis Stream
├── consumer/
│ └── JobConsumer.java # Subscribes + processes + ACKs
├── config/
│ └── RedisStreamConfig.java # Stream + consumer group setup
└── RedisStreamExampleApplication.java
JobProducer.java — Receives job requests from the API and publishes them into the Redis Stream using XADD.
JobConsumer.java — Subscribes to the Redis stream via a consumer group, processes jobs sequentially, and acknowledges each completed job with XACK.
JobService.java — Core business logic handling job validation, duplicate prevention, and queue state management.
JobController.java — Spring Boot REST controller exposing endpoints to submit jobs, list queued jobs, and check worker health.
RedisStreamConfig.java — Configures the Redis Stream connection, consumer groups, and stream listener container.
POST /redis-stream-example/v1/jobs/start
Content-Type: application/jsonRequest Body:
{
"id": 1,
"name": "example job"
}cURL:
curl -X POST http://localhost:8080/redis-stream-example/v1/jobs/start \
-H 'Content-Type: application/json' \
-d '{"id":1,"name":"example job"}'GET /redis-stream-example/v1/jobs/queuedcurl http://localhost:8080/redis-stream-example/v1/jobs/queuedGET /redis-stream-example/actuator/healthVerifies: Redis stream connection · worker subscription · overall application health
curl http://localhost:8080/redis-stream-example/actuator/healthStep 1 — Start Redis / Valkey
docker run -p 6379:6379 valkey/valkeyStep 2 — Run the application
mvn spring-boot:runServer starts at → http://localhost:8080
1. Start Redis or Valkey
redis-server
# or
valkey-server2. Build the project
mvn clean install3. Run the application
mvn spring-boot:run| Property | Description |
|---|---|
| Ordered Execution | Jobs processed in exact submission order |
| Persistence | Jobs survive application restarts via Redis Stream log |
| Worker Recovery | Unacknowledged jobs are re-delivered after worker failure |
| Deduplication | Duplicate job IDs are rejected before entering the queue |
This architecture scales horizontally without code changes:
- Multiple consumers — Add more
JobConsumerinstances to parallelize processing - Stream partitioning — Distribute load across multiple Redis Streams by key
- Horizontal API scaling — Stateless Spring Boot layer supports multiple replicas
- Redis Cluster — Scale the message broker across nodes for high availability
- Job retry with exponential backoff
- Priority queues for urgent job types
- Distributed worker pools across services
- Job monitoring dashboard (status, throughput, lag)
- Dead letter queue (DLQ) for persistently failed jobs
MIT © Bathula Ganesh
