Skip to content
Rate this page
☆ ☆ ☆ ☆ ☆
Thanks for your feedback
Thank you! The feedback has been submitted.

For help, click the link below to get free database assistance or contact our experts for personalized support.

Percona Server for MySQL thread pool

Version notice

This page documents the built-in Percona Server for MySQL thread pool.

Percona Server for MySQL 9.7.2-2 and later also includes the MySQL thread_pool plugin. Only one implementation can be active at a timetime; configuring the built-in thread pool prevents the MySQL thread pool plugin from loading. See the MySQL thread pool plugin for details.

Percona Server for MySQL provides thread pooling as a built-in feature controlled by the thread_handling system variable. Thread pooling replaces the default one-thread-per-connection model with a fixed set of worker threads, organized into thread groups, shared across client connections.

Set the thread pool variable thread_handling to pool-of-threads by adding the following line to my.cnf:

thread_handling=pool-of-threads

Priority connection scheduling

The thread pool limits concurrently running queries using high-priority and normal-priority queues. A connection enters the high-priority queue and decrements its ticket count if it meets both conditions:

  • Has an active open transaction

  • Holds a non-zero number of high-priority tickets (thread_pool_high_prio_tickets)

Otherwise, the connection enters the normal-priority queue. Worker threads check the high-priority queue first and process normal-priority requests only when the high-priority queue is empty. Setting high-priority tickets to 0 routes all connections to the normal-priority queue.

Normal-priority queue throttling

Under high concurrency, thread groups can become oversubscribed when active worker threads reach thread_pool_oversubscribe while waiting on locks. Because oversubscription tracking excludes inactive waiting threads, total threads can grow until reaching thread_pool_max_threads, causing performance degradation or deadlocks.

To prevent oversubscription deadlocks:

  • The thread pool throttles the normal-priority queue when total worker threads (active and waiting) reach the thread_pool_oversubscribe limit.

  • New transactions pause while throttled.

  • Queued events from existing transactions continue processing, releasing locks so the pool can drain.

Handling long network waits

Workloads with large result sets, BLOBs, or slow network I/O report socket waits to the thread pool. The pool responds by waking an idle worker thread or spawning a new thread to keep pending queries moving.

System variables

thread_handling

Option Description
Command-line Yes
Config file Yes
Scope Global
Dynamic No
Data type String
Default one-thread-per-connection

Defines how the server dispatches statements from client connections to execution threads.

Option Description
one-thread-per-connection Allocates one dedicated thread per client connection for its lifetime.
pool-of-threads Shares execution requests across a managed thread pool.
no-threads Executes all requests inside a single thread (debugging mode only).

thread_pool_high_prio_mode

Controls fine-grained high-priority queue scheduling.

Value Description
transactions Default. Statement priority depends on active transactions and available tickets.
statements Directs all individual statements to the high-priority queue, overriding transaction state and ticket limits.
none Disables high-priority queuing for the connection, routing all statements to the normal-priority queue.

thread_pool_high_prio_tickets

Option Description
Command-line: Yes
Config file: Yes
Scope: Global, Session
Dynamic: Yes
Data type: Numeric
Default value: 4294967295

Sets the number of high-priority tickets assigned to each new connection. Setting this value to 0 disables the high-priority queue.

thread_pool_idle_timeout

Option Description
Command-line: Yes
Config file: Yes
Scope: Global
Dynamic: Yes
Data type: Numeric
Default value: 60 (seconds)

Specifies the number of seconds an idle worker thread stays in the pool before exiting. Lower values reclaim memory faster during bursty workloads; higher values reduce thread-creation overhead when traffic resumes.

thread_pool_max_threads

Option Description
Command-line: Yes
Config file: Yes
Scope: Global
Dynamic: Yes
Data type: Numeric
Default value: 100000

Caps the maximum total number of threads allowed in the pool. When this limit is reached, the server refuses to spawn new worker threads.

thread_pool_oversubscribe

Option Description
Command-line: Yes
Config file: Yes
Scope: Global
Dynamic: Yes
Data type: Numeric
Default value: 3

Sets the maximum active worker threads permitted simultaneously within a single thread group. When threads stall on I/O or locks, the group creates worker threads up to this limit to keep queued requests moving.

thread_pool_size

Option Description
Command-line: Yes
Config file: Yes
Scope: Global
Dynamic: Yes
Data type: Numeric
Default value: Number of processors

Sets the number of thread groups in the thread pool. Connections are assigned to thread groups in round-robin order. Start with a value equal to the available CPU cores and tune based on queue metrics.

thread_pool_stall_limit

Option Description
Command-line: Yes
Config file: Yes
Scope: Global
Dynamic: No
Data type: Numeric
Default value: 500 (ms)

Defines the elapsed time in milliseconds before a running statement is marked stalled, triggering the pool to wake or spawn another thread to prevent long queries from blocking the group.

Status variables

Threadpool_average_hp_queue_wait_us

Option Description
Scope: Global
Data type: String

Reports aggregated wait-time statistics in microseconds for requests in the high-priority queue:

The value is a formatted string, for example:

avg: 0.000, min: 0.000, max: 0.000, dev: 0.000, cnt: 0
  • cnt: Number of samples collected since server startup.

  • avg, min, max, dev: Computed wait-time metrics across all dequeued requests.

Threadpool_average_queue_wait_us

Option Description
Scope: Global
Data type: String

Reports aggregated wait-time statistics in microseconds for requests in the normal-priority queue:

avg: 590.000, min: 470.000, max: 736.000, dev: 110.266, cnt: 5

Threadpool_idle_threads

Option Description
Scope: Global
Data type: Numeric

Tracks worker threads that are currently idle. Calculate active threads using: Threadpool_threads - Threadpool_idle_threads.

Threadpool_requests_starved_in_queue

Option Description
Scope: Global
Data type: Numeric

Counts normal-priority requests starved because worker threads were occupied processing high-priority traffic.

Threadpool_requests_waiting_in_hp_queue

Option Description
Scope: Global
Data type: Numeric

Tracks requests currently waiting in the high-priority queue. Sustained non-zero values indicate high-priority traffic is arriving faster than worker threads can drain it.

Threadpool_requests_waiting_in_queue

Option Description
Scope: Global
Data type: Numeric

Tracks requests currently waiting in the normal-priority queue. High values indicate capacity bottlenecks or high-priority queue saturation.

Threadpool_threads

Option Description
Scope: Global
Data type: Numeric

Shows total worker threads in the pool, including both active and idle threads.