bunqueue v2.9.18
blog · release
bunqueue v2.9.18
Fixes 3 bugs. The weekly SDK advisory audit passes again for all six SDKs.
To install bunqueue v2.9.18
Section titled “To install bunqueue v2.9.18”bun add bunqueue@2.9.18npm install bunqueue@2.9.18TAG=2.9.18docker run -p 6789:6789 -p 6790:6790 ghcr.io/egeominotti/bunqueue:$TAGTo upgrade bunqueue
Section titled “To upgrade bunqueue”bun add bunqueue@latestSecurity
Section titled “Security”- The weekly SDK advisory audit passes again for all six SDKs. It had failed
every week since 16 August: until 4 October at the Go step, which skipped the
Rust and Elixir audits, and on 11 and 18 October at the TypeScript step, which
skipped the other five:
oxfmtpins its worker pool,tinypool, to 2.1.0, which has two critical advisories; the repository and the TypeScript SDK now override it to a patched release. It is a development dependency only and neither published package ships it.- The Go toolchain used by CI, the SDK workflows and the SDK test image moves
from 1.26.5 to 1.26.10. The Go SDK’s TLS connection reaches four standard
library vulnerabilities fixed between 1.26.6 and 1.26.10 (GO-2026-6809,
GO-2026-6607, GO-2026-6090, GO-2026-5972). The module still declares
go 1.26.5; build applications with Go 1.26.10 or later on 1.26, or 1.27.3 or later. - The Rust SDK’s lockfile moves
rustlsto 0.23.46 andrustls-webpkito 0.103.16 (RUSTSEC-2026-0285, -0346, -0348, -0349 and -0382); rustls 0.23.46 also bringsaws-lc-rs1.18 andaws-lc-sys0.46. The existing dependency ranges allow all of them, so applications only needcargo update -p rustls -p rustls-webpki.
- The root package’s development dependencies no longer carry critical or high
advisories: with the
tinypooloverride above,bun auditdrops from 48 findings (3 critical, 19 high) to one low (@ai-sdk/provider-utils2.x, pinned through the locked@mastra/core1.53.0, whichbun audit fixcannot move). The lockfile now resolves patched releases inside the existing version ranges (bun audit fix;package.jsonis unchanged): the MCP SDK used to develop and testbunqueue-mcpmoves to 1.32.0, andproxy-addr,brace-expansion,fast-uri,hono,@hono/node-server,js-yaml,markdown-it,nanoidandqsmove to their patched releases, as doesip-address, to 10.7.4, which also fixes GHSA-rxp7-6hxx-x8q5, published on 22 October. The published package’s dependencies were already clean (bun audit --prod), and its optional@modelcontextprotocol/sdkpeer range is unchanged.
Bugfixes
Section titled “Bugfixes”- With the PostgreSQL backend, a broker no longer briefly loses its own
committed writes from its local view
(#158). A full-queue
refresh that read PostgreSQL before the broker’s own commit could finish after
it, so a job the broker had just failed terminally could be reported
activeagain and be missing from its DLQ until the job’s event arrived; the same applied to its claims, completions, pushes, cancellations, DLQ removals and queue-wide operations. Each own commit is now recorded for such an in-flight refresh before the change is installed locally, so the refresh no longer overwrites it (see #161 below for how it is applied). Optimistic local settings that are applied before their deferred write commits (non-durablepause,resume, rate limit, concurrency, stall and DLQ configuration,drainandobliterate) can still be briefly reverted until the queue is reloaded. No data was lost, and claims were always decided in PostgreSQL. - With the PostgreSQL backend,
WaitJob(and sowaitUntilFinishedwithout QueueEvents) no longer returns the result of a completed job thatCancelhas since removed (#162). A broker receives a job’scompletedevent after its commit, so the event of the ACK could arrive after the Cancel; a WaitJob reading the job at that moment answered with the event’s result instead ofcompletedwithout a result. It now takes the result from the job’s completion record, which the Cancel cleared, as a waitingWaitJobalready did. Memory and SQLite are unchanged.test/postgres-cancel-outcome.test.tsfailed 8 of 50 runs under injected 0-15 ms scheduling delays before and 0 of 50 after. - With the PostgreSQL backend, a full-queue refresh of a busy queue now applies
on its first load (#161).
A refresh was discarded and reloaded whenever an event or the broker’s own
write for any job of its queue arrived while it loaded, so with steady traffic
it could be retried indefinitely without applying. Meanwhile the broker’s
local view missed queue-level changes made through other brokers (pause, rate
and concurrency limits, drain, clean, obliterate, DLQ pruning) and the
recovery after a startup event-buffer overflow, and the broker’s own
queue-wide durable operations, such as
drainDurableor a durable pause, could be missing from its view when they returned. A refresh now reads the journal position of its PostgreSQL snapshot and installs every job that did not change after it, leaving the jobs changed meanwhile to their own per-job refreshes, and an older refresh never replaces a newer one. Per-job state still converged, and claims were always decided in PostgreSQL. This also fixes the intermittent PostgreSQL test failure in which a broker still reported a queue as not paused right after another broker paused it during a burst of 256 pushes, and an ID-only update of a job the broker had not seen yet can no longer be briefly undone by an older refresh.
Testing
Section titled “Testing”- Two PostgreSQL event catch-up regressions no longer fail intermittently. They treated “event cursor at the journal head” as “snapshot updated”, which stopped being true when job events became asynchronous projection refreshes; they now also wait for queued refreshes to settle and for the expected DLQ. Under injected 0-15 ms scheduling delays the old wait failed 14 of 200 runs and the new one 0 of 200. The PostgreSQL design notes now describe the asynchronous refresh instead of a direct snapshot update.
- The TypeScript SDK’s cooperative-cancel end-to-end test no longer times out
intermittently. The broker counts a job active before the worker has read its
pull reply, and
cancelAllJobsonly cancels jobs the worker already holds, so the test could cancel one job instead of two; it now also waits until both processors have started. With a 5 ms stall after each count request the old test failed 31 of 50 runs and the new one 0 of 50.
Thanks to 1 contributor!
Section titled “Thanks to 1 contributor!”← bunqueue v2.9.17 · Release on GitHub · Commits since v2.9.17 · Full changelog · All posts