okuri

Introduction

okuri is a self-hosted, open-source job queue that stores all of its state (messages, leases, acks, and dead letters) in S3 or any S3-compatible object store such as MinIO or Cloudflare R2. Compute nodes are fully stateless: any node can serve any request, any node can die at any time, and nothing is lost. Support for GCS and Azure Blob is planned.

okuri is in active development. The SQS-compatible surface is its first stabilized API; the on-bucket format and the Rust crate APIs may still change before 0.1.0. Deployments of 0.0.x should be treated as development infrastructure.

The gap it fills

Teams that need a job queue usually pick one of four trade-offs: SQS (managed, but AWS lock-in and no self-hosting), RabbitMQ (self-hosted, but a stateful cluster to babysit), Redis-backed queues (fast, but durability is an afterthought), or Kafka (durable, but log semantics rather than job semantics). okuri targets the gap: SQS semantics, self-hosted, with zero stateful infrastructure beyond a bucket.

Semantics

  • At-least-once delivery. An acked message is never lost; an unacked one may be redelivered. Consumers should be idempotent.
  • Visibility timeouts backed by leases. Every lease transition is fenced by compare-and-swap on the bucket, so a slow clock costs a redelivery, never a lost or double-acked message.
  • Per-queue dead-letter scope with manual redrive. Every queue’s dead letters live at {queue}-dlq.
  • Purge takes effect the moment it lands. There is no SQS-style 60-second purge window, and messages sent after the purge are untouched by construction.
  • Producer-side deduplication window. The window is in-memory and best-effort, so this is not exactly-once.
  • Per-message delay on send, and long polling up to 20 seconds on receive.
  • 1 MB maximum message size, natively, with no need for payload-pointer workarounds.

Who it is for

  • Platform engineers on Kubernetes who are tired of operating RabbitMQ or Redis for queues.
  • Teams on AWS who want exit optionality, multi-cloud, or on-prem parity while keeping their SQS-shaped code.
  • Bursty batch workloads (ML, media, ETL) where paying per request beats paying for idle brokers.
  • Indie and homelab deployments: one binary plus MinIO is a complete install.

When not to use okuri

  • You need sub-millisecond enqueue or dequeue latency. Object storage has a latency floor; okuri is not a microsecond queue.
  • You need strict FIFO ordering today. Ordering is best-effort in 0.x; FIFO message groups are on the roadmap.
  • Extremely chatty workloads pay per-request object-store pricing. okuri batches to amortize it, but the S3 bill is still part of the design.

okuri is also deliberately not a streaming log, an AMQP replacement, a workflow engine, or a database.

Next

Head to the quickstart to bring up a full local stack in one command.