MongoDB $stdDevPop Accumulator

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

What You’ll Learn

The $stdDevPop accumulator measures population standard deviation in each $group bucket—how far numeric values typically spread from their average. Use it when the grouped data represents the complete population you care about.

01

Spread per group

Population std dev.

02

Simple syntax

{ $stdDevPop: "$field" }

03

vs $stdDevSamp

Population vs sample.

04

+ $avg

Mean and spread together.

05

Non-numeric skipped

Null and strings ignored.

06

Single value → 0

No spread with one point.

Definition and Usage

$stdDevPop is a MongoDB accumulator used in the $group stage. For each group, it evaluates a numeric expression on every document and returns the population standard deviation—a measure of how much values vary from their mean.

💡
Beginner tip

Think of $avg as “where is the center?” and $stdDevPop as “how scattered are the numbers?” Low std dev means scores cluster tightly; high std dev means wide spread.

Use $stdDevPop when your group contains all data you want to describe (every student in a class, every sale in a store for the month). When values are only a sample meant to represent a larger population, use $stdDevSamp instead.

📝 Syntax

$stdDevPop takes one expression inside $group:

mongosh
{
  $group: {
    _id: <expression>,
    <outputField>: { $stdDevPop: <expression> }
  }
}

Syntax Rules

  • Stage — primary use as accumulator in $group (also $bucket, windows).
  • Expression — field path like "$score" or a numeric formula.
  • Output — a decimal/double standard deviation value, or null if no numeric inputs exist.
  • Population formula — divides variance by N (count of numeric values), not N−1.
  • Non-numeric — null, missing, strings, booleans, and objects are ignored.
  • Single value — one numeric document in a group returns 0.
mongosh
db.users.aggregate([
  {
    $group: {
      _id: "$quiz",
      stdDev: { $stdDevPop: "$score" }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage$group accumulator
Syntax{ $stdDevPop: <expression> }
MeasuresPopulation standard deviation (spread)
vs $stdDevSampPop divides by N; sample divides by N−1
All non-numericReturns null
One numeric valueReturns 0
Per category
{ _id: "$quiz",
  std: { $stdDevPop: "$score" } }

Spread per quiz

Global
{ _id: null,
  std: { $stdDevPop: "$score" } }

All docs in one group

Mean + spread
avg:  { $avg: "$score" }
std:  { $stdDevPop: "$score" }

Center and variability

Round output
{ $round: ["$stdDev", 2] }

In $project stage

🧰 Parameters

$stdDevPop accepts one expression inside $group:

expression Required

Numeric value evaluated per document in the group. Non-numeric results are skipped from the calculation.

{ $stdDevPop: "$score" }
{ $stdDevPop: { $multiply: ["$price", "$qty"] } }
_id Group key

Defines buckets. Each group gets its own standard deviation based only on documents in that bucket.

_id: "$quiz"
return type Decimal | null

MongoDB returns the result as a decimal/double. Very large or precise financial data may use Decimal128 inputs.

8.04155872120988
ignored inputs Important

In $group, if the expression resolves to an array, it is treated as non-numeric and ignored. Unwind or project scalars first.

$match: { score: { $type: "number" } }

Examples Gallery

Quiz scores from the MongoDB docs—calculate spread per quiz, combine with $avg, and format readable output.

📚 Getting Started

Insert sample quiz scores and compute standard deviation per quiz.

Example 1 — Sample users collection

mongosh
db.users.insertMany([
  { _id: 1, name: "dave123", quiz: 1, score: 85 },
  { _id: 2, name: "dave2",   quiz: 1, score: 90 },
  { _id: 3, name: "ahn",     quiz: 1, score: 71 },
  { _id: 4, name: "li",      quiz: 2, score: 96 },
  { _id: 5, name: "annT",    quiz: 2, score: 77 },
  { _id: 6, name: "ty",      quiz: 2, score: 82 }
]);

How It Works

Three students per quiz—quiz 1 scores are 85, 90, 71; quiz 2 scores are 96, 77, 82. Both groups have similar spread (~8.04 population std dev).

Example 2 — Standard deviation per quiz

mongosh
db.users.aggregate([
  {
    $group: {
      _id: "$quiz",
      stdDev: { $stdDevPop: "$score" }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Result:
[
  { _id: 1, stdDev: 8.04155872120988 },
  { _id: 2, stdDev: 8.04155872120988 }
]
*/

How It Works

Each quiz group includes only its three scores. MongoDB computes population variance (divide by 3), then takes the square root for standard deviation.

📈 Practical Patterns

Combine mean and spread, compute globally, and round for dashboards.

Example 3 — Average and standard deviation together

mongosh
db.users.aggregate([
  {
    $group: {
      _id: "$quiz",
      avgScore: { $avg: "$score" },
      stdDev:   { $stdDevPop: "$score" },
      count:    { $sum: 1 }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Quiz 1:
   avgScore ≈ 82, stdDev ≈ 8.04, count: 3
   Quiz 2:
   avgScore ≈ 85, stdDev ≈ 8.04, count: 3 */
*/

How It Works

Reporting both center ($avg) and spread ($stdDevPop) in one $group gives a complete statistical snapshot per category.

Example 4 — Global population standard deviation

Treat all scores as one population with _id: null:

mongosh
db.users.aggregate([
  {
    $group: {
      _id: null,
      stdDev: { $stdDevPop: "$score" },
      avgScore: { $avg: "$score" }
    }
  }
]);

/* All six scores: 85, 90, 71, 96, 77, 82
   avg ≈ 83.5, stdDev ≈ 8.28 (population, N=6) */
*/

How It Works

_id: null merges every document into one bucket—useful for overall variability across an entire filtered dataset.

Example 5 — Round standard deviation for display

mongosh
db.users.aggregate([
  {
    $group: {
      _id: "$quiz",
      stdDev: { $stdDevPop: "$score" }
    }
  },
  {
    $project: {
      _id: 1,
      stdDev: { $round: ["$stdDev", 2] }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Quiz 1 → { _id: 1, stdDev: 8.04 }
   Quiz 2 → { _id: 2, stdDev: 8.04 } */
*/

How It Works

Raw std dev values have many decimal places. Use $round in $project for cleaner dashboard and report output.

🧠 How $stdDevPop Works

1

Documents bucketed

$group assigns each document to a bucket via _id.

Group
2

Numeric values collected

Each document’s expression is evaluated; non-numeric values are skipped.

Collect
3

Variance computed

MongoDB finds the mean, sums squared deviations, and divides by N (population variance).

Variance
=

Std dev returned

Square root of population variance—or 0 for one value, null if no numerics.

📝 Notes

  • $stdDevPop uses the population formula (divide variance by N)—not the sample formula (N−1).
  • Non-numeric values are ignored—same behavior as $avg and $sum.
  • A group with one numeric value returns 0 standard deviation.
  • In $group, an expression that resolves to an array is treated as non-numeric.
  • Result type is typically decimal/double—use $round for display.
  • Previous topic: $push. Next: $stdDevSamp.

Conclusion

$stdDevPop adds statistical spread to your aggregation reports. Use it when each $group bucket represents a complete population, and pair it with $avg for mean-and-variability summaries.

When data is only a sample of a larger population, switch to $stdDevSamp. For simple range checks, $min and $max may be enough.

💡 Best Practices

✅ Do

  • Use $stdDevPop when the group contains the full population you analyze
  • Combine $avg + $stdDevPop + $sum: 1 for complete stats
  • Filter non-numeric junk with $match before $group when data is messy
  • Round output with $round for human-readable dashboards
  • Choose $stdDevSamp when inferring about a larger population from a subset

❌ Don’t

  • Confuse population ($stdDevPop) with sample ($stdDevSamp) formulas
  • Expect meaningful spread from groups with only one or two numeric values without context
  • Pass array fields directly in $group—they are ignored as non-numeric
  • Compare std dev across groups with very different N without also showing counts
  • Use std dev on non-numeric categorical data—filter to numbers first

Key Takeaways

Knowledge Unlocked

Five things to remember about $stdDevPop

Use these points when measuring numeric spread inside $group.

5
Core concepts
📝 02

Simple syntax

{ $stdDevPop: "$field" }

Syntax
📈 03

vs $stdDevSamp

N vs N−1 divisor.

Compare
💲 04

+ $avg

Mean and spread.

Pair
🔢 05

One value → 0

No spread alone.

Edge case

❓ Frequently Asked Questions

$stdDevPop calculates the population standard deviation of numeric values in each $group bucket. It measures how spread out the values are around their mean, treating the grouped data as the entire population.
Inside $group: { spread: { $stdDevPop: "$score" } }. It also works in $project, $addFields, and window stages—but this tutorial focuses on the $group accumulator.
$stdDevPop divides by N (population formula). $stdDevSamp divides by N−1 (sample formula) when you want to estimate spread for a larger population. Use $stdDevPop when your group is the complete dataset.
Non-numeric values—including null, missing fields, strings, and objects—are ignored. If no numeric values exist in a group, $stdDevPop returns null.
$stdDevPop returns 0. With a single data point there is no spread around the mean.
$avg returns the mean (center). $stdDevPop returns the population standard deviation (spread). Pair both in one $group for mean-and-variability reports.
Did you know?

Population standard deviation divides by N; sample standard deviation ($stdDevSamp) divides by N−1 (Bessel’s correction) to better estimate spread when your data is a subset. For three scores 85, 90, and 71, both formulas happen to yield ~8.04—but they diverge as group size grows. See the official $stdDevPop docs.

Continue the Accumulators Series

Measure population spread with $stdDevPop, then learn $stdDevSamp for sample-based estimates.

Next: $stdDevSamp →

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