Laravel: pluck() vs modelKeys(): how to get an array of IDs from an Eloquent Collection
- 👤 Andrés Cruz
There are plenty of situations in Laravel where you just need an array of IDs from a set of models. Nothing fancy: no extra fields, no transformations… just the identifiers.
Sounds simple, but once you start working with Eloquent relationships, non-standard primary keys, or large tables, the decision between pluck() and modelKeys() actually matters more than it seems.
I’ve run into this exact problem many times, so let’s break it down properly.
The common problem: getting an array of IDs in Laravel
A very typical scenario looks like this:
- You have a
hasManyrelationship - One model already loaded
- You need the IDs of the related models
For example, a Role that has many Permission models.
At that point, you usually already have an Eloquent Collection, not a query builder — and that detail is key.
Working with Eloquent relationships (hasMany example)
$permissionIDs = $role->permissions->pluck('id'); This works, it’s readable, and most Laravel developers use it instinctively. And honestly, in real projects, this is still what I reach for most of the time.
But there’s a catch
Using pluck() to extract IDs from a Collection
Basic pluck('id') usage
pluck() extracts a given attribute from each model in the collection and returns a new collection containing those values.
$permissionIDs = $role->permissions->pluck('id'); You can later call ->toArray() if you really need a plain array.
When pluck() is the safest option
From experience, pluck() is the safest default when:
- You want a specific column
- You might later change the key name
- You’re not 100% sure how the collection was built
It works on:
- Query builders
- Eloquent models
- Eloquent collections
That flexibility alone makes it hard to beat.
Formatting values with pluck() closures
This is where pluck() really shines — especially after closure support was introduced.
For example:
Product::available()->get() ->pluck(fn ($product) => "{$product->brand} {$product->model}", 'id'); No extra map(). No mapWithKeys(). No intermediate transformations.
I’ve used this a lot in Blade views for dropdowns. It keeps the intent clear and the code chainable.
Using modelKeys(): what it really does
At first glance, modelKeys() looks like a neat shortcut:
$permissionIDs = $role->permissions->modelKeys(); Same result. Same character count. Slightly cooler
But what is it actually doing?
How modelKeys() works internally
modelKeys() simply returns:
“The array of primary keys from the models in the collection.”
That’s it.
No transformations. No formatting. No flexibility.
Primary keys and non-standard key names
One advantage of modelKeys() is that it respects custom primary keys.
If your model uses something other than id, modelKeys() will still work correctly — whereas pluck('id') would obviously fail unless you change the column name.
That’s usually the first reason developers notice this method.
Why modelKeys() only works on Collections
This part trips people up all the time.
❌ This will fail:
Permission::modelKeys(); Because modelKeys() does not exist on the model or query builder.
✅ This works:
Permission::all()->modelKeys(); But here’s the catch — and this is important in real projects.
Loading all records into memory just to extract IDs can be a serious performance problem on large tables. I’ve seen this done accidentally more than once.
pluck() vs modelKeys(): key differences
Flexibility vs simplicity
pluck()→ flexible, expressive, works everywheremodelKeys()→ simple, strict, collection-only
If you need anything beyond “just give me the primary keys”, pluck() wins immediately.
Performance considerations
In practice:
pluck('id')can be executed at the query levelmodelKeys()requires an already-loaded collection
That alone makes pluck() the better choice when performance matters.
Common mistakes and misconceptions
A common misunderstanding is thinking that modelKeys() is somehow “more efficient” because it sounds lower-level.
It isn’t.
If you already have the collection loaded, sure — it’s fine.
If you don’t, forcing a full all() just to call modelKeys() is usually a bad idea.
Common pitfalls when extracting values from Eloquent models
Why only() doesn’t work on model attributes
This comes up often (and there’s a classic Laracasts thread about it).
only() works on collection keys, not model attributes.
So this will return an empty collection:
$options->only('responses'); Because responses lives inside each model, not at the collection level.
Collection vs Model: the mental model
This is the key mental shift that solves most confusion:
- Collections contain models
- Collection methods don’t magically reach into model attributes
Once you internalize that, pluck() suddenly makes perfect sense — and methods like only() stop being tempting in the wrong places.
Which one should you use in real projects?
Clear decision rules
Use pluck() when:
- You don’t already have a loaded collection
- You need flexibility or formatting
- Performance matters
- You want predictable behavior everywhere
Use modelKeys() when:
- You already have a collection
- You only care about primary keys
- The primary key name might vary
What I actually use most of the time
In real-world Laravel apps, I still default to pluck('id').
modelKeys() is useful to know — and I’m glad it exists — but it’s more of an “interesting to know” method than something I reach for daily.
Frequently asked questions
Is modelKeys() faster than pluck()?
No. If anything, pluck() is often more efficient because it can run at the query level.
Can pluck() return formatted values?
Yes. With closures, it’s extremely powerful and replaces many map() use cases.
Does modelKeys() work on Eloquent models?
No. Only on Eloquent collections.
Can I get IDs without loading full models?
Yes — use pluck() directly on the query.
Conclusion
Both pluck() and modelKeys() solve the same surface-level problem, but they live at different layers of Eloquent.
If you understand when you’re dealing with a collection versus a query, the right choice becomes obvious almost every time.
Know modelKeys().
Use pluck().
I agree to receive announcements of interest about this Blog.
Learn when to use pluck() or modelKeys() in Laravel to get an array of IDs from Eloquent collections, with real examples and performance tips.