High CPU utilization on an ApsaraDB for MongoDB instance — sometimes approaching 100% — slows down read/write operations and disrupts business operations. Work through the following diagnostic steps to identify and resolve the root cause.
Check running operations
Connect to the instance using the mongo shell. Connection procedures vary by instance architecture:
Run db.currentOp() to list all operations currently running on the instance:
db.currentOp()
Sample output:
{
"desc" : "conn632530",
"threadId" : "140298196924160",
"connectionId" : 632530,
"client" : "11.192.159.236:57052",
"active" : true,
"opid" : 1008837885,
"secs_running" : 0,
"microsecs_running" : NumberLong(70),
"op" : "update",
"ns" : "mygame.players",
"query" : {
"uid" : NumberLong(31577677)
},
"numYields" : 0,
"locks" : {
"Global" : "w",
"Database" : "w",
"Collection" : "w"
},
....
}
Focus on the following fields to identify problematic operations:
| Field | Description | When to act |
|---|---|---|
client |
The client that sent the request | Use this to trace the request back to its source |
opid |
Unique operation ID | Run db.killOp(opid) to stop the operation if needed |
secs_running |
How long the operation has been running, in seconds | Investigate operations with unexpectedly large values |
microsecs_running |
How long the operation has been running, in microseconds | Investigate operations with unexpectedly large values |
ns |
The namespace (collection) being scanned | Cross-reference with slow query logs to find hot collections |
op |
Operation type: query, insert, update, or delete |
— |
locks |
Lock information for the operation | See FAQ: Concurrency |
For more information about db.currentOp(), see db.currentOp().
A common cause of CPU spikes is an O&M operation — such as a full collection scan — running alongside your regular workload. If db.currentOp() shows an operation with a large secs_running value that you did not expect, stop it:
db.killOp(<opid>)
Replace <opid> with the value of the opid field from the db.currentOp() output. For more information, see db.killOp().
Analyze slow query logs
If CPU utilization increases immediately after your application starts and stays high, but db.currentOp() shows no obviously problematic operations, the cause is likely a pattern of slow queries accumulating over time.
View slow query logs in the ApsaraDB for MongoDB console. For more information, see View slow query logs.
A sample slow query log entry looks like this:
{
"atype": "slowOp",
"param": {
"op": "query",
"ns": "abbott_analysis.uaidScanInfo",
"query": {
"find": "uaidScanInfo",
"filter": {
"dateType": 2,
"companyCode": "GMP"
},
"ntoreturn": -1,
"sort": {
"scanDateTime": -1
}
},
"keysExamined": 0,
"docsExamined": 2181021,
"hasSortStage": true,
"cursorExhausted": true,
"numYield": 17059,
"locks": { ... },
"nreturned": 0,
"responseLength": 20,
"millis": 4878,
"planSummary": "COLLSCAN"
},
"result": "OK"
}
Look for the following patterns in slow query logs:
Full collection scans (COLLSCAN, docsExamined)
planSummary: COLLSCAN means the query scanned the entire collection without using an index. The docsExamined field shows how many documents were scanned — the higher this number, the more CPU the query consumed.
Create an index on the queried fields to fix this:
db.<collection>.createIndex({ <field>: 1 })
Inefficient indexes (IXSCAN, keysExamined)
When a query uses an index, planSummary shows IXSCAN. The keysExamined field shows how many index keys were scanned. The greater the value, the more CPU resources the request occupies.
Index selectivity example
Consider a collection where the x field has only two possible values (1 or 2), while y spans a much wider range (1 to 100000). For the query { x: 1, y: 2 }:
{ x: 1, y: 1 }
{ x: 1, y: 2 }
...
{ x: 1, y: 100000 }
{ x: 2, y: 1 }
...
| Index | Selectivity | Reason |
|---|---|---|
db.createIndex({ x: 1 }) |
Poor | Half the collection shares the same x value |
db.createIndex({ x: 1, y: 1 }) |
Poor | Leading field x is still low-selectivity |
db.createIndex({ y: 1 }) |
Good | y has a wide range — few documents share the same value |
db.createIndex({ y: 1, x: 1 }) |
Good | Leading field y eliminates most documents immediately |
Index the high-selectivity field first. For more information, see Design Principles of MongoDB Indexes and Compound indexes.
Excessive indexes affect the write and update performance. If your application involves a large number of write operations and you use indexes, the application performance may be affected. Audit and remove unused indexes if write performance is also degraded.
In-memory sorting (SORT, hasSortStage)
hasSortStage: true means the instance sorted query results in memory because no index could satisfy the sort order. In-memory sorts on large result sets consume significant CPU.
If slow query logs contain the keyword SORT, create an index on the fields used in the sort clause:
db.<collection>.createIndex({ <sort-field>: 1 })
Other high-CPU operations
Index creation and aggregation pipelines (which combine traversal, filtering, updates, and sorting) can also drive high CPU. Apply the same diagnostic approach: check docsExamined, keysExamined, hasSortStage, and planSummary in the slow query logs.
Assess service capacity
If all queries are using appropriate indexes and CPU utilization remains high, the instance may have reached its capacity limit.
-
Review monitoring data to understand your resource usage pattern. For more information, see View monitoring data and Node monitoring (previously basic monitoring).
-
Check whether the current instance spec meets your workload requirements. If necessary, upgrade the instance. For more information, see Change the configurations of an instance or Change the configurations of a replica set instance.
Quick reference
| Command | Purpose |
|---|---|
db.currentOp() |
List all operations currently running on the instance |
db.killOp(<opid>) |
Stop a specific operation by its operation ID |
| View slow query logs in the console | Identify slow queries without connecting to the instance |