A priority field does not help when the worker is already four minutes into a nightly export.
// one queue: the reset waits behind the export
dispatch(new SendPasswordReset($user));
dispatch(new ExportCatalogue());
// split by LATENCY REQUIREMENT, not by importance
dispatch(new SendPasswordReset($user))->onQueue('interactive');
dispatch(new ExportCatalogue())->onQueue('bulk');
// php artisan queue:work --queue=interactive,bulk
// → drains interactive first, every poll
Splitting by latency requirement rather than by importance is the framing that produces the right queues: an unimportant job somebody is waiting for belongs in the fast queue, and an important job nobody is watching does not. Dedicated workers per queue is safer than an ordered list, because a list still means one worker is unavailable while it runs a long job. Starvation of the bulk queue is the risk and needs its own monitoring.