Use profiler, logs, live-operation inspection, and query-shape analysis as bounded diagnostic tools with explicit performance and data-exposure costs.
Database Profiler, Slow Operation Thresholds, Logs, $currentOp, and Query Analysis
Triangulate slow operations with bounded profiler capture, diagnostic logs, $currentOp, comments, shape hashes, and optional managed query statistics.
Learning objectives
Separate historical profiler evidence, diagnostic logs, and
live $currentOp evidence by time horizon.
Configure profiler levels/filters only inside a bounded disposable diagnostic window.
Interpret slowms, sample rate, and filters
without assuming one setting controls every signal
identically.
Correlate operations with comment, shape
hashes, plan summaries, keys/docs examined, and memory/spill
fields.
Distinguish local Community diagnostics from optional
Atlas-only $queryStats query analysis.
This lesson pins MongoDB Community Server
8.3.8 with
mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim
and mongosh 2.10.0. The server is a disposable
standalone published only on loopback
127.0.0.1:27075. Authentication and TLS are
disabled only for this isolated local lab. Feature Compatibility
Version (FCV) is observed but never changed. Default read/write
concern and primary read preference apply. Atlas, Search, KMS,
and Enterprise Advanced are not mandatory. This lesson
temporarily changes profiler configuration only inside its
disposable database and restores profiling to level 0. MongoDB
8.3.8 strengthened authorization requirements around changing
slowms/sampleRate; production
deployments must use least-privilege administrative roles.
Runtime measurements are not pre-filled: this generation
environment has no Docker/mongod/mongosh runtime, so learners
must record the values produced on their own machine.
1. Choose the signal by time horizon
The database profiler writes captured
operations to the per-database capped collection
system.profile. The
diagnostic log records server messages,
including sampled slow operations.
$currentOp streams operations that are active
right now. These tools overlap in fields but answer different
questions.
| Signal | Best question | Main risk |
|---|---|---|
system.profile |
What slow/filtered operations happened during a bounded window? | Profiler overhead, disk use, sensitive query metadata. |
| Diagnostic log | What did the server report, including sampled slow operations/spills? | Log volume and sensitive command text. |
$currentOp |
What is running or waiting now? | Timing-sensitive; fast operations may finish before observation. |
$queryStats |
What query shapes accumulated runtime statistics? | Managed-tier availability and unstable output contract. |
docker rm -f atlasmart-mongo-ch12-l4 2>/dev/null || truedocker volume rm atlasmart-mongo-ch12-l4-data 2>/dev/null || truedocker run -d --name atlasmart-mongo-ch12-l4 \ -p 127.0.0.1:27075:27017 \ -v atlasmart-mongo-ch12-l4-data:/data/db \ mongodb/mongodb-community-server:8.3.8-ubuntu2204-slimmongosh "mongodb://127.0.0.1:27075/atlasmart?directConnection=true" --quiet --eval \'printjson({server:db.version(),hello:db.hello().isWritablePrimary}); printjson(db.getSiblingDB("admin").runCommand({getParameter:1,featureCompatibilityVersion:1}))'
2. Seed the disposable diagnostic workload
const c=db.orders_ch12_l4;c.drop();let b=[];for (let i=0;i<15000;i++) { b.push({_id:i,tenantId:`tenant-${i%25}`,status:i%5===0?"review":"ok",createdAt:new Date(Date.UTC(2026,7,1,0,i%60,0)+Math.floor(i/60)*3600000),payload:`payload-${i%200}`}); if (b.length===1000) { c.insertMany(b); b=[]; }}if (b.length) c.insertMany(b);printjson({count:c.countDocuments({}),profiling:db.getProfilingStatus()});
The default slowms is 100 ms. Slow-operation
logging uses working time rather than every form of elapsed
waiting. With profiler level 0, slowms/sampleRate
affect diagnostic logging; with profiling enabled they also
affect profiler capture unless a profiler filter is set. A
filter overrides slowms and
sampleRate for the filtered capture path.
3. Capture exactly one tagged profiler probe
Rather than enabling “profile everything,” the lab uses a comment-scoped filter. The comment becomes a correlation key visible in profiler/log/currentOp records. After the probe, profiling returns to level 0 and the filter is unset.
const c=db.orders_ch12_l4;print("original profile status"); printjson(db.getProfilingStatus());db.setProfilingLevel(1,{filter:{"command.comment":"ch12-l4-profiler-probe"}});c.find({tenantId:"tenant-7",status:"review"}).sort({payload:1}).comment("ch12-l4-profiler-probe").toArray();db.setProfilingLevel(0,{filter:"unset"});printjson(db.system.profile.find({"command.comment":"ch12-l4-profiler-probe"},{_id:0,op:1,ns:1,millis:1,workingMillis:1,planSummary:1,keysExamined:1,docsExamined:1,hasSortStage:1,usedDisk:1,planCacheShapeHash:1,planCacheKey:1,peakTrackedMemBytes:1}).sort({ts:-1}).limit(3).toArray());
Inspect the returned planSummary, keys/documents
examined, sort/disk flags, shape hashes, and 8.3 memory fields
if present. Absence of a field can be version/engine/operation
dependent; do not treat every optional field as mandatory
telemetry.
4. Use $currentOp for a live probe, not historical forensics
Run an intentionally expensive tagged query in one terminal and
the following admin aggregation immediately in another. If the
query finishes before observation, an empty array is a valid
result—not a monitoring failure. MongoDB recommends the
aggregation stage over the deprecated
currentOp command/helper.
const admin=db.getSiblingDB("admin");printjson(admin.aggregate([ {$currentOp:{allUsers:false,idleConnections:false,idleCursors:false,idleSessions:false}}, {$match:{"command.comment":"ch12-l4-currentop-probe"}}, {$project:{_id:0,op:1,ns:1,active:1,secs_running:1,microsecs_running:1,queryShapeHash:1,planSummary:1,waitingForLock:1,inUseTrackedMemBytes:1,peakTrackedMemBytes:1,command:1}}]).toArray());
const c=db.getSiblingDB("atlasmart").orders_ch12_l4;c.find({status:"ok"}).sort({payload:1,createdAt:-1}).comment("ch12-l4-currentop-probe").batchSize(1).toArray();
The lab does not change the host clock/firewall, disable indexes globally, or use server failpoints. On a fast machine the query may be too short to catch. In production, prefer naturally occurring tagged workload plus observability rather than deliberately making customer traffic slow.
5. Logs and optional query-shape analysis
MongoDB slow-query logs include plan-cache shape/key identifiers and, in 8.3, can include tracked-memory metrics plus slow-in-progress entries. Use the container log only for this disposable lab:
docker logs atlasmart-mongo-ch12-l4 --since 5m 2>&1 | grep -E 'ch12-l4|Slow query|planCacheShapeHash|planCacheKey' || true
$queryStats is useful query-shape analysis, but
current MongoDB documentation describes it as
unsupported/unstable and available on Atlas deployments with at
least an M10 cluster tier. It is therefore
optional, not a mandatory Academy lab.
Community learners get the same diagnostic reasoning from
explain + bounded profiler/log/currentOp evidence.
const admin=db.getSiblingDB("admin");admin.aggregate([ {$queryStats:{}}, {$match:{"key.queryShape.cmdNs.coll":"orders"}}, {$project:{_id:0,queryShapeHash:1,"metrics.execCount":1,"metrics.keysExamined":1,"metrics.docsExamined":1,"metrics.totalExecMicros":1,"metrics.usedDisk":1}}]).toArray();
6. Deliberately wrong: turn profiler level 2 on in production “for a few hours”
Level 2 profiles every operation and can materially degrade performance, consume disk, and expose unencrypted command/query data. A safer incident workflow starts with logs/currentOp/query-shape aggregates, narrows the target with comments or filters, enables the least invasive profiler window needed, records the previous settings, and restores them immediately afterward.
Production judgment. Monitoring privileges
expose operational metadata and sometimes user literals.
Restrict who can read profiler/currentOp output, avoid copying
sensitive query documents into tickets, and treat thresholds as
workload-specific—not universal. On mongos,
database profiling itself is unavailable; profile settings there
influence diagnostic logging instead.
docker rm -f atlasmart-mongo-ch12-l4docker volume rm atlasmart-mongo-ch12-l4-data
Check your understanding
- What is the main time-horizon difference between system.profile and $currentOp?
- What happens to slowms/sampleRate when a profiler filter is set?
- Why add a comment to diagnostic queries?
- Why is profiler level 2 a poor default incident response?
- Why is $queryStats optional here?
Review the answers
1. system.profile stores
captured historical operations;
$currentOp reports operations active at
observation time.
2. For filtered profiling/logging, the filter controls selection and slowms/sampleRate are not used for that capture path.
3. It provides a stable correlation token across profiler, logs, currentOp, and explain/command records.
4. It captures all operations and can add substantial performance, disk, and sensitive-data exposure.
5. Its current availability is tied to qualifying Atlas tiers and its output is explicitly unsupported/unstable, so the free local path cannot depend on it.
Authoritative references
- MongoDB 8.3 release notes — Current stable series, patch-sensitive behavior, 8.3 query-planning/profiling additions.
- Explain command — Verbosity modes and explain behavior.
- Explain results — Plan stages, execution statistics, query-shape hashes, and version-dependent output.
- Query plans — Candidate selection, cost-based ranker backup, plan-cache states, and cache invalidation.
- PlanCache.list() — Current mongosh plan-cache inspection interface.
- $planCacheStats — Plan-cache documents and engine-dependent output.
- Database profiler — Profiler levels, overhead, filters, thresholds, and security considerations.
- $currentOp — Preferred live-operation inspection stage.
- Slow query monitoring — Profiler/currentOp diagnostic workflow.
- $queryStats — Managed-deployment query-shape statistics and stability/availability caveats.
- Query shapes — MongoDB 8.x query-shape and plan-cache-shape terminology.
- Profiler output — Fields such as keys/docs examined, sort/disk, shape hashes, and 8.3 tracked-memory metrics.
- Log messages — Slow-operation log structure and 8.3 slow-in-progress additions.