A policy that loads the resource’s owner runs once per row, and eager loading in the controller cannot see it.
// 50 rows → 50 queries, invisible to the eager loader
$orders->filter(fn ($o) => $user->can('view', $o));
// the batch form: one query, then an in-memory check
$visibleIds = $this->policy->visibleOrderIds($user, $orders->pluck('id'));
$orders->filter(fn ($o) => $visibleIds->contains($o->id));
Authorisation is invisible to the query planner and to every N+1 detector that only watches the ORM, which is why this survives a profiling pass. The cost is a second way to write a check and therefore a rule about which to use — the per-object form for a single resource and the batch form for a collection, enforced by review rather than by a tool.