How7o
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Reading: How to Count Rows in Laravel Eloquent Efficiently
Share
How7oHow7o
Font ResizerAa
  • OS
Search
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Follow US
© 2024–2026 How7o. All rights reserved.
How7o > Free Laravel, PHP, WordPress & Server Tutorials > Web Development > How to Count Rows in Laravel Eloquent Efficiently
Web Development

How to Count Rows in Laravel Eloquent Efficiently

how7o
By how7o
Last updated: April 20, 2026
6 Min Read
Laravel Eloquent count rows — Post::count query snippet with aggregate bar chart icon
SHARE

Getting a row count in Laravel should be a one-liner that hits the database with SELECT COUNT(*) and returns an integer. But it’s easy to accidentally pull every row into PHP first and count in memory — which works on tiny tables and falls over on real data. This guide covers the right way to laravel eloquent count rows, how withCount() avoids N+1 queries when counting relationships, and when NULL-aware count('column') or distinct counts are what you actually want.

Contents
  • TL;DR
  • Counting rows with a where clause
    • The anti-pattern to avoid
  • Counting relationships with withCount
  • Counting non-NULL values with count(‘column’)
  • Frequently asked questions
  • Related guides
  • References

Last verified: 2026-04-21 on Laravel 11 with PHP 8.3. Originally published 2022-10-07, rewritten and updated 2026-04-21.

TL;DR

Call ->count() at the end of any query builder or Eloquent chain — it emits SELECT COUNT(*) and returns an integer without hydrating rows. For counting relationships, use withCount('relation') to avoid N+1. Avoid Model::all()->count() — that loads the entire table into memory first.

Counting rows with a where clause

Both the query builder and an Eloquent model expose count(). They produce identical SQL — pick whichever fits the surrounding code:

$postCount = DB::table('posts')->where('user_id', '=', $user_id)->count();
$postCount = Post::where('user_id', '=', $user_id)->count();

Both emit:

SELECT COUNT(*) AS aggregate FROM posts WHERE user_id = ?

The database returns a single scalar, PHP casts it to int, and nothing gets hydrated into a model instance. Use the Eloquent form when you want global scopes (soft-delete filtering, tenant scoping) applied automatically; use DB::table() when you explicitly want to bypass them.

The anti-pattern to avoid

This looks innocent but runs a full table scan into PHP memory:

// WRONG — hydrates every matching row before counting
$postCount = Post::where('user_id', $user_id)->get()->count();
// even worse:
$allCount = Post::all()->count();

get() returns a collection of model instances; all() is even broader. Counting the collection works but does O(n) work on the PHP side for a value the database can return in O(1). Always end a chain with count() when a number is all you need.

laravel eloquent count rows — count, withCount, count(column), and distinct count comparison

Counting relationships with withCount

When you’re listing users and want to show each user’s post count, the obvious approach is the slow one:

// N+1: one extra COUNT query per user
foreach (User::all() as $user) {
    echo $user->name . ': ' . $user->posts->count();
}

Eloquent’s withCount() folds the count into a single aggregate subquery and attaches it as a {relation}_count attribute:

$users = User::withCount('posts')->get();
foreach ($users as $user) {
    echo $user->name . ': ' . $user->posts_count;
}

You can pass constraints inside withCount to count only matching related rows — for example, “count only published posts”:

User::withCount(['posts' => function ($q) {
    $q->where('status', 'published');
}])->get();

Counting non-NULL values with count(‘column’)

Pass a column name and count() ignores NULLs, which is occasionally useful:

// how many users have filled in a phone number?
$withPhone = User::count('phone');
// total users, NULLs included:
$total = User::count(); // same as count('*')

For a distinct count, wrap the column in a raw expression or use the fluent distinct():

$distinctCountries = User::count(DB::raw('DISTINCT country'));
// or:
$distinctCountries = User::select('country')->distinct()->count();

Both generate SELECT COUNT(DISTINCT country) FROM users.

Frequently asked questions

Is Model::count() faster than Model::all()->count()?

Yes — dramatically so on anything bigger than a few hundred rows. Model::count() emits SELECT COUNT(*) and returns an integer. Model::all()->count() loads every row into memory as a hydrated collection and then counts PHP objects. On a million-row table the first runs in milliseconds and the second will run out of memory.

How do I count a relationship without N+1 queries?

Use withCount('relation') on the parent query: User::withCount('posts')->get(). Each user row comes back with a posts_count attribute, loaded in a single additional aggregate query. Without it, calling $user->posts->count() in a loop issues one query per user.

Why does count('column') return a different number than count('*')?

count('column') counts only non-NULL values in that column. count('*') counts every row regardless. If the column is nullable, the two will diverge — which is sometimes what you want (“how many users have set a phone number?”) but usually not.

How do I get a distinct count in Eloquent?

Pass a raw expression: User::count(DB::raw('DISTINCT country')). Or use the fluent distinct(): User::select('country')->distinct()->count(). Both emit SELECT COUNT(DISTINCT country) under the hood.

When should I use DB::table() instead of the Eloquent model for counts?

If you only need a number and you don’t care about scopes, accessors, or casts, DB::table('posts')->where(...)->count() skips the model boot step and is marginally faster. In practice the gap is negligible for a single count() — use whichever reads better in context. Eloquent’s model is worth it when global scopes (like soft-delete filtering) should apply.

Related guides

  • How to Install Laravel on Ubuntu — get Laravel running before writing count queries.
  • How to Check If a Record Exists in Laravel — use exists() instead of count() > 0.
  • Best Way to Insert or Update Records in Laravel Eloquent — related single-query aggregate pattern.

References

Query-builder aggregates (count, sum, avg): laravel.com/docs/queries. Eloquent relationship counting and withCount: laravel.com/docs/eloquent.

TAGGED:EloquentLaravelmysqlperformancephpsql

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
[mc4wp_form]
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Previous Article Laravel Eloquent delete record — trash-bin icon next to User::destroy code snippet How to Delete a Record with Laravel Eloquent (4 Methods)
Next Article Laravel Eloquent group by count — Book::groupBy('author') query with bar-chart aggregate icon How to Count Records Grouped By a Column in Laravel Eloquent
Leave a Comment

Leave a Reply Cancel reply

You must be logged in to post a comment.

FacebookLike
XFollow
PinterestPin
InstagramFollow
Most Popular
Bun runtime — faster JS toolkit replacing npm in Laravel projects
How to Install Bun Runtime on Ubuntu (And Use It in a Laravel Project)
May 24, 2026
Tailscale mesh — peer-to-peer connections between devices, coordination server
How to Install Tailscale on Ubuntu (Zero-Config Mesh VPN for Self-Hosters)
May 24, 2026
Caddy server — automatic HTTPS, 3-line Caddyfile vs 25-line nginx config
How to Install Caddy Server on Ubuntu (Automatic HTTPS, Drop-in nginx Alternative)
May 24, 2026
Cloudflare Tunnel — outbound-only connection from server, no inbound port forward
How to Install Cloudflare Tunnel on Ubuntu (Expose Local Services, No Port Forwarding)
May 24, 2026
WireGuard encrypted tunnel between server and clients with lock icons
How to Set Up WireGuard VPN on Ubuntu (Server, Linux Client, and iOS)
May 24, 2026

You Might Also Like

Validate an email address in PHP with filter_var
Web Development

How to Validate an Email Address in PHP

5 Min Read
WooCommerce get customer ID from order — WC_Order::get_user_id
Web Development

How to Get the Customer ID from an Order ID in WooCommerce

7 Min Read
Fix 409 Conflict error in Laravel (cookies, cache, WAF)
Web Development

How I Fixed the 409 Conflict Error in Laravel (Cookie / Browser / WAF Fix)

7 Min Read
Laravel 403 forbidden on shared hosting — root htaccess rewrite into public folder
Web Development

Fix “403 Forbidden” on Laravel Shared Hosting

8 Min Read
How7o

We provide tips, tricks, and advice for improving websites and doing better search.

Tools

  • Age Calculator
  • Word Counter
  • Image Upscaler
  • Password Generator
  • QR Code Generator
  • See all tools→

Pranks

  • Fake Blue Screen Prank
  • Hacker Typer
  • Fake iMessage Generator
  • Windows XP Crash Prank
  • Windows 11 Update Prank
  • See all prank screens →

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service
  • Sitemap
© 2024–2026 How7o. All rights reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?