pulse
A reliable, Postgres-backed distributed job queue in Go — gRPC server, typed SDK, operator CLI, web dashboard.
Contention-free dispatch with FOR UPDATE SKIP LOCKED, retries with backoff and dead-letter, lease-based crash recovery, priority, scheduling, and pause/resume.
go get github.com/bete7512/pulseA job is never lost
Submitted work is durable in Postgres before the submit returns — the queue is the database, not a process.
Retries, then dead-letter
Failures retry with attempts² backoff up to a bounded cap, then dead-letter with the last error preserved. Poison jobs can’t loop forever.
Crash recovery, automatic
Claims carry a lease; workers heartbeat to keep it; a watchdog routes lapsed leases back through the retry path. Zombie workers are fenced by attempt tokens.
Contention-free dispatch
Claims are FOR UPDATE SKIP LOCKED batches over a partial index — concurrent workers take disjoint batches, O(batch) at any backlog depth.
Priority & scheduling
Per-job priority with FIFO within a level. Schedule once, on an interval, or by cron — exactly-once per occurrence across replicas.
Operable by design
Pause dispatch durably for maintenance, inspect and requeue dead-lettered jobs, watch live stats — from the CLI or the web dashboard.
One client, both roles
The same *pulse.Client produces and consumes over a single gRPC connection. Handlers run in your process — the server only moves data.
type EmailArgs struct {
To string `json:"to"`
Subject string `json:"subject"`
}
func main() {
ctx := context.Background()
p, err := pulse.New("localhost:50051",
pulse.WithConcurrency(20), // parallel handlers (default 10)
pulse.WithUserPass("worker", "hunter2"), // when the server sets PULSE_AUTH_USERS
pulse.WithTLS(nil), // system roots; pass *tls.Config to customize
)
if err != nil {
log.Fatal(err)
}
defer p.Close()
// register a handler — a plain typed function:
pulse.Register(p, "send-email", func(ctx context.Context, a EmailArgs) error {
return sendEmail(a.To, a.Subject)
})
// enqueue by name; urgent work jumps the queue:
pulse.Enqueue(ctx, p, "send-email", EmailArgs{To: "a@b.com", Subject: "Welcome"})
pulse.Enqueue(ctx, p, "send-email", EmailArgs{To: "vip@b.com"}, pulse.WithPriority(10))
// schedule work — once, on an interval, or by cron:
pulse.ScheduleJob(ctx, p, "send-email", EmailArgs{To: "digest@b.com"}, pulse.Cron("0 8 * * *"))
p.Run(ctx) // process jobs until ctx is cancelled
}How it works
01 · enqueue
One jobsrow holds each job's state, retry policy, and worker lease — durable before submit returns.
02 · claim
Workers stream assignments; the server claims disjoint batches with SKIP LOCKED — nothing to race, no lock queues.
03 · report
Guarded UPDATEs enforce every state transition in the WHERE clause — invariants live in the database, race-free by construction.
1,223
jobs/s end-to-end
0
claim conflicts
~1.6
DB transactions per job
2,000 jobs across 8 workers on one laptop — methodology and full numbers
Everything speaks the same API
Typed Go SDK
Register plain typed handlers; enqueue with one call. Idempotency keys, heartbeats, and backpressure built in.
Operator CLI
pulse stats, jobs list/get/cancel/requeue, schedules, dispatch pause/resume — with saved credentials.
Web dashboard
Live queue composition, throughput chart, job browser with payloads, requeue buttons, schedule controls.
Authored by Bete Goshme (bete7512)