The task queue that just works
PostgreSQL is your only dependency. No message broker, no cache layer, no complexity. Just a task queue that scales.
Everything you need, nothing you don't
Built from the ground up for simplicity and performance.
PostgreSQL Only
Single source of truth. No Redis, no RabbitMQ, no NATS. One dependency to deploy and manage.
Zero-Latency Dispatch
In-memory matching engine routes tasks to waiting workers instantly via oneshot channels.
Polyglot SDKs
First-class SDKs for Rust, TypeScript, Python, and Go. Same builder pattern, every language.
Fully Observable
Real-time log streaming, event bus, Prometheus metrics, and a built-in web dashboard.
Task Signals
Send real-time signals to running workers over the gRPC bidirectional stream.
Smart Retries & DLQ
Configurable exponential backoff, dead letter queue, and automatic lease recovery.
One API, every language
Same builder pattern across Rust, TypeScript, Python, and Go.
use valka_sdk::{TaskContext, ValkaWorker};
let worker = ValkaWorker::builder()
.name("email-worker")
.server_addr("http://localhost:50051")
.queues(&["emails"])
.concurrency(8)
.handler(|ctx: TaskContext| async move {
let input: serde_json::Value = ctx.input()?;
// process task ...
Ok(serde_json::json!({"status": "sent"}))
})
.build()
.await?;
worker.run().await?;How it works
Two paths, one goal: get tasks to workers as fast as possible.
Ingest
Tasks arrive via REST or gRPC and are durably persisted to PostgreSQL. The in-memory MatchingService checks for waiting workers immediately.
Match
Hot path: instant delivery via in-memory oneshot channel. Cold path: workers poll with PG SKIP LOCKED for guaranteed delivery.
Execute
Workers receive tasks over a single gRPC bidirectional stream. Heartbeats, logs, signals, and results all flow over one connection.
Ready to simplify your task queue?
Read the docs, spin up a server, and ship your first worker in minutes.