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

# Resource Groups

> [!NOTE]
>
> **This feature is in [preview](https://docs.cockroachlabs.com/docs/releases/cockroachdb-feature-availability.md)** and subject to change. To share feedback and/or issues, contact [Support](https://support.cockroachlabs.com).

Resource groups divide the CPU of each node among workloads. Each resource group has a CPU weight, and each [session](https://docs.cockroachlabs.com/docs/stable/show-sessions.md) can be assigned to a resource group. When a node's CPU is contended, [admission control](https://docs.cockroachlabs.com/docs/stable/admission-control.md) on that node admits work so that each group's CPU use is proportional to its weight. Weights are enforced independently on each node. When CPU is not contended, a group can use CPU that other groups leave idle.

Resource groups and [quality of service](https://docs.cockroachlabs.com/docs/stable/admission-control.md#set-quality-of-service-level-for-a-session) (QoS) levels work together. A resource group determines how much CPU a workload receives under contention. The QoS level determines the order in which queued work is admitted within a resource group. The `background` QoS level is an exception: KV work from a `background` session is admitted through the elastic CPU queue, not through the session's resource group.

Resource groups manage CPU only. They do not manage memory, storage I/O, or connections.

## How CPU is shared

Each resource group has a `cpu_weight`. A group's share of CPU is its weight divided by the sum of the weights of all user-defined resource groups. For example, a group with a weight of `300` and a group with a weight of `100` have shares of 75% and 25%. [`SHOW RESOURCE GROUPS`](https://docs.cockroachlabs.com/docs/stable/show-resource-groups) displays each group's share in the `cpu_share_percent` column.

Weights are relative, not absolute. When CPU is contended, admission control on each node admits queued work from the group that has used the least CPU relative to its weight. Over time, each group that has work waiting receives CPU in proportion to its weight. A group that has no work waiting does not hold on to its share, and the other groups can use that CPU.

Work that waits for admission is delayed, not rejected. Work in a group that has used more than its share waits longer, and can exceed a timeout such as [`statement_timeout`](https://docs.cockroachlabs.com/docs/stable/set-vars#supported-variables).

### `max_cpu`

When CPU is contended, admission control on each node sorts resource groups into two tiers:

* Burst tier: admitted first, and can run the node up to the highest CPU utilization that admission control allows.
* Regular tier: admitted only after the burst tier, and throttled at a lower node CPU utilization.

Within each tier, groups share CPU in proportion to their `cpu_weight`.

The `max_cpu` option controls which tier a group is in:

* `max_cpu = true`: the group is always in the burst tier.
* `max_cpu = false` (default): the group is in the burst tier while its recent CPU use is within its share. Once it uses more than its share, it drops to the regular tier until its use falls back within its share.

Neither setting caps a group. A group in the regular tier can still use CPU that no other group needs.

For example, `oltp` (`max_cpu = true`, 75%) and `reporting` (`max_cpu = false`, 25%) both have queued work. While `reporting` stays within 25%, both groups are in the burst tier and share CPU 3:1. If `reporting` uses more than 25%, its work waits behind `oltp`'s until its use drops back.

### CPU utilization targets

Two cluster settings set the node CPU utilization at which admission control throttles each tier.

| Setting | Default | Description |
| - | - | - |
| `admission.cpu_time_tokens.target_util` | `0.8` | The node CPU utilization at which work in the regular tier is throttled. The minimum is `0.5`. |
| `admission.cpu_time_tokens.target_util.burst_delta` | `0.05` | Added to `admission.cpu_time_tokens.target_util` to get the node CPU utilization at which work in the burst tier is throttled. Must be greater than `0`. |

### Built-in resource groups

Work from sessions that are not assigned to a resource group runs in a built-in default resource group, named `crdb_internal_resource_group_default`. By default, this group has the minimum CPU weight and is always in the burst tier, as if it were created with `max_cpu = true`. As a result, work that is not assigned to a group can use idle CPU, but when CPU is contended it receives a small share compared with user-defined groups. Because it is always in the burst tier, unassigned work is also admitted ahead of work from a `max_cpu = false` group that has used more than its share.

Internal KV work that is not tied to a session, such as intent resolution and transaction cleanup, runs in a separate built-in resource group that is admitted ahead of user-defined groups. Low-priority internal work, such as MVCC garbage collection and rangefeed catch-up scans, is paced by elastic CPU admission control and does not go through resource groups.

The two built-in resource groups are configured the same way as user-defined resource groups, with a CPU weight and a `max_cpu` setting. Their behavior follows from these values, not from a separate priority. The following table shows the configuration of each built-in group and its effect:

| Built-in resource group | CPU weight | `max_cpu` | Effect |
| - | - | - | - |
| `crdb_internal_resource_group_default`, for work from sessions that are not assigned to a resource group | `1` (the minimum) | `true` | Can use idle CPU, but receives a small share of CPU compared with user-defined groups when CPU is contended. |
| Internal KV group, for internal KV work such as intent resolution and transaction cleanup | `4294967295` (the maximum) | `true` | Is admitted ahead of user-defined groups. |

The built-in resource groups do not appear in the output of `SHOW RESOURCE GROUPS`, and their weights are not included in `cpu_share_percent`.

## Enable resource groups

Resource groups are disabled by default. To use resource groups, enable the resource group SQL statements and switch CPU admission control to a mode that enforces resource groups:

1. Make sure that the [upgrade to v26.4 is finalized](https://docs.cockroachlabs.com/docs/stable/upgrade-cockroach-version.md). Until it is, resource group statements return the following error:

   ```
   ERROR: resource group SQL is not available until the cluster upgrade to v26.4 is finalized
   SQLSTATE: 0A000
   ```

2. Enable the `CREATE RESOURCE GROUP`, `ALTER RESOURCE GROUP`, `DROP RESOURCE GROUP`, and `SHOW RESOURCE GROUPS` statements by setting the `sql.experimental_resource_groups.enabled` cluster setting to `true`:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING sql.experimental_resource_groups.enabled = true;
   ```

   While this setting is `false`, resource group statements return the following error:

   ```
   ERROR: resource group SQL is disabled by the sql.experimental_resource_groups.enabled cluster setting
   SQLSTATE: 0A000
   HINT: to enable, run: SET CLUSTER SETTING sql.experimental_resource_groups.enabled = true
   ```

3. Switch CPU admission control to resource manager mode by setting the `admission.cpu_time_tokens.mode` cluster setting to `resource_manager`:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SET CLUSTER SETTING admission.cpu_time_tokens.mode = 'resource_manager';
   ```

   In this mode, CPU admission control on every node admits work by resource group. In any other mode, you can create resource groups and assign sessions to them, but admission control does not enforce them.

For the privileges required to change cluster settings, refer to [`SET CLUSTER SETTING`](https://docs.cockroachlabs.com/docs/stable/set-cluster-setting#required-privileges).

## Create resource groups

To create a resource group, use [`CREATE RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/create-resource-group). The following statements create a group named `oltp` for a latency-sensitive application, and a group named `reporting` for analytics queries:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE RESOURCE GROUP oltp WITH (cpu_weight = 300, max_cpu = true);
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE RESOURCE GROUP reporting WITH (cpu_weight = 100);
```

To view the groups and their CPU shares, run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SHOW RESOURCE GROUPS;
```

```
  id |   name    | cpu_weight | max_cpu | cpu_share_percent
-----+-----------+------------+---------+--------------------
  17 | oltp      |        300 |    t    |                75
  18 | reporting |        100 |    f    |                25
(2 rows)
```

When CPU is contended and both groups have work waiting, `oltp` receives about three times as much CPU as `reporting`. Because `oltp` has `max_cpu = true`, it stays in the burst tier when it uses more than its share.

## Assign workloads to a resource group

A session's resource group is set by the `resource_group` [session variable](https://docs.cockroachlabs.com/docs/stable/set-vars.md). You can assign a resource group in the following ways:

* For the current session, use [`SET`](https://docs.cockroachlabs.com/docs/stable/set-vars):

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  SET resource_group = 'oltp';
  ```

* For all future sessions of a role, use [`ALTER ROLE ... SET`](https://docs.cockroachlabs.com/docs/stable/alter-role#assign-a-role-to-a-resource-group):

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER ROLE report_user SET resource_group = 'reporting';
  ```

* For all future sessions that connect to a database, use [`ALTER DATABASE ... SET`](https://docs.cockroachlabs.com/docs/stable/alter-database#assign-a-database-to-a-resource-group):

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER DATABASE analytics SET resource_group = 'reporting';
  ```

When a session starts, its resource group is determined by the same [session variable precedence](https://docs.cockroachlabs.com/docs/stable/alter-role.md#session-variable-precedence) as other session variables. Role and database defaults apply only to sessions that start after the default is set.

The group name in the `resource_group` session variable is case-sensitive, and it must name an existing resource group. Only members of the [`admin` role](https://docs.cockroachlabs.com/docs/stable/security-reference/authorization#admin-role) can set the `resource_group` session variable, including through `ALTER ROLE`, `ALTER DATABASE`, and connection string parameters. Any user can run `RESET resource_group` or `SET resource_group = DEFAULT`, which returns the session to the resource group set by its role or database default. If no such default applies, the session is not assigned to a resource group.

To view the current session's resource group, run:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SHOW resource_group;
```

```
  resource_group
------------------
  oltp
(1 row)
```

To view role and database defaults, use [`SHOW DEFAULT SESSION VARIABLES FOR ROLE`](https://docs.cockroachlabs.com/docs/stable/show-default-session-variables-for-role).

## Change or remove a resource group

To change a group's weight or `max_cpu` option, use [`ALTER RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/alter-resource-group). The change applies to sessions that are already assigned to the group.

To remove a resource group, use [`DROP RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/drop-resource-group). Sessions, roles, and databases that are assigned to a dropped group keep the group name in their `resource_group` setting, and their work runs in the default resource group.

## Disable resource groups

To stop enforcing resource groups, set the `admission.cpu_time_tokens.mode` cluster setting to `off`:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SET CLUSTER SETTING admission.cpu_time_tokens.mode = 'off';
```

Resource groups and session assignments are kept, and are enforced again if you set the mode back to `resource_manager`.

## Known limitations

* Resource groups are supported only on clusters that do not use [cluster virtualization](https://docs.cockroachlabs.com/docs/stable/cluster-virtualization-overview.md).
* Resource groups manage CPU only. They do not manage memory, storage I/O, or connections.
* Resource groups do not affect [lock contention](https://docs.cockroachlabs.com/docs/stable/performance-best-practices-overview.md#transaction-contention). A transaction in a group with a small share that holds locks can still block a transaction in a group with a larger share.
* Only members of the `admin` role can create, change, drop, or view resource groups, and assign sessions to them.
* A default set with `ALTER ROLE ... SET resource_group` applies only to sessions of that role. It does not apply to sessions of members of the role.
* `DROP RESOURCE GROUP` does not check whether sessions, roles, or databases are assigned to the group.
* `cpu_share_percent` does not include the weights of the built-in resource groups.

## See also

* [Admission Control](https://docs.cockroachlabs.com/docs/stable/admission-control.md)
* [`CREATE RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/create-resource-group)
* [`ALTER RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/alter-resource-group)
* [`DROP RESOURCE GROUP`](https://docs.cockroachlabs.com/docs/stable/drop-resource-group)
* [`SHOW RESOURCE GROUPS`](https://docs.cockroachlabs.com/docs/stable/show-resource-groups)
* [Session variables](https://docs.cockroachlabs.com/docs/stable/session-variables.md)
