Skip to main content
This feature is in and subject to change. To share feedback and/or issues, contact Support.
Resource groups divide the CPU of each node among workloads. Each resource group has a CPU weight, and each can be assigned to a resource group. When a node’s CPU is contended, 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 (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%. 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 .

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.

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: 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 . Until it is, resource group statements return the following error:
  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:
    While this setting is false, resource group statements return the following error:
  3. Switch CPU admission control to resource manager mode by setting the admission.cpu_time_tokens.mode cluster setting to 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 .

Create resource groups

To create a resource group, use . The following statements create a group named oltp for a latency-sensitive application, and a group named reporting for analytics queries:
To view the groups and their CPU shares, run:
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 . You can assign a resource group in the following ways:
  • For the current session, use :
  • For all future sessions of a role, use :
  • For all future sessions that connect to a database, use :
When a session starts, its resource group is determined by the same 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 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:
To view role and database defaults, use .

Change or remove a resource group

To change a group’s weight or max_cpu option, use . The change applies to sessions that are already assigned to the group. To remove a resource group, use . 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:
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 .
  • Resource groups manage CPU only. They do not manage memory, storage I/O, or connections.
  • Resource groups do not affect . 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