Migration fatigue, and how LLMs help us avoid it
How we avoided shipping a database migration by using an LLM to turn a slow active job rescue query into a single producer-state pass, producing a ~130x speedup without an index.
Announcements, engineering posts, and other news from the River team. Available as an Atom feed .
How we avoided shipping a database migration by using an LLM to turn a slow active job rescue query into a single producer-state pass, producing a ~130x speedup without an index.
River v0.41 adds support for Turso, a ground-up rewrite of SQLite in Rust.
River Pro v0.26 adds active job rescue, which uses queue heartbeats to quickly recover jobs orphaned by crashed clients, no additional schema required.
River v0.41 adds an extensible hook for receiving metrics, starting with job-fetch duration and locked-job counts, and with batteries-included OpenTelemetry support through otelriver.
Go can't kill a stuck goroutine, but River v0.40's new stuck-job handler can expose a goroutine stuck in an indefinite wait, preserve worker capacity, and trigger a restart before stuck jobs exhaust a process.
River Pro v0.24.0 introduces workflows V2 with durable workflow signals, timers, CEL wait conditions, and a rebuilt engine with 60% higher sustained workflow throughput in local benchmarks.
A new TypeScript client for inserting River jobs from Node.js, with drivers for node-postgres and Prisma.
`SoftStopTimeout` simplifies River's graceful shutdown by collapsing a previously elaborate and lengthy routine down to a single config option.
Resumable jobs break work into steps so retries skip what's already done, saving time and money on expensive operations.
At long last, a prospective feature for Postgres 19, `REPACK (CONCURRENTLY)`, will provide a production-safe way to reclaim space from bloated tables without downtime.
River has completed its SOC 2 Type II audit, verifying that the security controls protecting hosted Pro customer data operate effectively over time.
From BackgrounDRb and Delayed::Job through Resque, Sidekiq, GoodJob, and Solid Queue, a history of how Ruby's job systems evolved—and what River learned from them.
GitHub's Dependabot can now work with private Go proxies/registries. But how do Go proxies even work? Learn how they function, how to configure them for private modules, and why ordering matters.
Build a Rails app that transactionally enqueues webhook jobs for Go workers using River's Ruby client, Active Record integration, retry controls, and structured job arguments.
River v0.23 and River Pro v0.15 bring 15–20% higher benchmark throughput, faster Sequences and Concurrency Limits, a SQLite preview, durable periodic jobs, and `database/sql` support for Pro.
River UI adds filters by kind, queue, ID, and priority plus per-attempt logs, while River expands alternate-schema and `lib/pq` support and adds job-kind aliases.
Using encrypted jobs and NaCL Secretbox to add a layer of security protecting data even in the worst case scenario of widespread database exfiltration.
Why River offers both middleware and lightweight hooks, and how small, interface-driven extension points add customization without forcing breaking API changes.
River Pro now supports global concurrency limits to precisely control how many jobs can run concurrently across your infrastructure, complete with granular partitioning and operational control through River UI.
Using unique jobs in River to build an email API that takes an idempotency key so that even in the event a request needs to be retried, it never sends a duplicate email.
Monitor River job insertion and execution with `otelriver`, which emits OpenTelemetry traces and metrics for duration, outcomes, queues, and job kinds.
River Pro Sequences process related jobs one at a time while allowing independent sequences to run in parallel, preventing races without consuming worker slots.
River UI v0.5 ships as an embeddable Go module with bundled frontend assets, letting applications mount the full UI as an `http.Handler` at any path.
River Pro launches with workflows: code-defined job graphs that split complex work into observable, independently retryable tasks with first-class River UI support.
River's expanded `riverdatabaseql` driver brings full `database/sql` support, including transactional job insertion alongside Bun, GORM, and other Go database tools.
Insert River jobs from Python with synchronous or asyncio clients, SQLAlchemy integration, transactional enqueueing, and type hints, then execute them in Go.
River UI is a self-hosted web interface for River, bringing powerful operational and development tooling to River users. It's freely available as a Docker image, a pre-built static binary, or for bundling into your own application.
How River combines Postgres transaction-level advisory locks with Go's FNV hashing to prevent duplicate jobs safely across concurrent clients.
River's first six months bring a stable core API, 4.5× higher benchmark throughput, queue controls, and new job-management APIs on the path to production readiness.
River 0.4.0's released, and it contains a few small breaking changes that've been batched together. A list of specific changes, upgrade guide, and a little rationale for why we thought they were justified.
For the past several months, I’ve been working with Brandur to build the Postgres background job library that the Go ecosystem needs: it’s called River, and we’re launching it today in beta.