MongoDB $bucketAuto Stage

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
Aggregation

What You’ll Learn

The $bucketAuto stage builds a histogram automatically—you pick how many bins (buckets) and which field (groupBy); MongoDB figures out the range edges from your data.

01

Auto edges

No boundaries array.

02

buckets count

How many bins to create.

03

_id min/max

Range object per bucket.

04

granularity

Round-number boundaries.

05

Custom output

count, avg, sum, $push.

06

vs $bucket

Auto vs fixed ranges.

Definition and Usage

$bucketAuto is an aggregation stage that divides documents into a fixed number of numeric buckets based on a groupBy expression. MongoDB inspects the minimum and maximum values in the pipeline input, then creates approximately equal-width intervals.

💡
Beginner tip

Each result document’s _id is an object: { min: 0, max: 250 } means “values from 0 up to (but not including) 250.” The last bucket’s max may equal the data maximum.

Use $bucketAuto for quick distribution charts—order amounts, response times, test scores—when you do not have predefined tiers. When ranges are fixed by policy, use $bucket instead. Add $avg or $sum inside output for richer stats.

📝 Syntax

$bucketAuto requires groupBy and buckets:

mongosh
{
  $bucketAuto: {
    groupBy: <expression>,
    buckets: <positive integer>,
    output: {
      <field1>: { <accumulator expression> },
      ...
    },
    granularity: <number>,
    facet: <expression>
  }
}

Syntax Rules

  • groupBy — required; numeric expression per document (field path, arithmetic, etc.).
  • buckets — required; target number of bins. MongoDB may merge empty adjacent buckets in edge cases.
  • output — optional; accumulators per bucket. Default: { count: { $sum: 1 } }.
  • granularity — optional; preferred rounding unit for boundaries (uses 1-2-5 series multiples).
  • facet — optional; bucket separately within each distinct facet value (advanced).
  • Output shape — one summary document per non-empty bucket; _id contains min and max.
mongosh
db.sales.aggregate([
  {
    $bucketAuto: {
      groupBy: "$amount",
      buckets: 4,
      output: { count: { $sum: 1 } }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage typeAuto histogram / dynamic range grouping
RequiredgroupBy, buckets (positive integer)
Bucket _id{ min: <n>, max: <n> } (nulls → both null)
Default output{ count: { $sum: 1 } }
vs $bucket$bucketAuto picks edges; $bucket uses your boundaries
IntroducedMongoDB 3.4 (with $bucket)
4-bin histogram
groupBy: "$amount"
buckets: 4

Quick chart

Round edges
granularity: 50

Cleaner axis labels

Revenue stats
output: {
  count: { $sum: 1 },
  total: { $sum: "$amount" }
}

Per-bin totals

Skip nulls
{ $match: {
  amount: { $type: "number" }
}}

Before $bucketAuto

🧰 Parameters

Keys inside the $bucketAuto object control auto-bucketing:

groupBy Required

Expression whose numeric result determines which bucket each document belongs to.

"$amount"
"$metrics.latencyMs"
buckets Required

Desired number of histogram bins. MongoDB divides the data range into roughly this many equal segments.

buckets: 5
buckets: 10
output Optional

Accumulator fields computed per bucket—same pattern as $group and $bucket.

count: { $sum: 1 }
avgMs: { $avg: "$latency" }
granularity Optional

Snaps boundaries to human-friendly multiples (powers of 10 × 1, 2, or 5).

granularity: 100
→ 0–100, 100–200, …

Examples Gallery

Sample sales orders—auto histograms, custom output, granularity for round bins, null handling, and comparison with fixed $bucket.

📚 Getting Started

Sample sales data and a basic auto histogram.

Example 1 — Sample sales collection

mongosh
db.sales.insertMany([
  { item: "Sticker pack", amount: 12,  region: "East" },
  { item: "T-shirt",      amount: 35,  region: "West" },
  { item: "Hoodie",       amount: 68,  region: "East" },
  { item: "Sneakers",     amount: 120, region: "West" },
  { item: "Jacket",       amount: 185, region: "East" },
  { item: "Laptop bag",   amount: 95,  region: "West" },
  { item: "Gift wrap",    amount: null, region: "East" }
]);

How It Works

Seven sale records with amount from $12 to $185—plus one null amount for the null-bucket demo later.

Example 2 — Four-bin amount histogram

mongosh
db.sales.aggregate([
  { $match: { amount: { $type: "number" } } },
  {
    $bucketAuto: {
      groupBy: "$amount",
      buckets: 4,
      output: { count: { $sum: 1 } }
    }
  },
  { $sort: { "_id.min": 1 } }
]);

/* MongoDB scans amounts 12…185, splits into ~4 equal ranges.
   Each row: _id: { min: …, max: … }, count: N
   Exact min/max depend on data; boundaries are computed automatically. */
*/

How It Works

You specify buckets: 4—MongoDB finds min (12) and max (185), divides the span, and assigns each sale. No boundaries array needed.

📈 Practical Patterns

Revenue totals, round boundaries, and comparison with $bucket.

Example 3 — Count and total revenue per bin

mongosh
db.sales.aggregate([
  { $match: { amount: { $type: "number" } } },
  {
    $bucketAuto: {
      groupBy: "$amount",
      buckets: 3,
      output: {
        count: { $sum: 1 },
        totalRevenue: { $sum: "$amount" },
        items: { $push: "$item" }
      }
    }
  }
]);

/* Each bucket shows how many orders and combined $ amount
   in that auto-computed price range. */
*/

How It Works

The output block mirrors $bucket—use any accumulators to summarize each auto-generated interval.

Example 4 — Round boundaries with granularity

mongosh
db.sales.aggregate([
  { $match: { amount: { $type: "number" } } },
  {
    $bucketAuto: {
      groupBy: "$amount",
      buckets: 4,
      granularity: 50,
      output: { count: { $sum: 1 } }
    }
  },
  { $sort: { "_id.min": 1 } }
]);

/* Without granularity → edges like 12, 55, 98 (data-driven)
   With granularity: 50 → edges snap toward 0, 50, 100, 150, 200
   Cleaner labels on charts and dashboards. */
*/

How It Works

granularity tells MongoDB to prefer boundary values that are multiples of round numbers—ideal when chart axes should read 0, 50, 100 instead of arbitrary splits.

Example 5 — $bucketAuto vs fixed $bucket

mongosh
// $bucketAuto — edges from data, 3 bins
db.sales.aggregate([
  { $match: { amount: { $type: "number" } } },
  {
    $bucketAuto: {
      groupBy: "$amount",
      buckets: 3,
      output: { count: { $sum: 1 } }
    }
  }
]);
// _id: { min, max } objects

// $bucket — YOU pick business tiers
db.sales.aggregate([
  {
    $bucket: {
      groupBy: "$amount",
      boundaries: [0, 50, 100, 200],
      default: "Other",
      output: { count: { $sum: 1 } }
    }
  }
]);
// _id: 0, 50, 100, 200, or "Other"

How It Works

Both stages produce histogram-style summaries. Choose $bucketAuto for discovery dashboards; choose $bucket when compliance or marketing defines exact breakpoints.

🧠 How $bucketAuto Works

1

Scan groupBy values

MongoDB evaluates groupBy on all input documents and finds the overall min and max (excluding null handling rules).

Scan
2

Compute boundaries

The range is divided into buckets segments. Optional granularity rounds edges to tidy numbers.

Split
3

Assign & aggregate

Each document lands in a bin; output accumulators update per bucket.

Aggregate
=

Histogram rows out

One document per bucket with _id: { min, max } and your stats.

📝 Notes

  • Bucket count may be fewer than buckets if MongoDB merges empty adjacent bins.
  • Null/missing groupBy values go to _id: { min: null, max: null }—filter with $match if unwanted.
  • All documents in the pipeline input affect boundary calculation—even outliers widen the range.
  • Sort by "_id.min" for left-to-right chart order.
  • granularity is a hint—MongoDB picks the nearest friendly multiple, not an exact guarantee on every dataset.
  • Previous topic: $bucket. Next: $changeStream.

Conclusion

$bucketAuto is the fastest path to a numeric histogram when you know how many bins you want but not where to draw the lines. Set groupBy and buckets, enrich with output, and add granularity for readable chart axes.

Switch to $bucket when ranges are fixed by business rules. Filter outliers or nulls before bucketing for cleaner results.

💡 Best Practices

✅ Do

  • Use $match first to drop nulls, test data, or extreme outliers
  • Start with 4–10 buckets for readable charts, then tune
  • Add granularity when axis labels should be round numbers
  • Sort by _id.min ascending before sending to a chart library
  • Pair with $project to add friendly labels from min/max

❌ Don’t

  • Use $bucketAuto when legal/compliance defines exact tier edges
  • Assume exact bucket count always equals buckets—empty bins may merge
  • Bucket categorical strings—use $group or $sortByCount
  • Ignore the null bucket when groupBy can be missing
  • Expect identical boundaries on every run if input data changes frequently

Key Takeaways

Knowledge Unlocked

Five things to remember about $bucketAuto

Use these points whenever you build data-driven histograms.

5
Core concepts
📊 02

buckets: N

Target bin count.

Required
📦 03

_id min/max

Range per bucket.

Output
🔢 04

granularity

Round boundaries.

Polish
🛠 05

vs $bucket

Auto vs fixed tiers.

Choose

❓ Frequently Asked Questions

$bucketAuto groups documents into a specified number of buckets (histogram bins) without you defining boundary values. MongoDB scans groupBy values in the input, computes min/max, and splits the range into roughly equal-width intervals.
groupBy (expression such as "$amount") and buckets (positive integer—how many bins you want). output is optional; if omitted, MongoDB adds count: { $sum: 1 }. granularity and facet are optional advanced options.
$bucket uses _id as a single lower-bound number (or default label). $bucketAuto uses _id: { min: <value>, max: <value> }—an object showing the inclusive min and exclusive max of each auto-computed range.
Use $bucketAuto for exploratory charts when you know how many bins you want but not exact edges—sales spread, latency distribution, score histograms. Use $bucket when business rules fix the ranges (tax brackets, age bands 0–18).
granularity nudges bucket boundaries toward round numbers from MongoDB's preferred series (1, 2, 5, 10, 20, 25, 50, 100…). Example: granularity: 100 may produce 0–100, 100–200 instead of 0–87, 87–174.
Documents where groupBy is null or missing are placed in a bucket whose _id is { min: null, max: null }. Filter with $match before bucketing if you want to exclude them.
Did you know?

The optional facet field in $bucketAuto lets you compute separate auto histograms for each distinct facet value in one stage—useful for per-region or per-category distribution charts. See the official $bucketAuto docs.

Continue the Stages Series

Build auto histograms with $bucketAuto, then explore real-time updates with $changeStream.

Next: $changeStream →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful