Chirpy
On this page
Chirpy is currently in active development. APIs, protocols, and features described on this page reflect the planned design and are subject to change. Follow the GitHub repository for progress updates.
Apalis works exceptionally well as an embedded library — your Rust application imports it, declares workers, and runs everything in-process. But not every team wants to embed a job engine into every service. In a multi-service environment, that means multiple independent job queues, disconnected dashboards, and duplicated operational overhead.
Chirpy is the answer to that problem. It is a standalone binary built on Apalis that runs the job engine as a central server. Any service in your infrastructure — Rust, Go, Python, JavaScript, or anything else that speaks HTTP or gRPC — can push jobs to it, and a fleet of workers can pull from it, all through a single deployment.
What Chirpy Provides
- A standalone binary — deploy it like any other service: Docker, systemd, Kubernetes
- A language-agnostic API — push and query jobs over HTTP or gRPC from any language
- All Apalis capabilities — retries, scheduled jobs, priority queues, heartbeating, and failure queues, backed by your choice of PostgreSQL, SQLite, or Redis
- A built-in web dashboard — the full
apalis-boardinterface, served directly from the binary - A metrics endpoint — Prometheus-compatible
/metricsout of the box
How It Differs from Embedded Apalis
| Embedded Apalis | Chirpy | |
|---|---|---|
| Deployment | Inside your application | Standalone binary |
| Language support | Rust only | Any language via HTTP/gRPC |
| Worker location | Same process as the server | Anywhere on the network |
| Operational overhead | Per-service | Centralised |
| Dashboard | Optional, self-hosted | Built in |
| Best for | Single-service Rust apps | Multi-service or polyglot environments |
Both modes will continue to be supported. Chirpy is an addition to the ecosystem, not a replacement for embedded Apalis.
Architecture
┌─────────────────────────────────────────────────────┐
│ Chirpy Server │
│ │
│ ┌─────────────┐ ┌────────────┐ ┌─────────────┐ │
│ │ HTTP API │ │ gRPC API │ │ Web UI │ │
│ │ /jobs │ │ JobService │ │ /dashboard │ │
│ └──────┬──────┘ └─────┬──────┘ └─────────────┘ │
│ │ │ │
│ └────────┬───────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Apalis Core │ │
│ │ Backend + Pool │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ Storage │ │
│ │ PG / SQLite / │ │
│ │ Redis │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────┘
▲ ▲ ▲
│ │ │
Rust client Python client Go client
(native SDK) (HTTP) (gRPC)
Chirpy exposes two API surfaces over the same underlying Apalis backend. Push a job from a Python service over HTTP, pull it from a Rust worker using the native SDK, and watch it all from the web dashboard — the backend does not care which client pushed which job.
Planned API
HTTP
POST /queues/{queue}/jobs Push a new job
GET /queues/{queue}/jobs List jobs (with filter)
GET /queues/{queue}/jobs/{id} Inspect a single job
DELETE /queues/{queue}/jobs/{id} Cancel a job
GET /queues List all queues
GET /workers List registered workers
GET /metrics Prometheus metrics scrape endpoint
Request body for pushing a job:
{
"payload": { "to": "user@example.com", "subject": "Welcome" },
"queue": "email",
"scheduled_at": "2026-07-01T09:00:00Z"
}gRPC
A JobService proto definition will be published alongside the first release, covering the same operations as the HTTP API. gRPC is the preferred transport for high-throughput producers and for language ecosystems where gRPC client generation is well-supported (Go, Python, Java, .NET).
Connecting a Rust Worker
Rust applications can connect a standard Apalis worker directly to a running Chirpy instance using the chirpy-client crate:
use apalis::prelude::*;
use chirpy_client::ChirpyBackend;
async fn send_email(email: Email) -> Result<(), BoxDynError> {
// handler logic
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), BoxDynError> {
let backend = ChirpyBackend::connect("http://chirpy.internal:7000")
.queue("email")
.await?;
WorkerBuilder::new("email-worker")
.backend(backend)
.enable_tracing()
.build(send_email)
.run()
.await?;
Ok(())
}The ChirpyBackend implements the standard Backend trait — so all existing middleware, retry policies, and observability layers work without modification.
Connecting from Other Languages
Any HTTP client can push jobs to Chirpy. No SDK required:
# Python
import httpx
httpx.post("http://chirpy.internal:7000/queues/email/jobs", json={
"payload": {"to": "user@example.com", "subject": "Welcome"},
})// Go
http.Post(
"http://chirpy.internal:7000/queues/email/jobs",
"application/json",
strings.NewReader(`{"payload":{"to":"user@example.com"}}`),
)Official client SDKs for Go and Python are planned. See the roadmap below.
Deployment
Chirpy is distributed as a single static binary with no runtime dependencies beyond the chosen storage backend.
Docker
docker run -e DATABASE_URL=postgres://user:pass@localhost/chirpy \
-p 7000:7000 \
ghcr.io/apalis-dev/chirpy:latestEnvironment Variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | — | Storage backend connection string |
CHIRPY_PORT | 7000 | HTTP and gRPC listen port |
CHIRPY_LOG | info | Log level (debug, info, warn, error) |
CHIRPY_UI | true | Enable or disable the web dashboard |
CHIRPY_METRICS | true | Enable or disable the /metrics endpoint |
Roadmap
Chirpy is under active development. The planned milestones are:
Alpha — Core Protocol
- HTTP API for push, list, and inspect
- PostgreSQL and SQLite storage backends
-
chirpy-clientRust crate withBackendimplementation - Basic web dashboard via
apalis-board - Docker image and basic deployment documentation
Beta — Extended Capabilities
- gRPC API and published
.protodefinitions - Redis storage backend
- Prometheus
/metricsendpoint - Scheduled and delayed job support via API
- Priority queue support
- Official Go client SDK
Stable — Ecosystem
- Official Python client SDK
- JavaScript / TypeScript client SDK
- Multi-tenant queue namespacing
- API key authentication
- Horizontal scaling — multiple Chirpy instances against a shared backend
- Webhook support — push job results to a URL on completion
Relationship to Apalis
Chirpy is built entirely on Apalis internals. It does not introduce a new job engine — it wraps the existing one in a network-accessible shell. This means:
- Every Chirpy deployment benefits from Apalis improvements automatically
- Teams already using embedded Apalis can migrate to Chirpy without changing their worker code — only the backend connection changes
- The
apalis-boarddashboard works identically whether you are using embedded Apalis or Chirpy
Get Involved
Chirpy is in early development and the design is still open. If you have opinions on the protocol, the API shape, or priorities for language SDKs, the best place to contribute is the GitHub discussion thread or by opening a pull request against the Chirpy repository.