# Front-of-queue dispatching

> Send an urgent job to the head of the queue so a worker picks it up next.

Source: https://boring-observability.dev/skyline/docs/front-of-queue-dispatching
Section: Queue control — Skyline for Laravel documentation
Updated: 2026-07-13

---

**Front-of-queue dispatching** prepends a job to the *head* of its Redis queue instead of appending it to the tail, so it is the next job a worker picks up. Add the `InteractsWithFrontOfQueue` trait to the job and call `onFront()` on dispatch. It buys ad-hoc priority for one urgent job without standing up a dedicated high-priority queue — and it breaks FIFO, which has consequences worth reading to the end for.

## Usage

Add the `InteractsWithFrontOfQueue` trait to the job, then call `onFront()` on the pending dispatch:

```php
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Laravel\Horizon\InteractsWithFrontOfQueue;

class ProcessPodcast implements ShouldQueue
{
    use Dispatchable, InteractsWithFrontOfQueue, Queueable;

    // ...
}
```

```php
// Jump to the front of the queue:
ProcessPodcast::dispatch($podcast)->onFront();

// Composes with the usual dispatch options:
ProcessPodcast::dispatch($podcast)->onFront()->onQueue('media');
```

When you are working with raw payloads, reach for the underlying queue method directly:

```php
Queue::connection('redis')->pushRawOnFront($payload, 'media');
```

## How it works

A Redis queue is a list. Dispatching normally `RPUSH`es the payload onto the tail while workers `LPOP` from the head. `onFront()` flags the job, and Skyline's `RedisQueue` then `LPUSH`es it onto the head instead — so the next worker to pop takes it.

A front-pushed job still fires the usual `JobPending` and `JobPushed` events, so it appears on the dashboard and in metrics exactly like any other job.

> **Why the trait is required**
>
> `Illuminate\Foundation\Bus\PendingDispatch` is not macroable, so `onFront()` cannot be registered globally. It is provided by the trait and reached through `PendingDispatch`'s `__call` proxy, which forwards unknown methods to the underlying job. That is why the job class itself must `use InteractsWithFrontOfQueue` — without it, the call has nowhere to land.

## Caveats

Front-of-queue dispatch is a deliberate escape hatch. It buys latency for one job by breaking a property the rest of the system quietly assumes.

- **Immediate dispatch only.** Delayed jobs (`->delay(...)`) live in a sorted set ordered by their available-at time, so `onFront()` has no effect on them until they migrate onto the ready queue.
- **It breaks FIFO ordering.** Prepending is a priority side-channel. For stable, configuration-driven priorities prefer several queues served in order — or [weighted queues](https://boring-observability.dev/skyline/docs/weighted-queues).
- **It skews wait-time metrics.** Skyline estimates a queue's actual wait time from the job at the head of the list, on the assumption that it is the oldest. A freshly prepended job sits at the head, so actual wait time and long-wait notifications can under-report the true backlog on queues that receive front-pushed jobs. There is no cheap fix for this once FIFO is broken.
- **Redis only.** The behaviour relies on Redis list semantics and does not apply to the `sync` or `database` queue drivers.

> **Use it sparingly**
>
> If most of your jobs go to the front, none of them do. Front-of-queue dispatch works best as a rare, operator- or incident-driven action — the "this one customer's export is on fire" lever — not as a standing property of a job class.


## Common questions

### How do I push a Laravel job to the front of the queue?

Add the InteractsWithFrontOfQueue trait to the job class, then call onFront() on the pending dispatch: ProcessPodcast::dispatch($podcast)->onFront(). Skyline LPUSHes the payload onto the head of the Redis list instead of RPUSHing it onto the tail, so the next worker to poll takes it.

### Does onFront() work on delayed jobs?

No. Delayed jobs live in a sorted set ordered by their available-at time rather than on the ready list, so onFront() has no effect on them until they migrate onto the queue. It applies to immediate dispatches on the Redis driver only.

### Why does front-of-queue dispatch skew wait-time metrics?

Actual wait time is measured from the job at the head of the list, on the assumption that it is the oldest one. A freshly prepended job sits at the head while being brand new, so a queue that receives front-pushed jobs under-reports its actual wait time and its long-wait notifications.
