Laravel 12.8.0 2,157 (8 April 2025) added Model::automaticallyEagerLoadRelationships(), called in AppServiceProvider::boot(), and withRelationshipAutoloading() for one collection. Reading a missing relationship on one model then lazy eager loads it for the whole collection, and the loaded models inherit the behavior. The 12.x documentation labeled this beta; the 13.x documentation carries no such warning, and both methods exist in 13.33.0.
use App\Models\Customer;
use Illuminate\Database\Eloquent\Model;
$report = fn ($customers) => $customers->each(fn ($customer) => $customer->orders
->each(fn ($order) => $order->products->each(fn ($product) => $product->category->name)));
measure('lazy', fn () => $report(Customer::limit(100)->get()));
measure('collection', fn () => $report(Customer::limit(100)->get()
->withRelationshipAutoloading()));
Model::automaticallyEagerLoadRelationships();
measure('global', fn () => $report(Customer::limit(100)->get()));
measure('global+()', fn () => Customer::limit(100)->get()
->each(fn ($customer) => $customer->orders()->count()));lazy 1507 queries 885.0 ms in MySQL 1283.6 ms in all collection 4 queries 8.8 ms in MySQL 64.8 ms in all global 4 queries 9.1 ms in MySQL 65.3 ms in all global+() 101 queries 52.1 ms in MySQL 67.3 ms in all
Lazily the report costs 1 + 100 + 404 + 1,002 queries (customers, orders, each order's products, each product's category); autoloading needs the same four as with('orders.products.category'). It hooks property access only, so orders()->count() still runs once per customer, and it cannot select columns or constrain. Treat it as a safety net and keep with() where you know the shape.