MongoDB $collStats Stage

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

What You’ll Learn

The $collStats stage returns collection-level statistics—document count, storage footprint, index sizes, latency histograms, and collection scan metrics—ideal for monitoring dashboards and performance audits.

01

Storage stats

Size, indexes, avg doc.

02

Fast count

Metadata-based total.

03

Latency stats

Read/write histograms.

04

Query exec

Collection scan totals.

05

First stage

Pipeline must start here.

06

Sharded output

One doc per shard.

Definition and Usage

$collStats is an aggregation stage that inspects the collection you run it on and returns diagnostic documents. Unlike stages that transform user data row-by-row, it reports server-side metrics about the collection itself.

💡
Beginner tip

Think of $collStats as db.collection.stats() inside a pipeline. Pick the sections you need—storageStats for disk/index size, count for a quick document total, latencyStats for slow-read investigation.

Use $collStats in admin pipelines, health checks, and capacity planning. Combine options in one stage, then follow with $project to trim fields for a monitoring API. Not allowed inside transactions.

📝 Syntax

$collStats accepts an options object—all fields are optional but you typically enable at least one:

mongosh
{
  $collStats: {
    storageStats: { scale: <number> },
    count: {},
    latencyStats: { histograms: <boolean> },
    queryExecStats: {}
  }
}

Syntax Rules

  • First stage$collStats must be stage 1; otherwise MongoDB errors.
  • Combine options — enable multiple sections in one $collStats object.
  • storageStats{} uses bytes (scale 1); { scale: 1024 } shows KB.
  • count — fast metadata count; also available as storageStats.count when storage is enabled.
  • latencyStats — set histograms: true for latency range breakdowns.
  • ViewsstorageStats, count, and queryExecStats error on views.
mongosh
db.orders.aggregate([
  { $collStats: { storageStats: {} } }
]);

⚡ Quick Reference

QuestionAnswer
Stage positionMust be first in the pipeline
Output scopeStatistics for the collection being aggregated on
Common fieldsns, host, localTime, plus requested stats
Index sizesstorageStats.indexSizes, totalIndexSize
Sharded clusterOne result document per shard (includes shard field)
Shell equivalentdb.collection.stats()
Storage (bytes)
{ $collStats: {
  storageStats: {}
}}

Size & indexes

Storage (KB)
storageStats: {
  scale: 1024
}

Readable units

Doc count
{ $collStats: {
  count: {}
}}

Fast metadata

Latency hist.
latencyStats: {
  histograms: true
}

Slow ops

🧰 Parameters

Each key inside the $collStats object enables a stats section:

storageStats Optional

Collection storage engine stats: size, count, avgObjectSize, indexSizes, totalIndexSize, WiredTiger details.

storageStats: {}
storageStats: { scale: 1024 }
count Optional

Top-level document count from collection metadata. Fast but may be approximate on sharded clusters.

count: {}
→ { count: 1103869 }
latencyStats Optional

Read, write, command, and transaction latency since mongod startup. Add histograms: true for microsecond ranges.

latencyStats: {
  histograms: true
}
queryExecStats Optional

Query execution metrics—especially collectionScans.total (queries that scanned the whole collection).

queryExecStats: {}
→ collectionScans: { total, nonTailable }

Examples Gallery

Sample orders collection—storage overview, scaled sizes, fast count, latency histograms, and collection scan diagnostics.

📚 Getting Started

Seed a collection, then inspect it with $collStats.

Example 1 — Sample orders collection

mongosh
db.orders.drop()
db.orders.createIndex({ customerId: 1 })
db.orders.insertMany([
  { customerId: "C001", product: "Keyboard", amount: 45,  status: "shipped" },
  { customerId: "C002", product: "Mouse",    amount: 25,  status: "pending" },
  { customerId: "C001", product: "Monitor",  amount: 220, status: "shipped" },
  { customerId: "C003", product: "Webcam",   amount: 60,  status: "pending" },
  { customerId: "C002", product: "Headset",  amount: 80,  status: "shipped" }
])

How It Works

Five orders with one secondary index—enough data for meaningful storage and count stats in the examples below.

Example 2 — Storage and index sizes

mongosh
db.orders.aggregate([
  { $collStats: { storageStats: {} } },
  {
    $project: {
      ns: 1,
      host: 1,
      count: "$storageStats.count",
      dataSize: "$storageStats.size",
      avgDoc: "$storageStats.avgObjectSize",
      indexes: "$storageStats.nindexes",
      totalIndexSize: "$storageStats.totalIndexSize"
    }
  }
])

/* Sample shape:
{
  ns: "test.orders",
  host: "localhost:27017",
  count: 5,
  dataSize: 1234,           // bytes (scale 1)
  avgDoc: 246,
  indexes: 2,               // _id + customerId
  totalIndexSize: 8192
} */

How It Works

storageStats: {} returns WiredTiger (or your engine) details. Chain $project to expose only the metrics your dashboard needs.

📈 Practical Patterns

Scaled units, fast counts, latency, and scan diagnostics.

Example 3 — Fast document count with scale factor

mongosh
// Count only — lightweight
db.orders.aggregate([
  { $collStats: { count: {} } }
])
// → { ns, host, localTime, count: 5 }

// Storage in kilobytes (scale 1024)
db.orders.aggregate([
  {
    $collStats: {
      storageStats: { scale: 1024 },
      count: {}
    }
  },
  {
    $project: {
      count: 1,
      dataSizeKB: "$storageStats.size",
      indexSizeKB: "$storageStats.totalIndexSize",
      scaleFactor: "$storageStats.scaleFactor"
    }
  }
])

How It Works

Use count: {} alone when you only need totals. Add storageStats: { scale: 1024 } when reporting human-readable KB/MB sizes to ops teams.

Example 4 — Read/write latency histograms

mongosh
// Run some reads/writes first so stats accumulate
db.orders.find({ status: "shipped" }).toArray()
db.orders.insertOne({ customerId: "C004", product: "Dock", amount: 90, status: "pending" })

db.orders.aggregate([
  {
    $collStats: {
      latencyStats: { histograms: true }
    }
  },
  {
    $project: {
      ns: 1,
      readOps: "$latencyStats.reads.ops",
      readLatencyMicros: "$latencyStats.reads.latency",
      writeOps: "$latencyStats.writes.ops",
      readHistogram: "$latencyStats.reads.histogram"
    }
  }
])

/* latencyStats tracks ops since mongod started.
   histogram[] → { micros, count } latency buckets. */

How It Works

latencyStats helps spot slow collections. Histogram buckets show how many operations fell into each microsecond range—useful when tuning indexes after seeing high-latency tails.

Example 5 — Collection scan diagnostics

mongosh
// Unindexed query — may increment collection scan counter
db.orders.find({ notes: "rush order" }).toArray()

db.orders.aggregate([
  { $collStats: { queryExecStats: {} } },
  {
    $project: {
      ns: 1,
      collScans: "$queryExecStats.collectionScans.total",
      nonTailableScans: "$queryExecStats.collectionScans.nonTailable"
    }
  }
])

/* High collectionScans.total → missing indexes or
   queries that cannot use indexes. Add indexes or
   rewrite queries, then compare over time. */

// Compare with db.collection.stats() shell helper:
db.orders.stats({ scale: 1024 })

How It Works

queryExecStats surfaces how often queries scanned entire collections— a red flag for performance. Use alongside the explain plan and index builds.

🧠 How $collStats Works

1

Pipeline starts on collection

$collStats runs as stage 1 against the target collection namespace.

Target
2

Server gathers metrics

MongoDB reads storage engine metadata, counters, and latency trackers for requested sections.

Collect
3

Stats document emitted

One doc (or one per shard) with ns, host, and enabled stat blocks.

Output
=

Downstream stages process

Optional $project, $merge, or export to monitoring systems.

📝 Notes

  • $collStats is not allowed in transactions.
  • After an unclean shutdown, size/count stats may be inaccurate until you run validate on the collection.
  • count from metadata is fast but can drift on sharded clusters—use $count or countDocuments() for precision.
  • On sharded collections, sum per-shard count values yourself for a cluster total.
  • Time series collections include extra storageStats.timeseries bucket diagnostics.
  • Previous topic: $changeStream. Next: $count.

Conclusion

$collStats puts collection diagnostics inside your aggregation toolbox. Enable storageStats for capacity planning, latencyStats for slow-operation analysis, and queryExecStats to catch full collection scans.

For a quick shell check use db.collection.stats(); for automated pipelines use $collStats as stage one, then shape output with $project. Next: $count.

💡 Best Practices

✅ Do

  • Request only the stat sections you need—smaller payloads, faster queries
  • Use scale: 1024 or 1048576 for KB/MB reporting
  • Follow with $project to build clean monitoring API responses
  • Track queryExecStats.collectionScans over time after index changes
  • On sharded clusters, aggregate per-shard results explicitly

❌ Don’t

  • Place any stage before $collStats
  • Trust metadata count alone for billing-critical exact totals
  • Run storageStats on views—it errors
  • Use inside multi-document transactions
  • Confuse cumulative latency stats (since startup) with per-query profiler data

Key Takeaways

Knowledge Unlocked

Five things to remember about $collStats

Use these points when monitoring MongoDB collections.

5
Core concepts
📚 02

First stage

Pipeline rule.

Syntax
📈 03

storageStats

Scale for KB/MB.

Storage
⏱️ 04

latencyStats

Histogram option.

Perf
🔍 05

Coll scans

queryExecStats.

Tune

❓ Frequently Asked Questions

$collStats returns statistics about the current collection—storage size, document count, index sizes, optional latency histograms, and query execution metrics. It must be the first stage in an aggregation pipeline and is used for monitoring and performance tuning.
Always first: db.orders.aggregate([{ $collStats: { storageStats: {} } }]). If any stage appears before $collStats, MongoDB returns an error.
All optional: storageStats (sizes, indexes), count (document total), latencyStats (read/write latency with optional histograms), queryExecStats (collection scan counts). Combine them in one object: { $collStats: { storageStats: {}, count: {} } }.
Both expose collection statistics. $collStats runs inside an aggregation pipeline so you can chain $project or $merge afterward. db.collection.stats() is a direct shell helper—often simpler for quick checks.
Partially. storageStats, count, and queryExecStats return errors on views. latencyStats can work on views. For physical storage details, run $collStats on the underlying collection.
$collStats outputs one document per shard, each with a shard field. Count values come from per-shard metadata and may be approximate—use $count or countDocuments for exact totals when accuracy matters.
Did you know?

$collStats was introduced in MongoDB 3.2 for aggregation-based monitoring. On time series collections, storageStats.timeseries exposes bucket-level metrics like bucketCount and numCommits. See the official $collStats docs.

Continue the Stages Series

Inspect collection health with $collStats, then count matching documents with $count.

Next: $count →

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