Could we help you? Please click the banners. We are young and desperately need the money
When you're working with Laravel Collections, there’s a common pattern developers fall into: looping through a collection every time they need a particular model by a specific attribute. It works… at first. But it's inefficient, repetitive, and slows down your code as your dataset grows.
There’s a much smarter way.
In this post, I’ll show you why keyBy() is one of the most underrated Laravel Collection methods — and how using it can give you fast, direct access to specific items without looping or searching.
keyBy() in Laravel?keyBy() is a Collection method that re-indexes your collection based on a given attribute. Instead of numeric keys (0, 1, 2…), each item becomes keyed using a field from the model — turning your collection into something you can query instantly.
// Before using keyBy('nicename')
Collection {
0 => SubscriptionPlan {
id: 1,
nicename: 'plan_1',
...
},
1 => SubscriptionPlan {
id: 2,
nicename: 'plan_2',
...
},
2 => SubscriptionPlan {
id: 3,
nicename: 'plan_3',
...
},
3 => SubscriptionPlan {
id: 4,
nicename: 'plan_4',
...
},
}
// After applying keyBy('nicename')
Collection {
'plan_1' => SubscriptionPlan {
id: 1,
nicename: 'plan_1',
...
},
'plan_2' => SubscriptionPlan {
id: 2,
nicename: 'plan_2',
...
},
'plan_3' => SubscriptionPlan {
id: 3,
nicename: 'plan_3',
...
},
'plan_4' => SubscriptionPlan {
id: 4,
nicename: 'plan_4',
...
},
}
keyBy() Matters// Inefficient lookup
foreach ($subscriptionPlans as $plan) {
if ($plan->nicename === 'plan_1') {
return $plan;
}
}
// O(1) access — fast and clean
$plan = $plansByNicename->get('plan_1');
$plansByNicename = $subscriptionPlans->keyBy('nicename');
$plan = $plansByNicename->get('plan_1');
A loop is O(n) — the more results, the slower.
A keyed lookup is O(1) — constant time.
$plan = $plansByNicename->get($userSelectedPlan);
keyBy() in Laravel$plans = SubscriptionPlan::all();
$plansByNicename = $plans->keyBy('nicename');
return $plansByNicename->get('plan_1');
$plansByNicename = SubscriptionPlan::where('is_active', true)
->orderBy('sort_order')
->get()
->keyBy('nicename');
$plan = $plansByNicename->get('unknown_plan', new SubscriptionPlan);
| Feature | keyBy() | Loop + Compare | firstWhere() |
|---|---|---|---|
| Performance | Best | Worst | Good |
| Readability | Cleanest | Messy | Clear |
| Repeating Lookups | Excellent | Expensive | Moderate |
keyBy()If the key exists more than once, later items overwrite earlier ones.
$plans = $plansByNicename
->filter(fn ($p) => $p->is_active)
->keyBy('nicename');
pluck() with keyBy()$names = $plans->pluck('name', 'nicename');
keyBy()keyBy() once — reuse the mapped collection$plansByNicename, not $plansIf you're still looping through collections to find specific items, you're wasting time — and performance. Using keyBy() turns your collection into a fast, keyed map that makes your code cleaner, safer, and easier to work with.
Your future self — and your app performance — will thank you.