Changelog
Version v0.15.1
What’s Changed
Bug Fixes
- Saturated workers no longer busy-loop. A worker whose slots were all busy kept polling
getNextJobAvailableInMsas fast as the event loop allowed: with a due job in the backlog the poll reported0ms, so the wait returned immediately and the worker re-entered the loop without being able to take the work. Saturated in-process workers now wait for a slot to free (or forpollIntervalMs) instead of polling.
Performance
- Postgres job acquisition now uses the acquisition index.
acquireJobandgetNextJobAvailableInMsmatched jobs withtype_name IN (...)ordered byscheduled_at, which Postgres cannot satisfy from the(type_name, scheduled_at)index for more than one job type — it fell back to scanning and sorting the entire pending backlog on every acquisition and every poll. Both queries are now per-job-typeLATERALlookups, turning a backlog scan into one index lookup per job type. Workers polling a large Postgres backlog should see a substantial drop in database load. - On Postgres, when several job types are polled together, acquisition now picks a job type at random and takes its oldest due job rather than always taking the globally oldest job. This keeps a backlogged job type from starving the others.
- Postgres
getNextJobAvailableInMsno longer takes row locks on jobs scheduled in the future.
Packages
All packages released at 0.15.1: queuert, @queuert/postgres, @queuert/sqlite, @queuert/redis, @queuert/nats, @queuert/otel, @queuert/dashboard.