Get expert guidance in a few days with a Laravel code review

Storage Cache Store in Laravel 13.10.0

Last updated on by

Storage Cache Store in Laravel 13.10.0 image

Laravel v13.10.0 introduces a storage cache driver backed by Laravel's filesystem abstraction, making it possible to use an S3 disk (or any configured disk) as a key/value cache store without additional packages. It also adds a --stop-when-empty-for queue worker option, a WorkerIdle event, schedule group lifecycle callbacks, Schema::hasForeignKey(), and several queue testing improvements.

  • New storage cache driver backed by Laravel's filesystem
  • --stop-when-empty-for queue worker option
  • WorkerIdle event for idle worker detection
  • Lifecycle and output callbacks on Schedule::group()
  • Schema::hasForeignKey() helper
  • queue:failed --json output option
  • assertPushedOnce() testing helper
  • Enum queue names in QueueFake
  • WorkerOptions passed to additional worker events

What's New

Storage Cache Store

A new storage cache driver uses Laravel's filesystem / Storage services to store cached values. This is primarily useful for using an existing S3 disk as a key/value cache — no Redis or Memcached required.

The default config/cache.php now includes a storage store entry:

'storage' => [
'driver' => 'storage',
'disk' => env('CACHE_STORAGE_DISK'),
'path' => env('CACHE_STORAGE_PATH', 'framework/cache/data'),
],

Point CACHE_STORAGE_DISK at any configured disk (including s3) and the cache driver will read and write values through Laravel's filesystem layer. Each cached value is stored as a file containing a serialized payload with an expiration timestamp.

PR: #60131 by @taylorotwell

Queue Worker Idle Stop Option

queue:work now accepts a --stop-when-empty-for option that stops the worker after it has gone a configured number of seconds without processing any jobs:

php artisan queue:work --stop-when-empty-for=60

This stops the worker if no jobs have been processed for 60 seconds. It's useful for short-lived workers, scaled-down environments, or any situation where you want workers to exit automatically when queues go quiet rather than running indefinitely.

PR: #60176 by @taylorotwell

Worker Idle Event

A new WorkerIdle event is dispatched when a queue worker checks for a job and finds the queue empty. This is distinct from JobPopping, which fires on every pop attempt regardless of whether a job was found. Listening to WorkerIdle lets you detect workers that are genuinely unused — useful for rebalancing worker capacity or logging idle time.

PR: #60134 by @jackbayliss

Worker Configuration Passed to Additional Worker Events

WorkerOptions (which includes the --name flag and other worker configuration) is now passed to the Pausing, Resuming, Interrupted, and Looping worker events. Previously these events did not include the worker's configuration, making it harder to know which worker instance was involved in a listener.

PRs: #60135, #60153 by @jackbayliss

Schedule Group Lifecycle Callbacks

Schedule::group() now supports the same lifecycle and output callback methods available on individual events. This lets you attach callbacks once for an entire group instead of repeating them on each task:

Schedule::group(function (Schedule $schedule) {
$schedule->command('reports:generate');
$schedule->command('reports:email');
})->onFailure(function () {
// fires for any failing task in the group
})->onSuccess(function () {
// fires when each task in the group succeeds
});

PR: #60133 by @cosmastech

Scheduled Event Instance in Callbacks

Scheduled event callbacks (such as onSuccess, onFailure, and then) can now optionally receive the Event instance as a parameter. This gives the callback direct access to the event's configuration — its command, output path, and other properties:

$schedule->command('reports:generate')
->onFailure(function (Event $event) {
Log::error("Scheduled task failed: {$event->command}");
});

PR: #60144 by @cosmastech

Schema Foreign Key Existence Helper

A new Schema::hasForeignKey() method checks whether a specific foreign key constraint exists on a table, complementing the existing getForeignKeys() and hasIndex() helpers:

if (! Schema::hasForeignKey('orders', ['user_id'])) {
Schema::table('orders', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users');
});
}

This is useful in migrations, package install scripts, and schema assertions where you want to avoid adding a foreign key that already exists.

PR: #60169 by @Tresor-Kasenda

JSON Output for Failed Jobs

The queue:failed Artisan command now accepts a --json flag, outputting failed jobs as JSON. Each entry includes id, connection, queue, class, and failed_at. An empty result returns []. This matches the --json support already available on route:list, db:show, queue:monitor, and other commands.

PR: #60168 by @Tresor-Kasenda

SQS Overflow Flush on Queue Clear

The SQS extended store (added in 13.9.0) now supports a flush_on_clear option. When enabled, running queue:clear will also call flush() on the configured overflow cache store after purging SQS, reclaiming storage immediately rather than waiting for TTL expiration. This matters for S3-backed stores where leftover objects incur ongoing cost:

'sqs' => [
// ...
'extended_store_options' => [
'enabled' => true,
'disk' => 's3',
'flush_on_clear' => true,
],
],

This option defaults to false to preserve existing behavior. Note that for most cache stores, flush() wipes the entire store — point overflow.store at a dedicated cache store (the new storage driver is a natural fit here) to avoid unintended data loss.

PR: #60138 by @Orrison

Assert Job Pushed Once

Queue::assertPushedOnce() is a more readable alternative to Queue::assertPushedTimes(JobClass::class, 1):

// before
Queue::assertPushedTimes(ProcessOrderJob::class, 1);
 
// after
Queue::assertPushedOnce(ProcessOrderJob::class);

PR: #60150 by @weshooper

Enum Queue Names in Fake Queue Assertions

QueueFake now normalizes enum queue names the same way the real queue driver does. Passing a UnitEnum case as a queue name to push(), size(), or pendingJobs() now works correctly, and assertions against enum queue names behave consistently with their string equivalents.

PR: #60161 by @Tresor-Kasenda

Cloud Request ID in Logs

For applications running on Laravel Cloud, the request ID is now output in log entries using a custom JSON formatter. It appears as a standalone field rather than being nested inside the Monolog context or extra blocks.

PR: #60156 by @jradtilbrook

Miscellaneous Fixes and Improvements

  • Fix starts_with/ends_with rejecting numeric values — these validation rules now correctly handle numeric input by casting to string before comparison, restoring behavior from Laravel 12 (#60120 by @aydinfatih)
  • URL encode paths for signed URLs — storage paths are now URL-encoded before being placed into signed route path segments, fixing temporary signed URLs that contain ?, &, or # characters (#60137 by @taylorotwell)
  • Delimit aggregate alias — SQL aggregate function aliases are now delimited to prevent conflicts with reserved words (#60140 by @willrowe)
  • Optimize Worker queue pause check — the queue worker's pause check is now more efficient (#60109 by @jackbayliss)
  • Validate against line breaks in emails — email validation now rejects values containing line breaks (#60151 by @taylorotwell)

References

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Tinkerwell

Enjoy coding and debugging in an editor designed for fast feedback and quick iterations. It's like a shell for your application – but with multi-line editing, code completion, and more.

Visit Tinkerwell
Acquaint Softtech logo

Acquaint Softtech

Acquaint Softtech offers AI-ready Laravel developers who onboard in 48 hours at $3000/Month with no lengthy sales process and a 100 percent money-back guarantee.

Acquaint Softtech
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
SerpApi logo

SerpApi

Access real-time search engine results through a simple API—no more scraping headaches! Use it for AI applications, SEO tools, product research, travel information, and more

SerpApi
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media

The latest

View all →
Laravel MongoDB Full-Text Search tutorial: The Art of the Relevancy image

Laravel MongoDB Full-Text Search tutorial: The Art of the Relevancy

Read article
Drag-and-Drop Sorting for Eloquent Models with Reorderable for Laravel image

Drag-and-Drop Sorting for Eloquent Models with Reorderable for Laravel

Read article
Ship AI with Laravel: Real-Time Streaming Chat UI with Livewire image

Ship AI with Laravel: Real-Time Streaming Chat UI with Livewire

Read article
Frontend Nation 2026 Returns June 3-4 with Laravel in the Lineup image

Frontend Nation 2026 Returns June 3-4 with Laravel in the Lineup

Read article
Use a Google Sheet as Your Laravel Database with the Google Sheets Database Driver image

Use a Google Sheet as Your Laravel Database with the Google Sheets Database Driver

Read article
Larapanda: A Type-Safe Lightpanda Browser SDK for Laravel image

Larapanda: A Type-Safe Lightpanda Browser SDK for Laravel

Read article