Operations
Retsu uses one binary and container image for the API, migrations, and background workers. A complete deployment runs each role separately.
Configure Retsu
Settings are loaded in this order:
- Built-in defaults
config/retsu.yaml, when present- Environment variables
Later values override earlier ones. Pass --config PATH when a specific YAML file must be present:
retsu --config /etc/retsu.yaml api
Environment variables start with RETSU_ and use double underscores between YAML levels:
RETSU_HTTP__PORT=3000
RETSU_DATABASE__URL=postgres://user:password@database:5432/retsu
RETSU_CACHE__DISTRIBUTED__URL=redis://cache:6379
RETSU_LOGGING__FORMAT=json
Common defaults are:
| Setting | Default |
|---|---|
| API address | 127.0.0.1:2424 |
| Worker management address | 127.0.0.1:24247 |
| Database pool size | 10 connections per process |
| Worker shutdown timeout | 30 seconds |
| Log format | pretty |
| Trace export | Disabled |
Bind to 0.0.0.0 inside a container. Keep connection URLs and other secrets in the deployment's secret manager, not in the repository.
See Configuration for the complete list, defaults, accepted ranges, and environment-variable format.
Run the processes
Run migrations once before starting a new release:
retsu migrate
Then run the API and all three workers as separate processes:
| Process | Command | Purpose |
|---|---|---|
| API | retsu api |
Serves queue requests |
| Expired-message cleaner | retsu worker run queue expired-message-cleaner |
Removes messages after their lifetime and visibility timeout end |
| Dead-letter-message cleaner | retsu worker run queue dead-letter-message-cleaner |
Removes dead-letter records after their retention period |
| State-metrics collector | retsu worker run queue state-metrics-collector |
Refreshes ready, in-flight, and oldest-message measurements |
Starting one process does not start any other process. Several state collectors can run for failover, but only one collects at a time.
See Workers for worker timing, management ports, and shutdown behavior.
Deploy the image
Published images use an explicit calendar version:
ghcr.io/karanbalani/retsu:YEAR.MONTH.RELEASE
Each release also has a sha-<commit> tag. There is no latest tag.
A safe rollout is:
- Run migrations as a one-time job.
- Start or update the API.
- Start or update every worker.
- Wait for each process to report ready.
- Scrape metrics from the API and every worker.
The image runs as user and group 65532 and contains no shell or package manager. It supports Linux AMD64 and ARM64.
See Deployment and releases for image tags, commands, rollout details, and the release workflow.
Check each process
The API and workers expose:
/health/liveto confirm that the process is running/health/readyto confirm that it can use PostgreSQL/metricsfor Prometheus
The API uses its HTTP port. Each worker uses its management port, so workers on the same host need different ports. Do not expose worker management ports to public traffic.
Retsu writes structured logs and can export traces through OTLP. Enable trace export with:
RETSU_TELEMETRY__TRACES__ENABLED=true \
RETSU_TELEMETRY__TRACES__ENDPOINT=http://collector:4317 \
retsu api
The local stack includes Prometheus, Grafana, Tempo, and the OpenTelemetry Collector. Open Grafana at http://127.0.0.1:24246.
See Monitoring for metrics, logs, traces, and dashboards. The local infrastructure reference lists every local port, resource limit, and troubleshooting command.
Create a release
Maintainers create a calendar-version tag from a clean local main that matches origin/main:
just release-tag 2026.7.1
The release workflow builds both image architectures, publishes version and commit tags, and creates a GitHub release.