Collection::count
Returns the number of items in the collection.
count(): int- Added in Laravel 4.0
Return value
int<0, max>The number of top-level items in the collection; 0 when empty.
Changelog
- PHP 8.xA native int return type was added to satisfy PHP 8's Countable::count() signature.
count() returns how many items the collection holds. Collection implements Countable, so PHP's count($collection) works identically and Blade's @forelse uses it automatically.
Top level only
It counts the collection's own items, not anything nested inside them. A collection of three groups, each holding ten models, counts as 3. Use ->flatten()->count(), or sum(fn ($g) => $g->count()), for the total.
Do not count to test emptiness
isEmpty() and isNotEmpty() say what they mean and read better than count() === 0. count() > 0 is not wrong, just noisier.
The expensive mistake
The real trap is counting a database result you did not need. User::all()->count() loads every row into PHP to produce a number; User::count() issues a SELECT count(*) and returns an integer. On a large table the difference is seconds and hundreds of megabytes. Only reach for the collection's count() when the records are already loaded and you need them anyway. The same applies to relations: $post->comments->count() hydrates every comment, while $post->comments()->count() and withCount('comments') do not.
Related
countBy() tallies occurrences by value or key rather than returning a single total.
Example
When to use it
- Show "12 results" above a list you have already loaded.
- Assert the expected number of records in a test.
- Decide whether a batch is large enough to be worth chunking.
Frequently asked questions
Is count($collection) the same as $collection->count()?
Yes — Collection implements PHP's Countable interface, so the native function delegates to the method and both return the same integer.
Why is my Laravel count() slow?
Because calling count() on a collection means every row was already loaded into PHP. Use Model::count() or $model->relation()->count() to issue a SELECT count(*) instead, or withCount() when listing many parents.
How do I count the items inside a grouped collection?
count() returns the number of groups, so call flatten()->count() for the total items, or sum(fn ($group) => $group->count()) to add up the group sizes.
More examples
Counting in the database instead of in PHP
Both counts print the same number, but the first builds 250,000 model objects to get it. The relation examples show the same distinction: the dynamic property hydrates, the method call delegates to SQL. withCount() adds a comments_count attribute in a single extra query, avoiding N+1. Needs a booted application with a database.
<?php
// Loads every row into memory, then counts the array.
$slow = User::all()->count();
// SELECT count(*) FROM users — one integer comes back.
$fast = User::count();
echo $slow, ' ', $fast, PHP_EOL;
// 250000 250000
// Same trap on relations:
$post = Post::find(1);
echo $post->comments->count(), PHP_EOL; // hydrates every Comment
echo $post->comments()->count(), PHP_EOL; // SELECT count(*)
// Best when listing: one extra query for all posts.
Post::withCount('comments')->get()->each(
fn (Post $p) => print "{$p->title}: {$p->comments_count}\n"
);Emptiness, nesting and Blade
The first block shows three equivalent emptiness checks; isEmpty() states the intent directly. The second shows why a grouped collection reports 2: count() sees two groups. flatten() or summing the inner counts gives the total number of underlying items.
<?php
$results = collect([]);
// Prefer the intent-revealing methods.
var_dump($results->isEmpty()); // bool(true)
var_dump($results->isNotEmpty()); // bool(false)
var_dump($results->count() === 0); // bool(true) — same answer, noisier
$byStatus = collect([
'open' => collect([1, 2, 3]),
'closed' => collect([4]),
]);
echo $byStatus->count(), PHP_EOL; // 2
echo $byStatus->flatten()->count(), PHP_EOL; // 4
echo $byStatus->sum(fn ($g) => $g->count()), PHP_EOL; // 4
Discussion