Eager loading a relationship with a plain with('author') pulls every single column from the related table, even when only the author's name is actually needed for display — for a wide table, or a relationship loaded on every request across a high-traffic page, that's real, avoidable overhead.
1. The default: every column
$posts = Post::with('author')->get();
// pulls id, name, email, password, remember_token, created_at, and every other
// column on the users table — for every single related author
2. Limiting columns with the colon syntax
$posts = Post::with('author:id,name')->get();
This is the concise shorthand for limiting an eager-loaded relationship to specific columns — cleaner than the closure-based form below for the common case of just naming a fixed column list.
3. The critical gotcha: the foreign key must be included
// BROKEN: author will be null for every post
$posts = Post::with('author:name')->get();
// CORRECT: id (the users table's primary key, referenced by posts.user_id) is included
$posts = Post::with('author:id,name')->get();
This is the single most common mistake with this feature. Eloquent needs the related table's key column present in the limited select to actually match related rows back to their parent — leaving it out doesn't throw an error; it just silently causes every relationship to resolve to null, which is a confusing failure mode if you don't know to check for exactly this.
4. Using a closure for more control (sorting, additional constraints)
$posts = Post::with(['author' => function ($query) {
$query->select('id', 'name', 'avatar');
}])->get();
The closure form is needed when the eager-loaded relationship also needs additional constraints beyond just column selection — an orderBy(), a where(), or anything more than a plain column list, none of which the colon shorthand syntax supports.
5. Applying this to a hasMany relationship too
$users = User::with('posts:id,user_id,title')->get();
The same rule applies regardless of relationship type — for a hasMany, the foreign key column (user_id here, referencing back to the parent) needs to be included in the limited select for Eloquent to correctly group the related rows under the right parent model.
6. When this optimization is actually worth doing
For a small users table with few columns, limiting the eager-loaded columns saves relatively little — the real benefit shows up on a wide table (many columns, some potentially large — a long text field, a big JSON blob) being eager-loaded frequently across high-traffic pages, where pulling unnecessary columns adds up across both database load and the memory footprint of the resulting Eloquent collection. It's a targeted optimization, not something to apply reflexively to every relationship in an app regardless of table width or traffic.