Relationships load lazily: Order::get() fetches orders only, and each $order->customer read sends its own SELECT. One query for the list plus one per row is the N+1 pattern:
use App\Models\Order;
DB::listen(fn ($query) => print('-- '.$query->toRawSql().PHP_EOL));
$orders = Order::where('status', 'shipped')->orderBy('id')->limit(3)->get();
foreach ($orders as $order) {
echo "order {$order->id}: {$order->customer->name}\n";
}Output
-- select * from `orders` where `status` = 'shipped' order by `id` asc limit 3 -- select * from `customers` where `customers`.`id` = 1 limit 1 order 1: Ana Souza -- select * from `customers` where `customers`.`id` = 2 limit 1 order 2: Ben Carter -- select * from `customers` where `customers`.`id` = 1 limit 1 order 4: Ana Souza
Each query runs on first access, and Ana Souza is fetched twice because sibling models share nothing. No query is visible in the code, which is why N+1 survives code review.

A JOIN would answer in one statement but repeat the customer columns on every order row. Eloquent's eager loading instead sends one WHERE ... IN (...) query per relationship and matches in memory, so the count no longer grows with the rows.