Go to production
Choose a backend, run workers as a service, watch the queue, and the short list of things to get right before you ship.
Choose a backend, run workers as a service, watch the queue, and the short list of things to get right before you ship.
Everything so far ran against an SQLite file on your laptop with a worker in a terminal. This page is the move to a machine you do not sit in front of. It is deliberately short: four decisions and a checklist, each linking to the Operate page that goes deep.
The queue is a database. Which one you point at is the first production decision, and the only one that is awkward to change later.
| Backend | Use it when | Cost |
|---|---|---|
| SQLite (default) | Everything runs on one machine — a single app server, a container with a persistent volume, a CLI tool. | Writers must share a filesystem. Not an option across machines. |
| Postgres | Workers and web processes live on different machines, or you already run Postgres. | One server to operate — the only external service flexiq ever needs. |
| Redis | You want the lowest dispatch latency and already run Redis. | Durability is Redis's durability. No SQL to query the queue with. |
SQLite is not a toy setting here — with WAL mode it will carry a real workload on one host. Move to Postgres when you need more than one host, not when you need "production".
Backends has the connection strings, the WAL and pool settings, and what changes behaviourally between them.
A worker is a long-running process with no state of its own, which makes it the easy half: run it under whatever already supervises your services, and let it be restarted freely.
# /etc/systemd/system/flexiq-worker.service
[Service]
ExecStart=/srv/app/.venv/bin/flexiq worker --app tasks:queue --queues emails,media
Restart=always
KillSignal=SIGTERM
TimeoutStopSec=60# /etc/systemd/system/flexiq-worker.service
[Service]
ExecStart=/srv/app/node_modules/.bin/flexiq run ./tasks.js --queues emails,media
Restart=always
KillSignal=SIGTERM
TimeoutStopSec=60# /etc/systemd/system/flexiq-worker.service
[Service]
ExecStart=/usr/bin/java -jar /srv/app/worker.jar
Restart=always
KillSignal=SIGTERM
TimeoutStopSec=60# /etc/systemd/system/flexiq-worker.service
[Service]
ExecStart=/srv/app/bin/worker
Restart=always
KillSignal=SIGTERM
TimeoutStopSec=60Nothing in the crate installs a signal handler. Catch SIGTERM in your own
main and call worker.shutdown() — it stops dispatching, drains what is
in flight, and unregisters the worker before it returns.
Two things matter more than the unit file:
SIGTERM starts a drain — in-flight jobs
finish, no new ones are claimed. Killing before the drain completes never
loses a job (the claim expires and another worker takes it) but the task body
runs again from the top, so a hard kill is only harmless for tasks that are
safe to repeat. Every rushed deploy is a round of duplicate execution.Deployment covers containers, Kubernetes, WAL tuning, rolling restarts and the full production checklist.
You need one number and one place to look. The number is pending — if it climbs and does not come down, you are under-provisioned or nothing is draining.
flexiq info --app tasks:queue --watch # live counts in the terminal
flexiq dashboard --app tasks:queue --auth # full web UI, session auth onflexiq --db signup.db stats # counts
flexiq --db signup.db dashboard --port 8787 --authflexiq --url signup.db stats # counts
flexiq --url signup.db dashboard --port 8080 --token "$DASH_TOKEN"let stats = queue.stats()?;
println!("pending {} · dead {}", stats.pending, stats.dead);The Rust SDK ships neither a CLI nor a dashboard server: stats() is the read,
and the flexiq-server crate is what serves the bundled dashboard over the same
store.
Both come from the bundled CLI, which is also what a container entrypoint or systemd unit should invoke.
The dashboard ships in the package — job browsing, dead-letter replay, per-task limits, no separate service. For metrics that belong in the monitoring you already have, tasks emit lifecycle events and there are Prometheus and OpenTelemetry integrations: Monitoring.
Three that are easy to miss on the first deploy:
SIGTERM.When something does go wrong, Troubleshooting is organised by symptom — stuck jobs, lock contention, workers that claim nothing.
Next: Next steps — where to go now that the basics hold.