TaskFlow is a distributed background job processing platform built with Go, Gin, PostgreSQL, Redis, Asynq, Docker, and Resend.
It demonstrates how production systems handle long-running work asynchronously using workers and message queues.
- Asynchronous email delivery
- CSV export jobs
- Redis-backed task queues (Asynq)
- Worker-based processing architecture
- Retry handling
- Failed task inspection API
- Metrics API and HTML dashboard
- Kubernetes deployment with HPA
- Load testing tool
- Docker Compose for local development
- Asynqmon monitoring
- Go 1.26.x
- Gin
- PostgreSQL
- Redis
- Asynq
- Resend
- Docker / Docker Compose
- Kubernetes
flowchart TD
Client[Client] --> API[API Replicas]
API --> PG[(PostgreSQL)]
API --> Redis[(Redis / Asynq Queue)]
Redis --> Worker[Worker Replicas]
Worker --> PG
Worker --> Email[Email via Resend]
Worker --> CSV[CSV Export]
| Layer | Role |
|---|---|
| API | Accepts task requests, persists metadata, enqueues jobs |
| PostgreSQL | Task lifecycle and status tracking |
| Redis / Asynq | Distributed job queue |
| Worker | Processes email and CSV export jobs |
| Resend | External email delivery |
| Environment | Purpose |
|---|---|
| Docker Compose | Local development and quick iteration |
| Kubernetes | Orchestration, scaling, and production-oriented demo |
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check (used by Kubernetes probes) |
| POST | /tasks |
Create email delivery task |
| GET | /tasks/:id |
Get task status |
| GET | /failed-tasks |
List failed tasks |
| GET | /metrics |
JSON metrics |
| GET | /dashboard |
HTML metrics dashboard |
| POST | /exports |
Queue CSV export job |
curl -X POST http://localhost:8080/tasks \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'curl -X POST http://localhost:8080/exports \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'- Copy environment file:
cp .env.example .env-
Set
RESEND_API_KEYin.env. -
Start services:
docker compose up --build| Service | URL |
|---|---|
| API | http://localhost:8080 |
| Dashboard | http://localhost:8080/dashboard |
| Asynqmon | http://localhost:8081 |
See k8s/README.md for full deployment instructions.
Quick start:
# Build local images
docker build -f Dockerfile.api -t taskflow-api:local .
docker build -f Dockerfile.worker -t taskflow-worker:local .
# Deploy to taskflow namespace
kubectl apply -f k8s/
# Port-forward API
kubectl port-forward service/taskflow-api 8080:8080 -n taskflowKubernetes resources include:
- API Deployment (2 replicas) with liveness/readiness probes on
/health - Worker Deployment (2 replicas, manually scalable)
- PostgreSQL with persistent volume
- Redis (internal ClusterIP)
- ConfigMap + Secret for configuration
- API HorizontalPodAutoscaler (2–5 replicas, CPU ~70%)
GET /metrics returns JSON:
| Metric | Description |
|---|---|
total_tasks |
All tasks |
completed_tasks |
Successfully completed |
failed_tasks |
Failed tasks |
pending_tasks |
Awaiting processing |
processing_tasks |
Currently processing |
success_rate |
Completed / total (%) |
failure_rate |
Failed / total (%) |
average_processing_time_ms |
Avg time from start to complete |
total_retry_attempts |
Sum of retry counts |
queue_depth |
Current Asynq queue depth |
throughput_per_second |
Completions in last minute / 60 |
throughput_per_minute |
Completions in last minute |
GET /dashboard renders a human-readable HTML view of the same data.
go run ./tools/loadtest --url http://localhost:8080 --tasks 1000 --concurrency 20Example output:
TaskFlow Load Test
------------------
Tasks submitted: 1000
Tasks completed: ...
Success rate: ...%
Throughput: ... jobs/sec
Compare worker throughput at 1, 2, and 3 replicas. See docs/benchmark.md.
kubectl scale deployment taskflow-worker --replicas=2 -n taskflow
go run ./tools/loadtest --url http://localhost:8080 --tasks 500 --concurrency 20Worker scaling is manual. CPU-based HPA is not queue-aware; production systems typically use queue-depth metrics.
- Separate API and worker binaries — independent scaling and deployment
- Asynq over raw Redis — built-in retries, scheduling, and monitoring
- PostgreSQL for task state — durable lifecycle tracking separate from queue
- ConfigMap + Secret in Kubernetes — non-sensitive vs sensitive config separation
- Local Docker images — no Docker Hub dependency for local clusters
- Manual worker scaling — honest approach without fake queue-aware HPA
- No cloud-specific resources — portable local Kubernetes demo
cmd/
api/ HTTP API server
worker/ Background job processor
internal/
config/ Environment configuration
handlers/ HTTP handlers
metrics/ Metrics service
models/ Domain models
repository/ PostgreSQL and Redis
services/ Business logic
tasks/ Asynq task definitions and processors
email/ Resend email integration
k8s/ Kubernetes manifests
tools/loadtest/ Load testing CLI
migrations/ Database schema
docs/ Benchmark and resume templates
Use docs/resume-metrics-template.md to record real benchmark results.
MIT