Updated June 2026. Tested on Laravel 13 and PHP 8.4. Part of the Techalyst queue series.

When you dispatch a job, its payload is stored in plain, serialized text in your queue store. For most jobs that is fine. But if a job carries something sensitive, a social security number, a card detail, a token, anyone or anything that can read your queue store can read that value. Laravel has a one line fix.

The problem: payloads are readable

Take a job that carries a social security number.

class VerifyUser implements ShouldQueue
{
    public function __construct(
        public User $user,
        public string $socialSecurityNumber,
    ) {}
}
VerifyUser::dispatch($user, '45678AB90');

Look at how it lands in the queue store and the value is right there in the serialized command string.

{
  "uuid": "765434b3-...",
  "data": {
    "commandName": "App\\Jobs\\VerifyUser",
    "command": "O:16:\"App\\Jobs\\VerifyUser\":...socialSecurityNumber\";s:9:\"45678AB90\";..."
  }
}

Anyone with access to Redis, the jobs table, or SQS can read 45678AB90 in plain sight. If your job holds anything you would not want sitting in a log, this is a real exposure.

The fix: ShouldBeEncrypted

Implement the ShouldBeEncrypted interface and Laravel encrypts the whole payload before storing it, decrypting it only inside your worker when the job runs.

use Illuminate\Contracts\Queue\ShouldBeEncrypted;

class VerifyUser implements ShouldQueue, ShouldBeEncrypted
{
    public function __construct(
        public User $user,
        public string $socialSecurityNumber,
    ) {}
}

Now the stored payload is ciphertext.

{
  "uuid": "765434b3-...",
  "data": {
    "commandName": "App\\Jobs\\VerifyUser",
    "command": "eyJpdiI6IjIyNWFQOXVNWn...ZTgyYjEifQ=="
  }
}

Anyone reading the queue store now sees only an encrypted blob. Encryption uses your application's APP_KEY, so only your application, holding that key, can decrypt and run the job. There is nothing else to configure.

Where it applies, and what to remember

ShouldBeEncrypted works not just on jobs but on queued mailables, notifications, and event listeners too, so any queued work carrying sensitive data can be protected the same way.

Two things to keep in mind. First, encryption depends on APP_KEY, so if you rotate that key while encrypted jobs are still sitting in the queue, those jobs can no longer be decrypted and will fail. Drain or be mindful of the queue around a key rotation. Second, encryption protects the payload at rest in the store, it does not replace good handling of that data once the job decrypts and runs it.

Wrapping up

Queued payloads are stored as readable serialized text, so sensitive values are exposed to anyone who can see your queue store. Implementing ShouldBeEncrypted encrypts the payload with your APP_KEY so only your workers can read it, and it applies to jobs, mailables, notifications, and listeners alike. If a job carries anything private, add the interface, it is a one line change for a real security win.

More in the series: how Laravel prepares a job for the queue and designing reliable, self-contained jobs. Questions welcome below.