Fiber and Asynq example
Description
This example shows how to run background jobs with Asynq (a Redis-backed task queue) from a Fiber HTTP server. The API enqueues a job and returns immediately; a separate worker process consumes the queue and does the slow work, with retries and priorities handled by Asynq.
How it works
- The Fiber API exposes
POST /enqueuewith a JSON body:{"user_id": "...", "email": "..."}. - Each request enqueues a
email:welcometask onto Redis and returns the task id — it never does the work inline. - A separate worker process pulls tasks from Redis and runs them, retrying on failure with backoff.
- The task type and payload live in a shared
taskpackage, so the API and the worker can't drift apart.
The worker uses weighted queues (critical drained ~6x as often as low), which is the usual way to keep a noisy low-priority job from starving important ones.
Requirements
- Go 1.25 or higher
- A running Redis instance (or use the provided
docker-compose.yml)
Running the example
With Docker Compose
docker compose up --build
This starts Redis, the API, and the worker together.
Manually
Start Redis, then in two terminals:
# terminal 1 — API
make run-api
# terminal 2 — worker
make run-worker
Set REDIS_ADDR if Redis isn't on localhost:6379.
Trying it out
curl -X POST http://localhost:3000/enqueue \
-H "Content-Type: application/json" \
-d '{"user_id":"42","email":"[email protected]"}'
# {"enqueued":true,"task_id":"...","queue":"default"}
The worker terminal logs:
sending welcome email for user 42
A request with a missing or invalid body returns 400.
Notes
- The handler returns an error to signal a retry; returning
asynq.SkipRetry(as it does for a malformed payload) tells Asynq not to bother retrying something that will never succeed. - Enqueue options like
asynq.MaxRetryandasynq.Queueare set per call, so different endpoints can enqueue onto different queues with different retry policies.