Laravel OrderBy relationship count
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Laravel Eloquent, the normal way to order models by the number of related records is withCount() followed by orderBy() or orderByDesc(). The reason this works is that withCount adds a computed {relationship}_count column to the query, which you can then sort like any other selected column.
Basic pattern with withCount
Suppose a User has many Post records:
Then:
Now each User model includes a posts_count attribute, and the result is ordered by that count.
This is the standard answer. You do not need to manually join and group in the common case.
Why the column is named posts_count
Laravel follows a simple naming rule:
So:
- '
posts()becomesposts_count' - '
comments()becomescomments_count'
That means the order column does not exist until withCount() is part of the query.
Conditional relationship counts
You can count only a filtered subset of related records:
This is useful when the real requirement is not "most posts overall" but "most published posts" or "most posts in the last 30 days."
Aliases keep the query readable when several counts are involved.
Multiple counts in one query
Laravel can add several relationship counts at once:
That gives each model:
- '
posts_count' - '
comments_count' - '
likes_count'
You can sort by any of them.
Sorting ascending or combining with eager loading
Descending order is common when you want the most active models first, but ascending order works the same way:
If the page also needs the related posts themselves, combine withCount with eager loading:
That keeps the count and the related data available in the same result set.
Filtering after withCount
Once the computed count column exists, you may want to filter on it too. Because it is part of the selected result, not a real table column, queries often use having when needed:
This is a common extension when you want "users with more than five posts, ordered by post count."
When not to use withCount
withCount is great for normal queries, but if the dataset is very large and the count is needed constantly, you may eventually consider a denormalized counter column such as users.posts_count.
That is not because withCount is wrong. It is because at scale, repeated count subqueries may become expensive compared with maintaining a cached counter.
For most ordinary application queries, though, withCount is the clean and idiomatic Eloquent solution.
Common Pitfalls
The biggest mistake is trying to order by posts_count without calling withCount('posts') first. The generated column does not exist otherwise.
Another mistake is using the wrong count column name. The generated attribute follows the relationship method name, not whatever table name you had in mind.
Developers also forget that withCount adds only the count, not the actual related models. If you also need the relationship data itself, add with('posts') separately.
Finally, do not overcomplicate the query with manual joins unless you actually need join-level control. Eloquent already has the simple count-ordering pattern built in.
Summary
- Use
withCount('relationship')to add a computed relationship count column. - Order by that generated column with
orderByororderByDesc. - Use aliases and closures for filtered counts such as published-only records.
- Use
havingwhen filtering on the computed count result. - For normal Laravel code,
withCountis the idiomatic way to sort by relationship count.

