> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Admission Control

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

CockroachDB supports an admission control system to maintain cluster performance and availability when some nodes experience high load. When admission control is enabled, CockroachDB sorts request and response operations into work queues by priority, giving preference to higher priority operations. Internal operations critical to node health, like <InternalLink path="cluster-setup-troubleshooting#node-liveness-issues">node liveness heartbeats</InternalLink>, are high priority. The admission control system also prioritizes transactions that hold <InternalLink path="crdb-internal#cluster_locks">locks</InternalLink>, to reduce <InternalLink path="performance-best-practices-overview#transaction-contention">contention</InternalLink> and release locks earlier.

## How admission control works

At a high level, the admission control system works by queueing requests to use the following system resources:

* CPU
* Storage IO (writes to disk)

For CPU, different types of usage are queued differently based on priority to allow important work to make progress even under <InternalLink path="common-issues-to-monitor#cpu-usage">high CPU utilization</InternalLink>.

For storage IO, the goal is to prevent the <InternalLink path="architecture/storage-layer#log-structured-merge-trees">storage layer's log-structured merge tree</InternalLink> (LSM) from experiencing high <InternalLink path="architecture/storage-layer">read amplification</InternalLink>, which slows down reads, while also maintaining the ability to absorb bursts of writes.

Admission control works on a per-<InternalLink path="architecture/overview#node">node</InternalLink> basis, since even though a large CockroachDB cluster may be well-provisioned as a whole, individual nodes are stateful and may experience performance <InternalLink path="understand-hotspots">hotspots</InternalLink>.

For more details about how the admission control system works, see:

* The blog post [Here's how CockroachDB keeps your database from collapsing under load](https://www.cockroachlabs.com/blog/admission-control-in-cockroachdb/).

## Use cases for admission control

A well-provisioned CockroachDB cluster may still encounter performance bottlenecks at the node level, as stateful nodes can develop <InternalLink path="understand-hotspots">hotspots</InternalLink> that last until the cluster rebalances itself. When hotspots occur, they should not cause failures or degraded performance for important work.

This is particularly important for CockroachDB Standard and CockroachDB Basic, where one user tenant cluster experiencing high load should not degrade the performance or availability of a different, isolated tenant cluster running on the same host.

Admission control can help if your cluster has degraded performance due to the following types of node overload scenarios:

* The node has more than 32 runnable goroutines per CPU, visible in the **Runnable goroutines per CPU** graph in the <InternalLink path="ui-overload-dashboard#runnable-goroutines-per-cpu">**Overload** dashboard</InternalLink>.
* The node has a high amount of overload in the Pebble LSM tree, visible in the **IO Overload** graph in the <InternalLink path="ui-overload-dashboard#io-overload">**Overload** dashboard</InternalLink>.
* The node has high CPU usage, visible in the **CPU Utilization** graph in the <InternalLink path="ui-overload-dashboard#cpu-utilization">**Overload** dashboard</InternalLink>.
* The node is experiencing out-of-memory errors, visible in the **Memory Usage** graph in the <InternalLink path="ui-hardware-dashboard#memory-usage">**Hardware** dashboard</InternalLink>. Even though admission control does not explicitly target controlling memory usage, it can reduce memory usage as a side effect of delaying the start of operation execution when the CPU is overloaded.

## Operations subject to admission control

Almost all database operations that use CPU or perform storage IO are controlled by the admission control system. From a user's perspective, specific operations that are affected by admission control include:

* <InternalLink path="selection-queries">General SQL queries</InternalLink> have their CPU usage subject to admission control, as well as storage IO for writes to <InternalLink path="architecture/replication-layer#leases">leaseholder replicas</InternalLink> and [follower replicas](#replication-admission-control).
* <InternalLink path="import-into">Bulk data imports</InternalLink>.
* <InternalLink path="copy">`COPY`</InternalLink> statements.
* <InternalLink path="delete-data">Deletes</InternalLink> (including deletes initiated by <InternalLink path="row-level-ttl">row-level TTL jobs</InternalLink>; the <InternalLink path="selection-queries">selection queries</InternalLink> performed by TTL jobs are also subject to CPU admission control).
* <InternalLink path="backup-and-restore-overview">Backups</InternalLink>.
* <InternalLink path="online-schema-changes">Schema changes</InternalLink>, including index and column backfills (on both the <InternalLink path="architecture/replication-layer#leases">leaseholder replica</InternalLink> and <InternalLink path="architecture/replication-layer#raft">follower replicas</InternalLink>).
* [Follower replication work](#replication-admission-control).
* <InternalLink path="architecture/replication-layer#raft">Raft log entries being written to disk</InternalLink>.
* <InternalLink path="create-and-configure-changefeeds">Changefeeds</InternalLink>.
* <InternalLink path="architecture/transaction-layer#write-intents">Intent resolution</InternalLink>.

<Note>
  Admission control is beneficial when overall cluster health is good but some nodes are experiencing overload. If you see these overload scenarios on many nodes in the cluster, that typically means the cluster needs more resources.
</Note>

### Replication admission control

The admission control subsystem paces all work done at the <InternalLink path="architecture/replication-layer#raft">Replication Layer</InternalLink> to avoid cluster overload. This includes user-facing writes from SQL statements, as well as background (elastic) replication work.

New in v25.1: The pacing of catchup writes is controlled at the replication layer to avoid overloading slow or <InternalLink path="eventlog#node_restart">newly restarted nodes</InternalLink> with replication flows. Note that this pacing does not slow down user-facing SQL writes; it only ensures there are fewer impacts from background operations.

At a high level, replication admission control works by:

* Pacing regular SQL writes at the rate of replica quorum. (**New in v25.1**)
* Pacing background (elastic) replication at the rate of the slowest replica.

This has the following effects:

1. Does not overload slow/restarted nodes with replication flows. (**New in v25.1**)
2. Isolates performance between regular and elastic traffic.
3. Paces regular writes at quorum speed. (**New in v25.1**)
4. Paces elastic writes at the slowest replica's speed.

For example, prior to CockroachDB v25.1, when a leader and follower replica were disconnected from each other due to a node going away and coming back, once the follower came back the leader would slam the follower with any Raft entries it had missed. In v25.1 and later, the leader paces the entries it sends to the follower. The result is that baseline cluster QPS (queries per second) and latency should not change substantially during perturbations such as <InternalLink path="eventlog#node_restart">node restarts</InternalLink>.

To monitor the behavior of replication admission control, refer to <InternalLink path="ui-overload-dashboard">UI Overload Dashboard > Replication Admission Control</InternalLink>.

## Enable and disable admission control

Admission control is enabled by default. To enable or disable admission control, use the following <InternalLink path="cluster-settings">cluster settings</InternalLink>:

* `admission.kv.enabled` for work performed by the <InternalLink path="architecture/distribution-layer">KV layer</InternalLink>.
* `admission.sql_kv_response.enabled` for work performed in the SQL layer when receiving <InternalLink path="architecture/distribution-layer">KV responses</InternalLink>.
* `admission.sql_sql_response.enabled` for work performed in the SQL layer when receiving <InternalLink path="architecture/sql-layer#distsql">DistSQL responses</InternalLink>.
* `kvadmission.store.snapshot_ingest_bandwidth_control.enabled` to optionally limit the disk impact of ingesting snapshots on a node. This cluster setting is in <InternalLink path="cockroachdb-feature-availability">Preview</InternalLink>.
* `kvadmission.store.provisioned_bandwidth` to optionally limit the disk bandwidth capacity of stores on the cluster. Disk bandwidth admission control paces background disk writes to keep disk bandwidth within its provisioned bandwidth. This cluster setting is in <InternalLink path="cockroachdb-feature-availability">Preview</InternalLink>.

When you enable or disable admission control settings for one layer, Cockroach Labs recommends that you enable or disable them for **all layers**.

## Work queues and ordering

When admission control is enabled, request and response operations are sorted into work queues where the operations are organized by priority and transaction start time.

Higher priority operations are processed first. The criteria for determining higher and lower priority operations is different at each processing layer, and is determined by the CPU and storage I/O of the operation. Write operations in the <InternalLink path="architecture/storage-layer">KV storage layer</InternalLink> in particular are often the cause of performance bottlenecks, and admission control prevents <InternalLink path="architecture/storage-layer#pebble">the Pebble storage engine</InternalLink> from experiencing high <InternalLink path="architecture/storage-layer">read amplification</InternalLink>. Critical cluster operations like node heartbeats are processed as high priority, as are transactions that hold <InternalLink path="crdb-internal#cluster_locks">locks</InternalLink> in order to avoid <InternalLink path="performance-recipes#transaction-contention">contention</InternalLink> and release locks earlier.

The transaction start time is used within the priority queue and gives preference to operations with earlier transaction start times. For example, within the high priority queue operations with an earlier transaction start time are processed first.

### Set quality of service level for a session

In an overload scenario where CockroachDB cannot service all requests, you can identify which requests should be prioritized. This is often referred to as *quality of service* (QoS). Admission control queues work throughout the system. To set the quality of service level on the admission control queues on behalf of SQL requests submitted in a session, use the <InternalLink path="set-vars">`default_transaction_quality_of_service`</InternalLink> session variable. The valid values are `critical`, `background`, and `regular`. Admission control must be enabled for this setting to have an effect.

To increase the priority of subsequent SQL requests, run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET default_transaction_quality_of_service=critical;
```

To decrease the priority of subsequent SQL requests, run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET default_transaction_quality_of_service=background;
```

To reset the priority to the default session setting (in between background and critical), run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET default_transaction_quality_of_service=regular;
```

The quality of service for <InternalLink path="copy">`COPY`</InternalLink> statements is configured separately with the <InternalLink path="set-vars">`copy_transaction_quality_of_service`</InternalLink> session variable, which defaults to `background`.

To increase the priority of subsequent `COPY` statements, run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET copy_transaction_quality_of_service=critical;
```

### Set quality of service level for a transaction

To set the quality of service level for a single <InternalLink path="transactions">transaction</InternalLink>, set the <InternalLink path="set-vars">`default_transaction_quality_of_service`</InternalLink> and/or <InternalLink path="set-vars">`copy_transaction_quality_of_service`</InternalLink> session variable for just that transaction using the <InternalLink path="set-vars#set-a-variable-for-the-duration-of-a-single-transaction">`SET LOCAL`</InternalLink> statement inside a <InternalLink path="begin-transaction">`BEGIN`</InternalLink> ... <InternalLink path="commit-transaction">`COMMIT`</InternalLink> block, as shown in the following example. The valid values are `critical`, `background`, and `regular`.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
BEGIN;
SET LOCAL default_transaction_quality_of_service = 'regular'; -- Edit transaction QoS to desired level
SET LOCAL copy_transaction_quality_of_service = 'regular'; -- Edit COPY QoS to desired level
-- Statements to run in this transaction go here
COMMIT;
```

## Known limitations

Admission control works on the level of each node, not at the cluster level. The admission control system queues requests until the operations are processed or the request exceeds the timeout value (for example by using <InternalLink path="set-vars#supported-variables">`SET statement_timeout`</InternalLink>). If you specify aggressive timeout values, the system may operate correctly but have low throughput as the operations exceed the timeout value while only completing part of the work. There is no mechanism for preemptively rejecting requests when the work queues are long.

Organizing operations by priority can mean that higher priority operations consume all the available resources while lower priority operations remain in the queue until the operation times out.

## Considerations

To prevent unnecessary queuing in admission control CPU queues, the `goschedstats.always_use_short_sample_period.enabled` <InternalLink path="cluster-settings">cluster setting</InternalLink> should be set to `true` for any production cluster.

<InternalLink path="connection-parameters">Client connections</InternalLink> are not managed by the admission control subsystem. Too many connections per <InternalLink path="architecture/sql-layer">gateway node</InternalLink> can also lead to cluster overload.

To control the maximum number of non-superuser (<InternalLink path="security-reference/authorization">`root`</InternalLink> user or other <InternalLink path="security-reference/authorization#admin-role">`admin` role</InternalLink>) connections a <InternalLink path="architecture/sql-layer">gateway node</InternalLink> can have open at one time, use the `server.max_connections_per_gateway` <InternalLink path="cluster-settings">cluster setting</InternalLink>.  If a new non-superuser connection would exceed this limit, the error message `"sorry, too many clients already"` is returned, along with error code `53300`.

## Observe admission control performance

The <InternalLink path="ui-overload-dashboard">DB Console Overload dashboard</InternalLink> shows metrics related to the performance of the admission control system.

## See also

* The <InternalLink path="ui-overload-dashboard">Overload Dashboard</InternalLink> in the <InternalLink path="ui-overview">DB Console</InternalLink>.
* The blog post [Here's how CockroachDB keeps your database from collapsing under load](https://www.cockroachlabs.com/blog/admission-control-in-cockroachdb/).
* The blog post [Rubbing Control Theory on the Go scheduler](https://www.cockroachlabs.com/blog/rubbing-control-theory/).
