Laravel Framework 13.33.0 is the 13.x release covered by the review published on 23 September 2026. The article is useful as a technical follow-up because it explains how the headline changes work in applications.

User.php
use Illuminate\Database\Eloquent\Attributes\Refreshes;

#[Refreshes('name')]
class User extends Model
{
}

Joost de Bruijn added tags() to the memoized cache store. Cache::memo() can now combine in-memory request caching with tagged caches. Repeated reads reach the backend once, then use the memoized value. Writes update the tagged cache and invalidate its memoized copy. Flushing a tag also removes the related memoized entries. Laravel 12.9 introduced the untagged memoized cache, which previously required a separate Cache::store('array') lookup for this pattern. The change is tracked in PR #61593.

Caleb White added the #[Refreshes] attribute and the matching $refreshes property for Eloquent models. They reload selected columns after a model is created or updated. The feature targets virtualAs, storedAs, and other database-generated values that can be absent or stale on the in-memory model. Laravel performs one query for the listed columns on the write connection. Column names can be supplied as an array or as variadic arguments. The example uses #[Refreshes('name')] on User and makes the generated value "Taylor Otwell" available after creating a user with first_name and last_name. PR #61523 contains the implementation.

Zein Ahmad added an opt-in nullable() mode to AsCollection and AsArrayObject. The regular casts continue to serialize an assigned null as the JSON string "null". The nullable variants write a database NULL, allowing whereNull() to match the row. The mode is available through AsCollection::nullable() and AsArrayObject::nullable(). The change is in PR #61596.

Sander Muller added inplace() and lock() modifiers for index and foreign key operations. A MySQL migration can request ALGORITHM=INPLACE and LOCK=NONE, which avoids a blocking table rebuild in supported cases. The modifiers apply to index(), unique(), primary(), fullText(), spatialIndex(), and foreign(). They extend the instant() modifier already available for column definitions. PR #61602 covers the change.

Md Sukkur Ali fixed attribute resolution for inherited form requests. PHP does not inherit attributes automatically, so #[StopOnFirstFailure] and #[FailOnUnknownFields] on a shared ApiRequest base class were previously ignored by child requests. StorePostRequest now receives those attributes when it extends ApiRequest. The fix is recorded in PR #61586.

Jack Bayliss added Worker::$killOnTimeout. The default behavior terminates the worker process when a job exceeds its timeout, after which the supervisor starts another worker. Setting the flag to false makes the worker throw TimeoutExceededException, allowing the job to clean up while the worker continues. A broad try/catch around handle() can consume that exception. Kieran Brown also added Worker::killUsing(), a hook that runs before SIGKILL and can pass a custom exit code to the supervisor. These changes appear in PRs #61591 and #61622.

Jenthe Noordsij split the two behaviors behind $this->artisan() into mockArtisan() and realArtisan(). The first returns a PendingCommand for expectations. The second executes the command and returns an integer exit code. Tests no longer need to switch $mockConsoleOutput. The helpers are covered by PR #61588.

The complete 13.33.0 changelog lists dozens of additional fixes and improvements: removal of restart_syscalls from pcntl_signal in Worker, adjustments to password-hash storage for authenticated sessions, enum-key fixes for tagged-cache many() and get(), Eloquent Collection duplicates() fixes with keys and callbacks, improved Cloud job retries, brick/math 0.20 and 1.0 support, health-start-period in workflows, order() for DevCommands, EncodedParameter for RouteUrlGenerator, stronger value types for Collection::put(), relative Mercure hub URLs, server options for PostgreSQL connections, MariaDB 11 and 12.3 CI coverage, valkey:// and valkeys:// protocol support, SQLite schema dump fixes for shadow tables, docblock spelling standardization, Composer --with-all-dependencies flag, phpredis client rebuilding after lost pipeline or transaction connections, --pretend on install:broadcasting, fresh batches passed to BatchFinished and BatchCanceled events, empty JSON arrays from route:list --json, default views for make:notification --markdown, test suite improvements, LazyCollection::take() fixes with large negative limits, unretryable batch skipping in queue:retry-batch, test consolidation and ordering fixes, FILESYSTEM_DISK override respect in Cloud configuration, database read replica support, opt-in native PostgreSQL pooling, non-string header handling in NotPwndVerifier, Redis 7.4 cursor error fixes in Predis scan(), query logging restoration after failing pretend callbacks, sole on higher-order proxies, createQuietly() and createManyQuietly() on BelongsToMany, and expression binding improvements in whereValueBetween().