Oracle problems
resmgr:cpu quantum: Resource Manager Throttling, and the Fix
3 November 2026
resmgr:cpu quantum is a session that is ready to run and is not allowed to: Oracle Database Resource Manager has given the CPU to other consumer groups, and this one waits for its next slice. Oracle's reference describes the counters in V$RSRC_CONSUMER_GROUP as waits "for CPU on the resmgr: cpu quantum wait event because of resource management", and the session state as "WAITING FOR CPU - Session is ready to run. It is waiting for a CPU quantum to run." It is the signature of a resource plan doing its job: a maintenance window at ten in the evening, instance caging on a shared host, a CDB plan with a share per PDB, an Exadata or cloud limit, or the 16-thread limit of Standard Edition 2. The fix is in the plan, the group or the CPU count, and it starts with knowing which of them switched the wait on.
What the wait means
Resource Manager schedules CPU between consumer groups when a plan is active. The reference says of RESOURCE_MANAGER_PLAN: "If you do not specify this parameter, the resource manager is off by default." Once a plan is on, the Administrator's Guide adds, "the Database Resource Manager does not begin to limit resource allocations according to resource plans until 100% of CPU is being used", with two exceptions that limit even an idle host: a UTILIZATION_LIMIT, which imposes "an absolute upper limit on CPU utilization for a resource consumer group", and instance caging, which the reference defines under CPU_COUNT: "When Resource Manager is managing CPU (RESOURCE_MANAGER_PLAN is set), then the database's CPU utilization is limited to CPU_COUNT CPU threads. This feature is called Instance Caging. If Resource Manager is enabled at the CDB level, then the PDB's CPU utilization is limited to the PDB's CPU_COUNT." A session that has used its quantum yields, and the counter YIELDS records "the number of times that sessions in the consumer group had to yield CPU to other sessions because of quantum expiration". The wait sits in the Scheduler class, and the CPU time it replaces was going to be spent anyway: the wait does not add work, it moves it.
Which plan is on, and why
SELECT name, is_top_plan, cpu_managed, instance_caging
FROM v$rsrc_plan;
SELECT name, value
FROM v$parameter
WHERE name IN ('resource_manager_plan', 'cpu_count');
SELECT window_name, resource_plan, active, next_start_date, duration
FROM dba_scheduler_windows
ORDER BY next_start_date;
The first query names the plan that is active now, which is not always the one in the parameter: a Scheduler window carries its own plan and switches it in when the window opens. The Administrator's Guide: "By default, all predefined maintenance windows use the resource plan DEFAULT_MAINTENANCE_PLAN. Automated maintenance tasks run under its subplan ORA$AUTOTASK." The weekday windows start "at 10 p.m." and end "at 2 a.m.", and the weekend ones start "at 6 a.m." and are "20 hours long", which is why so many databases show this wait from ten at night and all weekend. The plan gives SYS_GROUP 75%, OTHER_GROUPS 20% and ORA$AUTOTASK 5% at level 1, and the unused share flows down, so the user sessions in OTHER_GROUPS only wait when the host is full; what the window changes is that the queue is now visible as a wait instead of a run queue in the operating system.
Who waits, and in which group
SELECT s.resource_consumer_group AS consumer_group,
s.username, s.sql_id, COUNT(*) AS sessions,
SUM(s.seconds_in_wait) AS seconds
FROM v$session s
WHERE s.event = 'resmgr:cpu quantum'
GROUP BY s.resource_consumer_group, s.username, s.sql_id
ORDER BY sessions DESC;
SELECT name, active_sessions, execution_waiters, cpu_waits,
ROUND(cpu_wait_time / 1000) AS cpu_wait_s,
ROUND(consumed_cpu_time / 1000) AS cpu_s, yields
FROM v$rsrc_consumer_group
ORDER BY cpu_wait_time DESC;
The group view counts since the plan was activated. The reference defines EXECUTION_WAITERS as the "Number of currently active sessions waiting for an execution time slice in which they will be able to use CPU", and CPU_WAIT_TIME as the time sessions "waited for CPU on the resmgr: cpu quantum wait event because of resource management", excluding latch, enqueue and I/O waits, so the ratio of cpu_wait_s to cpu_s is the share of each group's CPU demand that the plan refused. The same by the minute, which answers whether the wait is new or has been there every night:
SELECT consumer_group_name,
ROUND(cpu_consumed_time / 1000) AS cpu_s,
ROUND(cpu_wait_time / 1000) AS wait_s,
avg_running_sessions, avg_waiting_sessions,
cpu_utilization_limit
FROM v$rsrcmgrmetric
ORDER BY cpu_wait_time DESC;
The reference describes CPU_UTILIZATION_LIMIT as the "Maximum percentage of CPU that the consumer group can use at any time, with respect to the total number of CPUs in the system", derived from CPU_COUNT when instance caging is on. A group with a limit of 25 on a 32-thread host waits with 24 threads idle, by design. V$RSRCMGRMETRIC_HISTORY keeps the same rows for the last hour, minute by minute.
The directives behind it
SELECT group_or_subplan, mgmt_p1, mgmt_p2, utilization_limit,
parallel_degree_limit_p1, switch_group, switch_time
FROM dba_rsrc_plan_directives
WHERE plan = (SELECT name FROM v$rsrc_plan
WHERE is_top_plan = 'TRUE')
ORDER BY mgmt_p1 DESC NULLS LAST;
SELECT plan, pluggable_database, shares, utilization_limit,
parallel_server_limit
FROM dba_cdb_rsrc_plan_directives
ORDER BY plan, shares DESC;
MGMT_P1 is the group's share of the CPU when the host is full, UTILIZATION_LIMIT its cap even when the host is idle, and SWITCH_GROUP with SWITCH_TIME is the rule that moves a long-running session into a slower group after a number of seconds, which is how a report that ran fine for a minute starts waiting in the second. In a container database the second query is the plan that divides the host between the pluggable databases, and the reference notes that a PDB plan with CPU directives but no CDB plan makes Resource Manager "automatically enable the DEFAULT_CDB_PLAN plan".
The fix, in order
- Decide which of the three it is. Host at 100% and the plan active: this is a CPU problem wearing a Scheduler wait, and the plan is protecting the groups you told it to; go to CPU at 100% and the statement that takes the database. Host with idle CPU and a group waiting: a
UTILIZATION_LIMIT, a cage or a CDB share is capping the group, by design or by accident. A wait that starts at ten in the evening or on Saturday morning: the maintenance window. - A saturated host: re-share before you add CPU. Raise
MGMT_P1for the group that carries the business, map the batch users to a group with a smaller share and aPARALLEL_DEGREE_LIMIT_P1, and give the reports aSWITCH_GROUPafter a minute. The plan then spends the shortage where it hurts least. Turning the plan off removes the wait and keeps the slowness; the queue only moves back into the operating system. - The maintenance window. Narrow the window or move it off the batch hours with
DBMS_SCHEDULER.SET_ATTRIBUTEon the window, or give the window another plan: the Administrator's Guide allows "any resource plan to any maintenance window" as long as the plan includes "the subplan ORA$AUTOTASK". The maintenance tasks themselves take 5%; the wait at ten o'clock is the batch that saturates the host at the moment the plan arrives. - A cap on the wrong group. A session mapped by user name or module into a capped reporting group runs the month-end close at 20% of the host. Fix the mapping with
DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING, or raise theUTILIZATION_LIMITof the group that was capped for a load that no longer exists. - The cage.
CPU_COUNTis dynamic: raise it for the instance that waits and lower it for a neighbour that idles, within the threads of the host. In a CDB, give the pluggable database moreSHARESor a higherUTILIZATION_LIMITin the CDB plan, or raise its ownCPU_COUNT. - Standard Edition 2. The 16-thread limit is enforced the same way, so an SE2 database on a bigger host shows this wait the moment it wants the seventeenth thread. No plan removes it; less CPU per statement does, and so does moving the database to a host it fits.
- Turn the plan off only to prove the point.
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = ''disables it, in the words of the reference. The wait disappears, the run queue appears, and the statement that needed the CPU is still the statement to fix.
See it coming
Radar Engine, the detection layer of Scops, samples every session every 5 seconds and knows the usual waits of every hour, so a Scheduler wait that was absent last week and takes a tenth of the waits tonight is a finding with the consumer group, the plan and the statements that wait, on the first night:
| Detector | Clock | When it fires |
|---|---|---|
| New wait event | Hourly. 10% of the waits of six hours, almost absent in the seven days before. | Watch. |
| Waits on E | Live. A sudden large share of the waits. | Watch. The largest one, if it continues: Warning. |
| CPU saturated | Live. Sessions on CPU or in the queue, against the usable CPUs. | As many as the CPUs: Critical. Rising toward them: Warning, with an ETA. |
| Host CPU busy | Live. 85% or more, less than half of it from the database. | Warning. 95% with a run queue of twice the cores: Critical. |
| SQL taking most of the load | Live. Half or more of the active sessions. | Above the usual of this hour: Warning. More sessions than CPUs: Critical. Always so at this hour: Watch. |
| Unusual Scheduler waits | Hourly, against the same hour on other days. | By size, duration and cause: the usual load, many statements, a backup or a database link. Critical only with a named cause, high for 3 hours. |
The finding names the database, the share of the hour the sessions spent waiting for CPU, the groups and the statements, and whether the host was full at the time, so the first question, shortage or cap, is answered in the mail. The Activity chart draws the Scheduler class next to CPU, by statement, on any edition and without the Diagnostics Pack. Scops AI, asked why the batch is slower since Tuesday, reads the plan, the window and the directives, and answers with the directive that changed.
Questions
What is resmgr:cpu quantum?
A session that is ready to run and waits for a CPU slice because Oracle Database Resource Manager gave the CPU to other consumer groups. Oracle's reference counts these waits in V$RSRC_CONSUMER_GROUP as CPU_WAITS and CPU_WAIT_TIME, and shows the session as WAITING FOR CPU in V$RSRC_SESSION_INFO. It appears only while a resource plan is active.
Does resmgr:cpu quantum mean the CPU is saturated?
Usually. Resource Manager does not limit a group until the host is at 100% of CPU, so on most databases the wait is CPU shortage made visible by the plan. The exceptions are a UTILIZATION_LIMIT on the group, instance caging through CPU_COUNT, a CDB plan share, or the 16-thread limit of Standard Edition 2, which cap a group even on an idle host. V$RSRCMGRMETRIC shows the host's state at the time.
Why does it appear every night at 10 pm?
The predefined maintenance windows open at 10 p.m. on weekdays and 6 a.m. at weekends and switch in DEFAULT_MAINTENANCE_PLAN, which gives SYS_GROUP 75%, OTHER_GROUPS 20% and the maintenance tasks 5%. The plan only takes effect when the host is full, so the wait at ten is the night batch saturating the CPU at the moment a plan arrives to schedule it.
Should I turn Resource Manager off?
Only to prove that the wait is CPU shortage: ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = '' removes the wait and the sessions queue in the operating system instead. Keep the plan and re-share it: a higher MGMT_P1 for the business group, a smaller share and a parallel degree limit for the batch, a switch group for long reports.
How do I see which consumer group is being throttled?
V$RSRC_CONSUMER_GROUP gives CPU_WAITS, CPU_WAIT_TIME and EXECUTION_WAITERS per group since the plan was activated; V$RSRCMGRMETRIC_HISTORY gives the same per minute for the last hour; V$SESSION shows each waiting session's RESOURCE_CONSUMER_GROUP; and DBA_RSRC_PLAN_DIRECTIVES shows the share, the limit and the switch rule that put it there.
Related problems
- CPU at 100%
- One SQL taking the whole database
- ORA-12827: parallel server pool full
- Standard Edition 2 limits
- Oracle wait events, by class
- All Oracle problems