Problem: You need to know how many records match your query criteria, but loading all records just to count them wastes memory and performance.
Solution:
// Count all records in a table
$userCount = User::count();
// Count with conditions
$activeUsers = User::where('active', true)->count();
$recentPosts = Post::where('created_at', '>', now()->subDays(7))->count();
// Count related records
$user = User::find(1);
$postCount = $user->posts()->count();
$publishedCount = $user->posts()->where('status', 'published')->count();
// Using withCount() for relationships
$users = User::withCount('posts')->get();
foreach ($users as $user) {
echo $user->posts_count; // No additional queries
}
// Multiple counts
$users = User::withCount(['posts', 'comments'])->get();
$users = User::withCount([
'posts',
'posts as published_posts_count' => function ($query) {
$query->where('status', 'published');
}
])->get();
// Count vs Collection count()
// Database count (efficient)
$count = User::where('age', '>', 18)->count(); // SELECT COUNT(*)
// Collection count (inefficient for large datasets)
$count = User::where('age', '>', 18)->get()->count(); // Loads all records
Why it works: The query builder's count()
executes a COUNT(*)
SQL query, returning only the number without loading records into memory. withCount()
adds a count subquery, preventing N+1 problems when counting relationships.
Performance tip: Always use query builder count()
instead of collection count()
when possible. For paginated results, use total()
on the paginator.
Share this article
Add Comment
No comments yet. Be the first to comment!