A highly scalable, distributed task scheduling system engineered in Go, backed by Redis and PostgreSQL
Overview: Designed to mirror production-grade backend systems, this project implements a resilient background job processing architecture. It decouples synchronous execution (like sending emails) into a highly available, asynchronous queue processed by horizontally scalable worker nodes, ensuring absolute reliability and idempotency even under systemic stress.
Built with production-grade system design principles in mind, focusing on reliability, horizontal scalability, and data consistency.
- ⚡ Asynchronous Distributed Processing: Utilizes Redis as an in-memory message broker. Independent worker nodes consume jobs via blocking pop operations (
BRPOP), eliminating busy-waiting and minimizing latency. - 🛡️ Bulletproof Idempotency (L1/L2 Caching Layer): Implements exactly-once execution semantics. Employs Redis (
SetNXwith TTL) as an ultra-fast L1 cache to short-circuit duplicates, backed by PostgreSQL as an L2 persistent store withUNIQUEconstraints to guarantee data integrity. - 🔁 Intelligent Fault Tolerance: Features an exponential backoff retry mechanism (
1s → 2s → 4s → 8s) for transient failures, preventing cascading system overloads. - ☠️ Dead Letter Queue (DLQ): Jobs exceeding maximum retries are safely persisted to a persistent DLQ for manual intervention, observability, and debugging.
- 🔐 Secure API Boundaries: Strict JWT-based authentication for all external system interactions.
- 🐳 Containerized & Orchestrated: Fully Dockerized environment ensuring identical parity between development and production deployments.
graph TD
Client(["👤 Client"]) -->|"JWT Auth Request"| API["⚡ API Server"]
API -->|"O(1) Enqueue"| Redis[("Redis Broker")]
subgraph "Worker Cluster (Horizontally Scalable)"
Worker1["Worker Node 1"]
Worker2["Worker Node 2"]
WorkerN["Worker Node N"]
end
Redis -->|"BRPOP Consume"| Worker1
Redis -->|"BRPOP Consume"| Worker2
Redis -->|"BRPOP Consume"| WorkerN
Worker1 -->|"Execute Task"| External["External Service / SMTP"]
Worker1 -.->|"Retry Exhausted"| DLQ[("Dead Letter Queue")]
subgraph "Idempotency Layer"
RedisCache[("Redis Cache L1")]
PostgresDB[("PostgreSQL L2")]
end
Worker1 <-->|"SetNX TTL Check"| RedisCache
Worker1 <-->|"Persistent Check"| PostgresDB
├── cmd/
│ ├── api/ # Main API server entrypoint & HTTP handlers
│ └── worker/ # Worker node entrypoint & background processing logic
├── internals/
│ ├── db/ # Database connection & pooling setup
│ ├── redis/ # Redis client & queue management
│ └── store/ # Data access layer (PostgreSQL repositories)
├── migrations/ # SQL schema migrations (up/down)
├── docker-compose.yml # Container orchestration
└── Dockerfile # Multi-stage build for Go services
In distributed systems, network partitions or process crashes can lead to duplicate message deliveries. This system guarantees exactly-once execution side-effects (e.g., a user is never sent two welcome emails).
-
L1 Fast-Path (Redis): Uses
SET key value NX EX 86400for$O(1)$ atomic duplicate detection. Prevents DB bottlenecking. - L2 Slow-Path (PostgreSQL): Fallback check against a durable relational table to ensure correctness across Redis cache evictions or worker failures.
[Worker Acquires Job]
│
▼
[Redis SetNX (L1 Cache)] ──(Exists)──> 🛑 SKIP (Idempotent)
│
(Not Found)
▼
[Postgres Check (L2 Store)] ──(Exists)──> 🛑 SKIP (Idempotent)
│
(Not Found)
▼
🚀 Execute Business Logic (e.g., Send Email)
│
▼
💾 Update Postgres & Redis State
- Docker Engine & Docker Compose
- Optional: Go 1.21+ (if running bare-metal)
Launch the API, Database, Redis broker, and a Worker node instantly:
docker-compose up --buildSimulate a high-throughput environment by dynamically scaling the worker pool:
docker-compose up --scale worker=5👀 View Scaled Output Logs
worker-1 | Worker: f82a11f88c4e processing job: job_abc123
worker-2 | Worker: 7dbf03042e66 processing job: job_def456
worker-5 | Worker: 607a7ab9242c processing job: job_ghi789
worker-1 | Successfully sent welcome email to user1@example.com
worker-2 | Successfully sent welcome email to user2@example.com
Notice how traffic is distributed perfectly across the node cluster.
| Endpoint | Method | Functionality | Auth Needed |
|---|---|---|---|
/addJob |
POST |
Atomically enqueues a new background task | 🔐 Bearer JWT |
/failedJobs |
GET |
Fetches paginated jobs from the Dead Letter Queue | 🔐 Bearer JWT |
Engineered with ❤️ and rigorous distributed system principles.