Getting an array of primary key values from an Eloquent collection is a common need — passing IDs to a whereIn() query, dispatching a job with a list of affected records, or serializing a selection for an API response. Laravel gives you three ways to do it, each with a different trade-off between brevity, flexibility, and performance.
:::note[TL;DR]
$collection->pluck('id')->toArray()— works on any column, not just the primary key$collection->modelKeys()— always returns the primary key values; no column name neededUser::where(...)->pluck('id')->toArray()— skip loading full models when you only need IDsmodelKeys()is the cleanest option when you already have a collection and need primary keys- Direct query
pluck()is most efficient — no model hydration :::
What is the quickest way to get IDs from a collection?
Scenario: You have a collection of selected users and need to pass their IDs to a
whereIn()query or a queued job.modelKeys()is the cleanest option — no column name to remember, no->toArray()call, always the primary key.
If you already have a collection in memory, use modelKeys():
$users = User::where('active', true)->get();
$ids = $users->modelKeys();
// Returns: [1, 4, 7, 12, ...]
modelKeys() is a Collection method that reads the model’s primary key definition. It works correctly even when the primary key is not named id — it checks getKeyName() under the hood.
How does pluck() compare to modelKeys()?
pluck() is more flexible — it works on any column, not just the primary key. But it requires you to know and pass the column name, and the return value is a Collection rather than a plain array, so you need ->toArray() if you need a PHP array.
$users = User::where('active', true)->get();
// pluck any column as a Collection
$emails = $users->pluck('email'); // Collection of emails
$ids = $users->pluck('id')->toArray(); // Plain PHP array of IDs
When you specifically want the primary key values, modelKeys() is shorter and more explicit. When you want any other column — or when you might need the column to be configurable — pluck() is the right choice.
What if I only need IDs and don’t want to load full models?
Query directly with pluck() on the builder instead of fetching full model instances first. This avoids hydrating each row into an Eloquent model object, which is faster when you only need a single column.
// Load full models, then extract IDs — two steps
$users = User::where('active', true)->get();
$ids = $users->modelKeys();
// Skip loading models entirely — one query, one column
$ids = User::where('active', true)->pluck('id')->toArray();
Both produce the same result. The second approach runs the same SQL but returns only the id column, so Laravel doesn’t build model instances at all.
Use the builder-level pluck() when:
- You’re working with large result sets
- You don’t need any other attributes from those rows
- You’re feeding the IDs directly into another query or job
How do I use IDs from a collection in a whereIn() query?
Pass the array directly to whereIn(). Both modelKeys() and pluck()->toArray() produce compatible PHP arrays.
$selectedUserIds = $request->input('user_ids'); // e.g. [1, 4, 7]
$users = User::whereIn('id', $selectedUserIds)->get();
// Now get their role IDs to pass to another query
$roleIds = UserRole::whereIn('user_id', $users->modelKeys())
->pluck('role_id')
->toArray();
Permission::whereIn('role_id', $roleIds)->get();
The chain is readable and avoids N+1 patterns — each step is a single query.
:::warning
On large tables, pluck('id') on the builder still runs a full table scan if there’s no index on the filtered column. Index your WHERE columns. Also, Collection::modelKeys() on a very large in-memory collection is fine — the CPU cost of iterating the collection is minimal. The real concern is whether the original query that built the collection is efficient.
:::
Summary
modelKeys()is the cleanest way to get primary key values from an existing collectionpluck('column')->toArray()is more flexible — use it for any column, or when you need a plain PHP array- Builder-level
pluck('id')skips model hydration entirely — best for large datasets where you only need IDs - All three approaches work in Laravel 10, 11, and 12
FAQ
What does modelKeys() return when the primary key is not ‘id’?
It returns whatever the model’s getKeyName() method returns. If your model has protected $primaryKey = 'uuid', then modelKeys() returns an array of UUID values.
Does pluck() on a Collection return a Collection or an array?
A Collection. Call ->toArray() to convert it to a plain PHP array. Builder-level pluck() also returns a Collection — same rule applies.
Is there a performance difference between modelKeys() and pluck(‘id’)?
On a collection already in memory, they’re negligible — both iterate the same data. The meaningful performance difference is between fetching full models with ->get() versus using builder-level ->pluck(), which skips model hydration.
Can I use these methods on a relationship collection?
Yes. $author->books->modelKeys() and $author->books->pluck('id')->toArray() both work on collections returned by relationship accessors.
Does pluck() on the builder work with composite primary keys?
For composite primary keys, modelKeys() returns the combined key values. Builder-level pluck('id') only gets one column — you’d need to specify both columns manually.
What to Read Next
- Laravel firstOrCreate(): Find or Create a Record — look up or create in one call
- Get Last 30 Days Records in Laravel — filtering Eloquent queries by date range
- Laravel Eloquent whereDate() Method Explained — date filtering on Eloquent collections