Between versions 13.17 and 13.27, Laravel published eleven minor releases in under three months, touching routing, database connections, queues, image handling, validation and security.

refreshForUpdate() in a transaction
DB::transaction(function () use ($product) {
    $product->refreshForUpdate();

    if ($product->stock === 0) {
        throw new RuntimeException('Product is out of stock.');
    }

    $product->decrement('stock');
});

13.17 introduced a metadata() method for routes, letting developers attach arbitrary data such as page titles without hacking the action array; group-level metadata cascades to child routes. The same release added native support for PostgreSQL connection poolers like PgBouncer, RDS Proxy and Neon, using a "pooled" config flag alongside a separate "direct" URL so commands like migrations bypass the pooler.

13.18 expanded queue observability: the WorkerStopping event now carries jobsProcessed and lastJobProcessedAt, and schedule:work catches SIGINT, SIGTERM and SIGQUIT so an in-progress scheduled task can finish before shutdown, useful in environments like Kubernetes.

13.19 added support for the HTTP QUERY verb through Http::query(), a reduceInto() collection method for mutating an accumulator object directly, and Str::counted() for formatting counts like "3 orders".

13.20 shipped a first-party image component, Illuminate\Image, for resizing, cropping and format conversion, removing the need to wire up Intervention Image manually. Every transformation returns a new immutable instance, so one source image can branch into several variants. It relies on Intervention Image v4 as an optional driver installed separately via Composer. The release also added a #[WithoutMiddleware] attribute to exclude middleware on specific controller methods.

13.21 added a #[RouteKey] attribute for setting the route-model-binding column on Eloquent models without overriding a method, more image output formats (PNG, GIF, AVIF, BMP), and a base64 validation rule checking RFC 4648 compliance.

13.22 introduced Validator::fakeDnsLookups() to stop active_url and email:dns validation tests from failing due to network flakiness, plus a #[BindWhen] attribute for container bindings evaluated conditionally via a closure, which requires PHP 8.5.

13.23 added a monthly log driver for apps that do not need daily log rotation, and tightened security by making maintenance-mode secret comparisons use hash_equals() consistently instead of mixing it with the == operator.

13.24 added dominantColor() to extract a placeholder color from an image while it loads, accepted HEIC and HEIF files as valid inputs instead of rejecting them, and introduced an arrayKeys validation rule restricting which keys an array is allowed to contain.

13.25 let developers pause or resume every named queue at once with queue:pause --all and queue:resume --all, instead of doing it queue by queue. The artisan dev command switched to a new terminal interface built on @laravel/multiplex, with separate tabs for the server, queue, Vite and logs, and automatic restart on crashes. Image also started implementing the Responsable interface, so it can be returned directly from a route.

13.26 added a read-through filesystem driver that reads from a primary disk and falls back to an older one when a file is missing, promoting accessed files to the primary disk automatically, easing gradual storage migrations. The #[DebounceFor] attribute, previously limited to queued jobs, now also works on queued event listeners.

13.27, the latest release, adds a mask_bindings_in_exception_messages database configuration option that replaces bound values with "?" placeholders inside QueryException messages, preventing data such as emails or phone numbers from leaking into logs, the failed_jobs table or APM tools; getBindings() still returns the real values for debugging. It also adds whereBinary() for case-sensitive column comparisons on MySQL and MariaDB without raw SQL, and refreshForUpdate(), an Eloquent method that refreshes an already-loaded model instance and applies lockForUpdate() in the same call, so a pessimistic lock no longer requires re-querying the model by primary key inside a transaction.