ORA-04036 fires when instance-wide PGA consumption crosses PGA_AGGREGATE_LIMIT, the hard cap introduced in 12c. This is not a tuning warning. The database is defending itself by killing or interrupting work.
PGA_AGGREGATE_TARGET is a soft target Oracle tries to honor. PGA_AGGREGATE_LIMIT is an enforced ceiling. Sessions can exceed the target legitimately. Crossing the limit triggers Oracle to abort the call of, and then terminate, the sessions holding the most untunable PGA. SYS and most background processes are not eligible for termination, which produces a distinct and more dangerous failure mode described below.
The Linux OOM killer may also be involved if SGA (hugepages) + PGA + OS needs exceed physical RAM, but ORA-04036 itself is Oracle’s internal mechanism. Both can fire in the same incident.
What this means
When aggregate PGA crosses PGA_AGGREGATE_LIMIT:
- The CKPT background process checks PGA usage every three seconds.
- Oracle first aborts the call of the session holding the most untunable PGA. Untunable memory is memory Oracle cannot release on demand: sort areas in use, PL/SQL collections, certain call memory.
- If the instance is still over the limit after the abort, Oracle terminates the session.
- SYS sessions and most background processes (DBWn, LGWR, SMON, PMON, MMON, and so on) are not terminated. Their PGA usage is written to trace files instead.
The last point is the dangerous variant. When a background process is the top PGA consumer, Oracle cannot enforce the limit against it. The alert log will say something like:
PGA_AGGREGATE_LIMIT has been exceeded but some processes using the most PGA memory are not eligible to receive ORA-4036 interrupts.
In that case ORA-04036 still fires for user sessions, but the root cause keeps growing. Killing user sessions will not self-correct the instance.
In 19c and later, the incident dump produced when ORA-04036 fires includes a “Top 10 processes” section showing private memory usage per Oracle process. Read that dump before guessing.
flowchart TD
A[Aggregate PGA rises] --> B{Crosses PGA_AGGREGATE_LIMIT?}
B -->|No| Z[Normal operation]
B -->|Yes| C[CKPT detects every 3s]
C --> D[Abort call of highest-PGA session]
D --> E{Still over limit?}
E -->|No| Z
E -->|Yes| F[Terminate the session]
F --> G{Top consumer user or background?}
G -->|User| Z
G -->|Background| H[Not eligible for ORA-4036
PGA written to trace]
H --> I[Persistent overage
user sessions keep dying]Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Unbounded PL/SQL collection or LOB | One session’s PGA_MAX_MEM grows monotonically over its lifetime | V$PROCESS.PGA_MAX_MEM per session |
| Massive serial sort or hash join | Single SQL doing direct path read temp / direct path write temp, one big consumer | V$SQL_WORKAREA_ACTIVE, top PGA consumers |
| Background PGA leak (MMON, space slaves) | “Not eligible to receive ORA-4036 interrupts” in alert log | Incident trace “Top 10 processes” section |
| Too many sessions with moderate PGA | total PGA allocated tracks session count linearly | V$PGASTAT vs V$SESSION count |
PGA_AGGREGATE_LIMIT set too low for workload | ORA-04036 fires at start of batch or right after restart | SHOW PARAMETER pga_aggregate_limit |
| OS memory pressure as a confounder | dmesg OOM kills alongside ORA-04036; ORA-27300, ORA-27301 | dmesg, /proc/meminfo |
Quick checks
All read-only. Run as DBA.
-- Show PGA configuration
SHOW PARAMETER pga_aggregate_target;
SHOW PARAMETER pga_aggregate_limit;
SHOW PARAMETER memory_target; -- AMM check
SHOW PARAMETER sga_target;
-- Aggregate PGA state from V$PGASTAT
SELECT NAME, VALUE
FROM V$PGASTAT
WHERE NAME IN (
'aggregate PGA target parameter',
'total PGA inuse',
'total PGA allocated',
'maximum PGA allocated',
'over allocation count',
'total freeable PGA memory',
'cache hit percentage'
);
-- Top PGA consumers, with OS PID and SQL_ID
SELECT p.SPID,
p.PGA_USED_MEM/1048576 AS pga_used_mb,
p.PGA_ALLOC_MEM/1048576 AS pga_alloc_mb,
p.PGA_MAX_MEM/1048576 AS pga_max_mb,
s.SID, s.USERNAME, s.SQL_ID, s.PROGRAM
FROM V$PROCESS p
LEFT JOIN V$SESSION s ON p.ADDR = s.PADDR
ORDER BY p.PGA_ALLOC_MEM DESC
FETCH FIRST 20 ROWS ONLY;
-- Per-category breakdown for top offenders (12c+)
SELECT PID, SERIAL#, NAME, CATEGORY,
ALLOCATED/1048576 AS alloc_mb,
USED/1048576 AS used_mb,
MAX_ALLOCATED/1048576 AS max_mb
FROM V$PROCESS_MEMORY
ORDER BY ALLOCATED DESC
FETCH FIRST 20 ROWS ONLY;
-- Sessions currently spilling to temp (PGA undersized indicator)
SELECT EVENT, TOTAL_WAITS, TIME_WAITED_MICRO
FROM V$SYSTEM_EVENT
WHERE EVENT IN ('direct path read temp', 'direct path write temp');
# Confirm ORA-04036 in the alert log and look for ineligible-process text
adrci exec="show alert -tail 500" | grep -E "ORA-04036|ORA-4036|not eligible"
# Rule out OS OOM killer as a confounder
dmesg -T | grep -iE "out of memory|oom|killed process"
How to diagnose it
- Confirm ORA-04036 in the alert log. Note whether the “not eligible to receive ORA-4036 interrupts” message appears alongside it. That changes the playbook.
- Snapshot
V$PGASTAT. Comparetotal PGA allocatedagainstPGA_AGGREGATE_LIMITandPGA_AGGREGATE_TARGET. The ratio tells you whether you are nudging the limit or blowing through it. - Identify the top PGA consumer in
V$PROCESSand break it down withV$PROCESS_MEMORY. The CATEGORY column separatesSQL,PL/SQL,OLAP,Java, andOther. A session whosePL/SQLcategory is huge is leaking collections. A session whoseSQLcategory is huge is doing a large workarea operation. - If the top consumer is a background process (MMON, a space background slave, DBWn), open the incident dump in the ADR. In 19c+ the dump contains a “Top 10 processes” section. Confirm which background process is the offender.
- Rule out OS OOM killer. If
dmesgshows Oracle PIDs being killed, the real ceiling is physical RAM, notPGA_AGGREGATE_LIMIT. The fix is to free RAM (hugepages for SGA, reduce PGA footprint, move other workloads off the host), not to raise the limit. - Correlate timing. Did ORA-04036 start after a stats gather, a batch window, a datapatch run, an upgrade, or a connection pool resize? PGA leaks often surface after a code change that introduced an unbounded loop.
- Check
direct path read temp/direct path write temptrends. If they rise in step with PGA, the workload is genuinely outgrowing PGA. If PGA rises while temp spill stays flat, suspect a leak rather than legitimate demand.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
total PGA allocated / PGA_AGGREGATE_LIMIT | Headroom before the hard cap | Sustained above 80% |
over allocation count in V$PGASTAT | Persistent over-target pressure | Non-zero and growing |
cache hit percentage in V$PGASTAT | Ratio of work done in PGA vs spilled to temp | Below 80% sustained |
direct path read temp / direct path write temp | PGA is undersized for the work | Rising trend |
Per-process PGA_MAX_MEM | Detects slow leaks in long-lived sessions | Single PID growing monotonically |
dmesg OOM kills | OS-level memory ceiling | Any Oracle-related entries |
| Alert log: “not eligible” text | Background process is the top consumer | Any occurrence |
Fixes
Immediate: stop the bleeding
If a single user session is the top consumer and you can identify the offending SQL_ID or program, kill the session. Rolling back an uncommitted transaction in that session releases its PGA.
-- Disruptive: kills the target session immediately
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
Use this when the cause is a runaway user session, not a background process.
Short-term: raise the limit
PGA_AGGREGATE_LIMIT is dynamic and can be raised without a restart:
-- Dynamically raise the limit, both spfile and memory
ALTER SYSTEM SET pga_aggregate_limit = <new_value> SCOPE=BOTH;
Do this only if physical RAM has headroom. Raising the limit above what the host can actually hold moves the failure from ORA-04036 to the OS OOM killer, which is worse because the OOM killer does not distinguish background from foreground processes.
To disable the limit entirely as an emergency workaround, for example during a datapatch run known to spike PGA:
-- Emergency only. Removes Oracle's self-protection.
ALTER SYSTEM SET pga_aggregate_limit = 0 SCOPE=BOTH;
Setting the limit to 0 disables it. Use it only for the duration of the operation, then restore a sane value.
Medium-term: reduce demand
- Fix the PL/SQL leak. Look for collections populated in a loop without a
DELETE, session-level LOBs held across calls, or associative arrays used as caches that never age out. - Reduce
PGA_AGGREGATE_TARGETif it has drifted higher than the workload needs. Oracle sizes per-session workareas off the target; an oversized target allows individual sessions to grab more memory before Oracle starts spilling to temp. - Move analytical workloads to an Active Data Guard standby (licensed) or a separate instance so a single hash join cannot starve OLTP.
Confounder: free OS memory first
If the issue is total RAM, not Oracle’s cap:
- Verify hugepages are configured for the SGA. Without hugepages, page table overhead can consume hundreds of MB per Oracle process on large SGAs. Check
/proc/meminfoforHugePages_Total,HugePages_Free, andHugePages_Rsvd. - Avoid
MEMORY_TARGET(AMM) on Linux. It uses/dev/shminstead of hugepages and makes memory leak diagnosis harder. - Move monitoring agents, backup scripts, or other tenants off the Oracle host.
Background-process leak: targeted workaround
If a background process is the top consumer, raising the limit only delays the next incident. Look for known defects and underscore workarounds relevant to your version. In 19c, space background process slaves have been observed to hold “control file i/o buffer” allocations for extended periods. Reducing the slave count via the underscore parameter limits the blast radius. Engage Oracle Support before changing underscore parameters.
Prevention
- Monitor
V$PGASTATcontinuously. Tracktotal PGA allocated,over allocation count, andcache hit percentage. The leading indicator isover allocation countrising before ORA-04036 ever fires. - Track per-process
PGA_MAX_MEM. A session whose high-water mark keeps climbing across snapshots is leaking. Catch it before it becomes the top consumer. - Size
PGA_AGGREGATE_LIMITwith explicit headroom. Peaktotal PGA allocatedshould stay below 80% of the limit. After an 18c+ upgrade, remember that MGA (Managed Global Area) is accounted under PGA, so reported PGA usage rises. A reasonable rule of thumb is to raise the limit by(max connected processes) * 4 MBafter upgrade. - Confirm hugepages for SGA. This frees the memory Oracle would otherwise burn on page tables.
- Avoid
MEMORY_TARGETon Linux. It conflicts with hugepages and obscures leak diagnosis. - Validate the 19c+ “Top 10 processes” dump works in your environment. When ORA-04036 fires, you want that dump to be there.
- Watch for the “not eligible” alert log text. It means the fix is not “kill user sessions”. It means a background process has a leak and you need Oracle Support.
- For datapatch and other known PGA-spiking operations, temporarily raise or disable
PGA_AGGREGATE_LIMITfor the duration, then restore it.
How Netdata helps
- Per-second PGA utilization from
V$PGASTAT(total PGA inuse, total PGA allocated, over allocation count, cache hit percentage) lets you see the climb toward the limit before ORA-04036 fires, not just after. - Correlate PGA with TPS, active sessions, and wait events. If
direct path read tempwaits climb alongsidetotal PGA allocated, the workload is outgrowing PGA. If PGA climbs while TPS is flat, suspect a leak. - Per-process PGA tracking surfaces a single PID whose
PGA_MAX_MEMgrows monotonically, the signature of a slow PL/SQL or LOB leak. - Linux memory pressure signals on the same timeline (OOM kills from
dmesg, hugepage utilization, slab, free memory) let you distinguish Oracle’s internal cap from the host’s physical RAM ceiling. - Anomaly detection on
over allocation countandcache hit percentageflags the leading indicators of PGA pressure even when absolute values look fine. - Alert log parsing for ORA-04036 and the “not eligible” text routes you straight to the background-process variant when it occurs.
For the full integration, see Oracle Database monitoring with Netdata.
Related guides
- How Oracle Database actually works in production: a mental model for operators
- Oracle archive log destination full: V$ARCHIVE_DEST_STATUS, the ERROR state, and space
- Oracle autoextend hit MAXSIZE: the space gotcha with a half-empty filesystem
- Oracle ‘Thread N cannot allocate new log’: the archive hang that masquerades as up
- Oracle ‘Checkpoint not complete’: redo log sizing, DBWn, and log-switch stalls
- Oracle Fast Recovery Area full: db_recovery_file_dest_size, reclaimable space, and DELETE OBSOLETE
- Oracle ’log file sync’ waits: slow commits, LGWR, and the redo path
- Oracle Database monitoring checklist: the signals every production instance needs
- Oracle Database monitoring maturity model: from survival to expert
- ORA-00257: archiver error, connect internal only until freed
- ORA-01555: snapshot too old, rollback segment too small
- ORA-01653: unable to extend table in tablespace






