The $limit stage keeps only the first N documents from the current pipeline and drops the rest—essential for top-10 lists, paginated APIs, and trimming heavy intermediate results before expensive downstream stages.
01
Cap output
First N docs.
02
Top-N lists
After $sort.
03
Pagination
$skip + $limit.
04
After $group
Top categories.
05
Performance
Less downstream work.
06
vs $sample
Ordered vs random.
Fundamentals
Definition and Usage
$limit is an aggregation stage that restricts how many documents continue to the next stage. It is the pipeline equivalent of .limit(N) on a find cursor—simple, fast, and one of the most commonly used stages in production pipelines.
💡
Beginner tip
$limit alone does not sort. For “top 5 highest scores,” always write $sort first, then $limit: 5. The limit stage takes whatever order the previous stage produced.
Use $limit after filtering ($match), sorting ($sort), or grouping ($group) when the UI or API only needs a subset. Pair with $skip for offset-based pagination.
Foundation
📝 Syntax
$limit accepts a single positive integer:
mongosh
{ $limit: <positive integer> }
Syntax Rules
Positive integer — N must be ≥ 0. { $limit: 0 } returns no documents.
First N only — passes documents in the order received from the prior stage.
Sort first — for ranked results, place $sort immediately before $limit.
Eight articles with views, category, and published flags—enough data to see how $limit trims results after filter and sort stages.
Example 2 — Return only 3 documents
mongosh
db.articles.aggregate([
{ $match: { published: true } },
{ $limit: 3 },
{ $project: { title: 1, views: 1, _id: 0 } }
])
// Returns exactly 3 published articles
// Order is NOT guaranteed without $sort
// → arbitrary first 3 in scan/processing order
📤 Basic cap:
3 documents max
7 published exist → 3 returned
Add $sort for meaningful order
How It Works
$limit stops the pipeline after N documents—downstream stages process fewer rows. Without $sort, which three you get depends on internal processing order, not business logic.
$sort defines ranking
$limit trims to 3
Index on views helps performance
How It Works
This is the classic leaderboard pattern: $match filters, $sort ranks, $limit keeps the head of the list. MongoDB can apply top-k optimization when sort and limit are adjacent.
3 articles (4th–6th newest)
Stable order requires $sort
Large $skip gets slow—prefer cursors
How It Works
$skip advances the window; $limit sets page size. Always sort by a unique or stable key (often createdAt + _id) so pages do not shift when new documents insert between requests.
Example 5 — Top 2 categories by total views (after $group)
Database → highest totalViews
Backend → second
$limit after $group reduces output rows
How It Works
$group shrinks many articles into few category rows; $sort + $limit picks the top two. The same pattern works after $geoNear for “nearest 5 locations” on a map.
Compare
📋 $limit vs related result-shaping stages
Stage / API
Effect
Best for
$limit
First N docs in current order
Top-N, page size, trimming output
$skip
Skip first N docs
Pagination offset (pair with $limit)
$sample
Random N docs
Statistical samples, spot checks
find().limit()
Cap query cursor results
Simple queries without aggregation
$facet + $limit
Limit inside sub-pipeline
Paginated items + total count facet
🧠 How $limit Works
1
Input stream
Documents arrive from the previous stage in whatever order that stage produced.
Input
2
Counter stops at N
$limit emits documents one by one until the count reaches N, then stops reading further input.
Cap
3
Downstream continues
Later stages ($project, $lookup) process only the limited set—saving CPU and memory.
Pass
=
📚
Bounded result
At most N documents reach the client—ideal for APIs with fixed page sizes or dashboard widgets.
Important
📝 Notes
$limit does not sort—pair with $sort for ranked top-N results.
{ $limit: 0 } is valid and returns zero documents.
Large $skip values (deep pagination) scan and discard many docs—consider cursor-based paging for page 100+.
MongoDB may fuse $sort + $limit into an efficient top-k plan when an index supports the sort.
In $facet, each sub-pipeline can have its own $limit (e.g. paginated items vs full count).
Index fields used in $match + $sort for top-N queries
Use stable sort keys (_id as tiebreaker) for consistent pagination
Place $limit before expensive stages like $lookup when possible
Combine with $facet when the API needs rows + total count
❌ Don’t
Expect meaningful “top N” without a preceding $sort
Use very large $skip on big collections without performance testing
Confuse $limit with $sample for random selection
Assume $limit alone reduces collection scan work without sort/index support
Forget that fewer than N input docs means a shorter result—not an error
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about $limit
Use these points whenever you cap or paginate aggregation results.
5
Core concepts
📚01
First N
Cap output.
Basics
📈02
$sort first
Meaningful top-N.
Pattern
📄03
$skip + $limit
Pagination.
API
⚡04
Top-k opt
Sort + limit fuse.
Perf
🎲05
vs $sample
Ordered vs random.
Compare
❓ Frequently Asked Questions
$limit passes only the first N documents from its input to the next pipeline stage and discards the rest. Use it to cap result size—for example, return the top 10 rows after $sort or the first page of a paginated API.
{ $limit: <positive integer> }. Example: { $limit: 5 } returns at most five documents. If fewer than N documents arrive from the prior stage, you get all of them.
Yes, when you need a meaningful top-N—such as newest orders or highest scores. Without $sort, $limit returns an arbitrary first N documents (often collection scan order), which is rarely what you want for ranked lists.
Combine $skip and $limit: page 1 → { $skip: 0 }, { $limit: 20 }; page 2 → { $skip: 20 }, { $limit: 20 }. Always $sort first for consistent pages. For large offsets, consider cursor-based pagination instead of high $skip values.
$limit takes the first N documents in current pipeline order. $sample randomly selects N documents (or all if the collection is smaller). Use $limit for ranked or ordered slices; $sample for random subsets.
It can—especially after $sort when MongoDB applies top-k optimization, or after $match/$sort on an indexed field. Placing $limit early reduces work for downstream stages, but only when earlier stages already produce the correct ordering.
Did you know?
When $sort and $limit are adjacent, MongoDB can use a top-k optimization that avoids sorting the entire collection—especially effective with a supporting index. For deep pagination, cursor-based approaches (filtering by _id > lastSeenId) often outperform large $skip values. See the official $limit docs.