Why do my Oracle database connections fail with ORA-17800 even though the processes parameter hasn't been reached?
Oracle PX server processes spawned by parallel queries exhaust the processes limit (ORA-00020), even though application connections are well below 4000. The resmgr:pq queued wait event shows sessions queued for parallel resources. Resolve by lowering PARALLEL_MAX_SERVERS, reducing PARALLEL_SERVERS_TARGET, adjusting Resource Manager plan directives, or reducing parallel query DOP.
Issue
I'm using Amazon RDS for Oracle. My application receives "ORA-17800: Got minus one from a read call" errors when trying to connect to my database. The processes parameter is set to 4000, and the alert log shows ORA-00020: maximum number of processes (4000) exceeded. However, the number of application database connections is well below 4000. In Performance Insights, I see the resmgr:pq queued wait event on Top SQL.
Description
Oracle Database uses parallel execution to accelerate data-intensive operations such as large table scans, hash joins, and aggregation queries. When a SQL statement is eligible for parallel execution, Oracle spawns multiple parallel execution (PX) server processes that work concurrently on portions of the data. The query coordinator process orchestrates the PX servers and assembles the final result. The degree of parallelism (DOP) determines how many PX server processes a single statement uses. For example, a statement running at DOP 16 requires 16 PX server processes (or 32 if the execution plan includes both a producer and consumer set of PX servers). Each PX server process counts as a separate OS process — they all consume from the same processes parameter pool.
Each PX server process counts as a separate operating system process on the database instance. This means parallel statements consume processes from the same pool governed by the processes initialization parameter. A single user session running a DOP 16 query can consume 16–32 additional process slots beyond its own session process. When multiple users run parallel queries concurrently, the total PX server demand can grow rapidly.
To prevent parallel queries from monopolizing all available resources and starving serial workloads, Oracle introduced parallel statement queuing controlled by the PARALLEL_SERVERS_TARGET initialization parameter. This parameter defines the threshold at which new parallel statements are queued rather than immediately executed. It is deliberately set lower than PARALLEL_MAX_SERVERS (the hard ceiling for parallel server processes) to create a buffer zone. When the total number of active PX servers across all sessions reaches PARALLEL_SERVERS_TARGET, any new parallel statement that would exceed this threshold is placed into a wait queue. The session remains connected but enters the resmgr:pq queued wait event until enough PX servers become available.
Oracle Database Resource Manager provides fine-grained control over this queuing mechanism through consumer groups and resource plan directives. A resource plan assigns database sessions to consumer groups based on criteria such as the user, application module, or service name. Each consumer group can have its own parallel_server_limit — a percentage cap of the PARALLEL_SERVERS_TARGET pool that the group is allowed to consume. This means a consumer group can hit its individual parallel server limit and start queuing its statements even when the system-wide PARALLEL_SERVERS_TARGET has not yet been reached. The Resource Manager also controls dequeue priority via the shares directive, which determines the probability that a consumer group's queued statements are dequeued next when resources free up.
In this scenario, the combination of high parallel query demand and Resource Manager throttling causes a cascade of events that ultimately results in ORA-17800 connection failures:
- Parallel server processes exhaust the
processeslimit: Multiple concurrent parallel queries spawn PX server processes that, combined with regular user sessions and background processes, push the total OS process count to theprocessesparameter ceiling (4000). The alert log records:ORA-00020: maximum number of processes (4000) exceeded. - Session queue buildup with
resmgr:pq queued: Sessions waiting on the Resource Manager parallel queue still occupy process/session slots. Each queued session has already authenticated and established a session — it holds a process but is waiting rather than executing. - New connections rejected: Once
processesis exhausted, Oracle cannot fork new server processes for incoming connections. The listener cannot hand off the connection to a dedicated server process. - ORA-17800 at the JDBC layer: The JDBC driver receives an unexpected end-of-stream (minus one from a read call) because the server-side cannot complete the connection handshake. This manifests as ORA-17800.
The key insight is that the processes limit (4000) is being reached, but not by application user connections alone. PX server processes spawned by parallel queries consume the majority of the process pool. From the application's perspective, the number of DB connections is well below 4000, yet the database cannot accept new connections because internal PX processes have consumed the remaining slots.
Important: Increasing the processes parameter requires an RDS instance reboot. Both PARALLEL_MAX_SERVERS and PARALLEL_SERVERS_TARGET are dynamic parameters (no reboot required in 19c and 21c). However, simply increasing PARALLEL_SERVERS_TARGET does not help if the root problem is that PX processes are already exhausting processes — it would allow even more PX servers to run concurrently, potentially making the problem worse.
The correct resolution is to limit the number of parallel server processes so they cannot exhaust the processes pool. This is achieved by lowering PARALLEL_MAX_SERVERS, reducing PARALLEL_SERVERS_TARGET, adjusting the Resource Manager parallel_server_limit per consumer group, or reducing the DOP of the offending queries.
This article explains how to diagnose the issue by checking parallel server utilization, reviewing the active Resource Manager plan and its consumer group directives, and resolving the problem by tuning PARALLEL_SERVERS_TARGET, adjusting plan directives, or reducing parallel query demand.
Resolution
Immediate recovery when the database cannot accept new connections
If the database is currently unreachable and you cannot establish a new session to run diagnostic queries, use the following steps to restore connectivity:
Step 1: Reboot the RDS instance (if immediate recovery is needed)
Reboot the RDS instance or stop some application servers to release DB processes. A reboot terminates all sessions (including queued PX sessions) and restarts the instance with a clean process pool. Use this only when immediate recovery is critical and other options are not feasible.
Step 2: Lower parallel_max_servers to cap PX server spawning
If you can establish at least one connection, immediately lower parallel_max_servers to prevent further PX server process spawning.
On RDS Oracle, modify parallel_max_servers via the parameter group:
- Open the Amazon RDS console.
- Choose Parameter groups, and then choose your custom parameter group.
- Set
parallel_max_serversto0. - Choose Apply immediately.
Setting it to 0 prevents any new parallel server processes from being spawned. This is a dynamic parameter — it takes effect immediately without a reboot. Existing PX server processes continue running until they complete, but no new ones are created.
Once the situation stabilizes and process slots free up, you can set it to an appropriate value (e.g., 200–500) rather than leaving it at 0.
Step 3: Disable the Resource Manager plan (to release queued sessions)
If you can establish at least one connection (for example, through a retry from the application or a brief window when a queued session completes), disable the Resource Manager plan to stop parallel statement queuing.
Set resource_manager_plan to empty via the parameter group:
- Open the Amazon RDS console.
- Choose Parameter groups, and then choose your custom parameter group.
- Set
resource_manager_planto an empty string (blank). - Choose Apply immediately.
This is a dynamic parameter — it takes effect immediately without a reboot (see Set up Database Resource Manager in Amazon RDS for Oracle). When the Resource Manager is disabled, sessions currently waiting on resmgr:pq queued are released from the queue because the queuing mechanism itself is removed.
Important: Only perform this step after Step 2 (lowering parallel_max_servers). Since disabling the Resource Manager releases all queued sessions at once, they will attempt to spawn PX servers simultaneously. With parallel_max_servers already lowered in Step 2, the released sessions are bounded and cannot worsen the ORA-00020 condition.
Step 4: Kill queued sessions to free connection slots
If you can connect, terminate sessions stuck on resmgr:pq queued to immediately free connection capacity. On RDS Oracle, use rdsadmin.rdsadmin_util.disconnect (see Killing a session).
First, identify the queued sessions:
SELECT sid, serial#, username, seconds_in_wait FROM V$SESSION WHERE EVENT = 'resmgr:pq queued' AND SECONDS_IN_WAIT > 300;
Then disconnect each session using the sid and serial# from the query above:
BEGIN rdsadmin.rdsadmin_util.disconnect(sid => <sid>, serial => <serial#>); END; /
Repeat for each queued session. This frees process/session slots so new connections can succeed.
After connectivity is restored, proceed with the diagnostic steps below to identify and fix the root cause.
Identify the root cause
The resmgr:pq queued wait event means that parallel query statements are being queued by Oracle Resource Manager. This happens when:
- The number of active parallel execution (PX) server processes reaches
PARALLEL_SERVERS_TARGET. - Each parallel query spawns multiple PX server processes that count toward the total process usage on the instance.
- Sessions waiting in the queue hold connection slots but aren't actively processing, which reduces available capacity for new connections.
- When connection slots are exhausted or the connection handshake times out, the JDBC driver receives ORA-17800 ("Got minus one from a read call").
Note: The processes parameter defines the maximum total OS processes for the instance. However, Resource Manager imposes a lower effective concurrency limit for parallel workloads through PARALLEL_SERVERS_TARGET. This parameter is intentionally set lower than PARALLEL_MAX_SERVERS to ensure each parallel statement gets all the parallel server resources it requires and to prevent overloading the system.
Understand how Oracle Resource Manager controls parallel statement queuing
Oracle Database Resource Manager uses consumer groups and resource plan directives to control parallel statement execution. The following directives affect parallel queuing behavior:
| Directive | Description |
|---|---|
parallel_server_limit | Maximum percentage of the PARALLEL_SERVERS_TARGET pool that a consumer group can use. When this limit is reached, additional parallel statements from that group are queued. |
parallel_queue_timeout | Maximum time (in seconds) a statement can remain queued. After timeout, the statement is terminated with ORA-7454 or allowed to run (depending on PQ_TIMEOUT_ACTION). |
parallel_degree_limit_p1 | Maximum degree of parallelism (DOP) for any operation in that consumer group. |
shares | Controls the dequeue priority across consumer groups. Higher shares = higher probability of being dequeued first. |
How it works:
- When
PARALLEL_DEGREE_POLICYis set toAUTO, Oracle queues parallel statements if running them would increase active parallel servers abovePARALLEL_SERVERS_TARGET. - Each consumer group has its own parallel statement queue. When
parallel_server_limitfor a consumer group is reached, statements from that group are queued even if the system-widePARALLEL_SERVERS_TARGEThasn't been reached. - When parallel servers become available, the
sharesdirective determines which consumer group's queued statement is dequeued next. - Serial (non-parallel) statements execute immediately regardless of parallel statement queuing.
Check current parallel server usage
Run the following query to compare active parallel servers against the target threshold:
SELECT (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'parallel_servers_target') AS pq_target, (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'parallel_max_servers') AS pq_max, (SELECT COUNT(*) FROM V$PX_SESSION) AS active_px_sessions;
Check sessions waiting on resmgr:pq queued
Run the following query to identify queued sessions:
SELECT sid, serial#, username, status, event, seconds_in_wait FROM V$SESSION WHERE EVENT = 'resmgr:pq queued' ORDER BY seconds_in_wait DESC;
Check the active Resource Manager plan and directives
Identify the active plan and review how parallel resources are allocated per consumer group:
-- Active Resource Manager plan SELECT VALUE FROM V$PARAMETER WHERE NAME = 'resource_manager_plan'; -- Plan directives with parallel controls SELECT plan, group_or_subplan, shares, parallel_server_limit, parallel_degree_limit_p1, parallel_queue_timeout FROM DBA_RSRC_PLAN_DIRECTIVES WHERE plan = (SELECT REPLACE(VALUE, 'FORCE:', '') FROM V$PARAMETER WHERE NAME = 'resource_manager_plan');
Check which consumer group each session belongs to:
SELECT s.sid, s.serial#, s.username, s.event, rm.consumer_group_name, rm.state FROM V$SESSION s JOIN V$RSRC_SESSION_INFO rm ON s.sid = rm.sid WHERE s.event = 'resmgr:pq queued';
Option 1: Lower PARALLEL_MAX_SERVERS and PARALLEL_SERVERS_TARGET
Since PX server processes are exhausting the processes limit, the primary fix is to cap the number of parallel servers so they cannot consume all available process slots. Lower PARALLEL_MAX_SERVERS to reserve process capacity for user connections and background processes.
Recommended formula:
PARALLEL_MAX_SERVERS ≤ processes - (expected_user_sessions + background_processes + safety_margin)
For example, if you expect 2000 user sessions, ~100 background processes, and want a 200-process safety margin:
PARALLEL_MAX_SERVERS = 4000 - 2000 - 100 - 200 = 1700
- Open the Amazon RDS console.
- Choose Parameter groups, and then choose your custom parameter group.
- Lower
parallel_max_servers(e.g., to 1700) andparallel_servers_target(e.g., to 1200 — lower thanparallel_max_serversto enable queuing as a buffer). - AApply the changes. Note: Both
parallel_max_serversandparallel_servers_targetare dynamic parameters (no reboot needed in Oracle 19c and 21c).
Important: Do NOT increase PARALLEL_SERVERS_TARGET in this scenario — that would allow more PX servers to run concurrently and worsen the process exhaustion problem.
Option 2: Adjust the Resource Manager plan directives
If a specific consumer group's parallel_server_limit is too restrictive, increase it to allow that group more parallel server capacity:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(); DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE( plan => 'YOUR_PLAN_NAME', group_or_subplan => 'YOUR_CONSUMER_GROUP', new_parallel_server_limit => 80, -- Increase from current value (e.g., 50 to 80%) new_parallel_degree_limit_p1 => 8 -- Optionally adjust DOP limit ); DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA(); END; /
Key considerations:
parallel_server_limitis a percentage of the totalPARALLEL_SERVERS_TARGET. For example, ifPARALLEL_SERVERS_TARGET = 64andparallel_server_limit = 50, the consumer group can use at most 32 parallel servers before its statements are queued.- If a low-priority consumer group has a small
parallel_server_limit, but a high-priority group has a high limit, the high-priority group can exhaust the pool, causing low-priority sessions to queue indefinitely. - You can also set
parallel_queue_timeoutto prevent statements from waiting too long in the queue. When the timeout expires, the statement is either terminated (ORA-7454) or allowed to run based on thePQ_TIMEOUT_ACTIONdirective.
Option 3: Reduce the degree of parallelism (DOP)
If queries are using an excessively high DOP, reduce it at the session or statement level:
ALTER SESSION SET PARALLEL_DEGREE_LIMIT = 4;
Or disable parallel query for specific sessions:
ALTER SESSION DISABLE PARALLEL QUERY;
Option 4: Identify and tune high-parallelism queries
Find the queries that consume the most parallel server resources:
SELECT sql_id, sql_text, px_servers_executions FROM V$SQL WHERE px_servers_executions > 0 ORDER BY px_servers_executions DESC FETCH FIRST 20 ROWS ONLY;
Add the /*+ NO_PARALLEL */ hint to queries that don't require parallel execution, or reduce the parallel degree attribute on the tables:
ALTER TABLE schema_name.table_name PARALLEL 2;
You can also use the /*+ NO_STATEMENT_QUEUING */ hint to let specific critical statements bypass the parallel statement queue:
SELECT /*+ NO_STATEMENT_QUEUING */ column_list FROM large_table WHERE conditions;
Note: Statements that bypass the queue can cause the system to exceed PARALLEL_SERVERS_TARGET. Only use this hint for critical operations.
Related information
- About Parallel Statement Queuing (Oracle Database 21c VLDB Guide)
- PARALLEL_SERVERS_TARGET (Oracle Database Reference)
- About Limiting Parallel Server Resources for a Consumer Group
- DBMS_RESOURCE_MANAGER Package (Oracle Database PL/SQL Packages Reference)
- Working with parameter groups (Amazon RDS User Guide)
Relevant content
- Accepted Answer
asked 2 years ago
asked 2 years ago
