Deployment Options
Rust Embedded
Section titled “Rust Embedded”The simplest deployment: run the worker inside your application binary using a background tokio task.
use zart::prelude::*;use zart::PgBackend;use std::time::Duration;use std::sync::Arc;use tokio::signal;
#[tokio::main]async fn main() -> anyhow::Result<()> { let pool = sqlx::PgPool::connect(&std::env::var("DATABASE_URL")?).await?; let pg = Arc::new(PgBackend::new(pool));
// Build the worker with fluent registration let worker = zart::WorkerBuilder::from_backend(&*pg) .register_durable_task("onboarding", OnboardingTask::new()) .register_durable_task("checkout", CheckoutTask::new()) .register_durable_task("report-gen", ReportTask::new()) .config(zart::WorkerConfig { poll_interval: Duration::from_secs(5), max_tasks_per_poll: 10, max_concurrent_tasks: 16, shutdown_timeout: Duration::from_secs(30), ..Default::default() }) .build();
// Spawn worker as a background task — doesn't block your app let worker_handle = tokio::spawn(async move { worker.run().await });
// Your web server / app logic runs here alongside the worker run_axum_server(pg).await?;
// Graceful shutdown worker_handle.abort(); Ok(())}Best for:
- Monoliths and smaller services
- Development and testing
- When you want the simplest possible setup
- Applications where all tasks are handled in one binary
Database Requirements
Section titled “Database Requirements”| Database | Crate | Notes |
|---|---|---|
| PostgreSQL 14+ | zart (PgBackend) | Recommended for production. Uses SKIP LOCKED, advisory locks, and LISTEN/NOTIFY for efficient polling. |
Connection Pooling
Section titled “Connection Pooling”The PostgreSQL backend uses sqlx’s built-in connection pool. Configure pool size via sqlx::PgPoolOptions:
use sqlx::PgPoolOptions;
let pool = PgPoolOptions::new() .max_connections(20) .min_connections(2) .acquire_timeout(Duration::from_secs(30)) .connect(&database_url) .await?;
let pg = PgBackend::new(pool);Custom Table Names
Section titled “Custom Table Names”By default Zart uses zart_tasks, zart_executions, and the other zart_* tables created by the bundled migration. If those names collide with existing tables in your database, or you need multiple logical workers sharing one database (e.g. per-environment isolation), you can override them with TableNames.
Custom prefix
Section titled “Custom prefix”use zart::postgres::{PgBackend, TableNames};
let names = TableNames::with_prefix("myapp_")?; // → myapp_tasks, myapp_executions, …let pg = PgBackend::with_table_names(pool, names);Schema qualifier
Section titled “Schema qualifier”let names = TableNames::default().with_schema("tenant_a")?;// → "tenant_a"."zart_tasks", "tenant_a"."zart_executions", …let pg = PgBackend::with_table_names(pool, names);Prefix + schema
Section titled “Prefix + schema”let names = TableNames::with_prefix("svc_")?.with_schema("myschema")?;// → "myschema"."svc_tasks", …let pg = PgBackend::with_table_names(pool, names);Environment variables
Section titled “Environment variables”For CLI or container deployments, TableNames::from_env_or_default() reads ZART_TABLE_PREFIX and ZART_SCHEMA:
ZART_TABLE_PREFIX=myapp_ ZART_SCHEMA=tenant_a ./my-workerlet names = TableNames::from_env_or_default()?;let pg = PgBackend::with_table_names(pool, names);Graceful Shutdown
Section titled “Graceful Shutdown”All deployment modes support graceful shutdown. When a shutdown signal is received:
- The worker stops polling for new tasks.
- In-flight tasks are allowed to complete (up to
shutdown_timeout). - Tasks still running after the timeout are re-queued for another worker.
zart::WorkerConfig { shutdown_timeout: Duration::from_secs(30), // wait up to 30s for tasks to finish ..Default::default()}In Docker / Kubernetes, set terminationGracePeriodSeconds to at least shutdown_timeout + 10 to give the pod time to drain cleanly.