Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
MongoDB's profiler is genuinely excellent — it records the full command, the plan summary, the number of keys and documents examined, lock time, and how long the operation waited on flow control — but it writes those records into a real collection inside the database it is profiling, which makes it the one diagnostic tool in this course that can cause the outage it is meant to diagnose. At level 2 on a busy primary it writes a document for every single operation, and since system.profile is a capped collection, those writes contend for the same WiredTiger resources as your actual workload while simultaneously rolling old records out of the window you wanted to analyse. The safe configuration is not obvious from the documentation: level 1 with a slowms threshold you have actually chosen, a sample rate below 1 if traffic is high, and a capped collection sized for the window you need rather than the 1MB default. Getting this right is a prerequisite for everything else, because the profiler is where the plan of a real production query comes from.
The full set of profiler knobs, what each one costs, and the query that turns a pile of profile documents into a diagnosis.
const db = db.getSiblingDB("qp");
// ── The three levels ─────────────────────────────────────────────
// 0 — off (default). Slow ops still go to the mongod log if they
// exceed slowms; you just do not get structured records.
// 1 — record operations slower than slowms. Safe in production.
// 2 — record EVERY operation. A write amplifier. Use on a replica,
// for a bounded window, or on a development box only.
db.getProfilingStatus();
// { was: 1, slowms: 200, sampleRate: 1, ok: 1 }
// ── Setting it safely ────────────────────────────────────────────
db.setProfilingLevel(1, {
slowms: 100, // your threshold, not the 100ms default by accident
sampleRate: 0.25, // profile 25% of qualifying ops. Cuts overhead 4x.
});
// sampleRate applies to level 1 AND to the log. At 0.25 your counts are
// a quarter of reality — multiply before you report them, and never use
// a sampled profile to claim "this query ran N times".
// ── Sizing system.profile ────────────────────────────────────────
// It is a CAPPED collection, default 1MB. At ~1KB per record that is
// roughly a thousand operations before the oldest scrolls off. On a
// busy system your window is seconds. Resize it (requires profiling off):
db.setProfilingLevel(0);
db.system.profile.drop();
db.createCollection("system.profile", { capped: true, size: 256 * 1024 * 1024 });
db.setProfilingLevel(1, { slowms: 100 });
// ── The fields that actually matter ──────────────────────────────
db.system.profile.findOne(
{ ns: "qp.orders", op: "query" },
{ ts: 1, millis: 1, planSummary: 1, keysExamined: 1, docsExamined: 1,
nreturned: 1, responseLength: 1, "command.filter": 1,
"command.sort": 1, numYield: 1, "locks.Global.acquireCount": 1,
fromMultiPlanner: 1, replanned: 1 }
);
// {
// ts: ISODate("2026-09-12T10:14:02.118Z"),
// millis: 2840,
// planSummary: "COLLSCAN", <- no index used
// keysExamined: 0, <- confirms it: zero index keys
// docsExamined: 2000000, <- read the entire collection
// nreturned: 23, <- to return 23 documents
// numYield: 15625, <- yielded the lock 15k times
// command: { filter: { userId: 8812, status: "refunded" } }
// }
//
// docsExamined / nreturned = 86,956. That ratio is the headline number
// of this whole course. Module 3 makes it rigorous; for now, anything
// above ~100 means you are reading far more than you return.
// ── The diagnosis query ──────────────────────────────────────────
db.system.profile.aggregate([
{ $match: { millis: { $gt: 100 }, ns: { $not: /system/ } } },
{ $project: {
ns: 1, millis: 1, planSummary: 1, nreturned: 1, docsExamined: 1,
waste: { $cond: [{ $gt: ["$nreturned", 0] },
{ $divide: ["$docsExamined", "$nreturned"] },
"$docsExamined"] },
filter: { $objectToArray: { $ifNull: ["$command.filter", {}] } },
} },
{ $group: {
_id: { ns: "$ns", plan: "$planSummary", fields: "$filter.k" },
n: { $sum: 1 }, totalMs: { $sum: "$millis" },
avgWaste: { $avg: "$waste" },
} },
{ $sort: { totalMs: -1 } },
{ $limit: 10 },
]);
// Turn it off when you are done. It does not turn itself off, and it
// is per-database, so a fleet-wide audit means visiting every db.
db.setProfilingLevel(0);