Skip to main content
A node shutdown terminates the cockroach process on the node. There are two ways to handle node shutdown:
  • Drain a node to temporarily stop it when you plan restart it later, such as during cluster maintenance. When you drain a node:
    • Clients are disconnected, and subsequent connection requests are sent to other nodes.
    • The node’s data store is preserved and will be reused as long as the node restarts in a short time. Otherwise, the node’s data is moved to other nodes.
    After the node is drained, you can manually terminate the cockroach process to perform maintenance, then restart the process for the node to rejoin the cluster. The --shutdown flag of automatically terminates the cockroach process after draining completes. A node is also automatically drained when . Draining a node is lightweight because it generates little node-to-node traffic across the cluster.
  • Decommission a node to permanently remove it from the cluster, such as when scaling down the cluster or to replace the node due to hardware failure. During decommission:
    • The node is drained automatically if you have not manually drained it.
    • The node’s data is moved off the node to other nodes. This generates a large amount of node-to-node network traffic, so decommissioning a node is considered a heavyweight operation.
This page describes:
This guidance applies to primarily to manual deployments. For more details about graceful termination when CockroachDB is deployed using Kubernetes, refer to Decommissioning and draining on Kubernetes. For more details about graceful termination in a CockroachDB Advanced cluster, refer to Decommissioning and draining on CockroachDB Advanced.

Node shutdown sequence

When a node is temporarily stopped, the following stages occur in sequence:

Draining

An operator initiates the draining process on the node. Draining a node disconnects clients after active queries are completed, and transfers any and to other nodes, but does not move replicas or data off of the node.When draining is complete, the node must be shut down prior to any maintenance. After a 60-second wait at minimum, you can send a SIGTERM signal to the cockroach process to shut it down. The --shutdown flag of automatically terminates the cockroach process after draining completes.After you perform the required maintenance, you can restart the cockroach process on the node for it to rejoin the cluster.
Do not terminate the cockroach process before all of the phases of draining are complete. Otherwise, you may experience latency spikes until the that were on that node have transitioned to other nodes. It is safe to terminate the cockroach process only after a node has completed the drain process. This is especially important in a containerized system, to allow all TCP connections to terminate gracefully. If necessary, adjust the server.shutdown.initial_wait and the cluster settings and adjust your process manager or other deployment tooling to allow adequate time for the node to finish draining before it is terminated or restarted.
Node drain consists of the following consecutive phases:
  1. Unready phase: The node’s returns an HTTP 503 Service Unavailable response code, which causes load balancers and connection managers to reroute traffic to other nodes. This phase completes when the fixed duration set by server.shutdown.initial_wait is reached.
  2. SQL wait phase: New SQL client connections are no longer permitted, and any remaining SQL client connections are allowed to close or time out. This phase completes either when all SQL client connections are closed or the maximum duration set by server.shutdown.connections.timeout is reached.
  3. SQL drain phase: All active transactions and statements for which the node is a are allowed to complete, and CockroachDB closes the SQL client connections immediately afterward. After this phase completes, CockroachDB closes all remaining SQL client connections to the node. This phase completes either when all transactions have been processed or the maximum duration set by server.shutdown.transactions.timeout is reached.
  4. DistSQL drain phase: All initiated on other gateway nodes are allowed to complete, and DistSQL requests from other nodes are no longer accepted. This phase completes either when all transactions have been processed or the maximum duration set by server.shutdown.transactions.timeout is reached.
  5. Lease transfer phase: The node’s field is set to true, which removes the node as a candidate for replica rebalancing, lease transfers, and query planning. Any or must be transferred to other nodes. This phase completes when all range leases and Raft leaderships have been transferred.
When draining manually, if the above steps have not completed after server.shutdown.initial_wait, node draining will stop and must be restarted manually to continue. For more information, see Drain timeout.At this point, it is safe to terminate the cockroach process manually or using your process manager or other deployment tooling (such as Kubernetes, Nomad, or Docker).

Process termination

After draining is complete:
  • If the node was drained automatically because the cockroach process received a SIGTERM signal, the cockroach process is automatically terminated when draining is complete.
  • If the node was drained manually because an operator issued a cockroach node drain command:
    • If you pass the --shutdown flag to , the cockroach process terminates automatically after draining completes.
    • If the node’s major version is being updated, the cockroach process terminates automatically after draining completes.
    • Otherwise, the cockroach process must be terminated manually. A minimum of 60 seconds after draining is complete, send it a SIGTERM signal to terminate it. Refer to Terminate the node process.
A node process termination stops the cockroach process on the node. The node will stop updating its liveness record.If the node then stays offline for the duration set by server.time_until_store_dead (5 minutes by default), the cluster considers the node “dead” and starts to rebalance its range replicas onto other nodes.If the node is brought back online, its remaining range replicas will determine whether or not they are still valid members of replica groups. If a range replica is still valid and any data in its range has changed, it will receive updates from another replica in the group. If a range replica is no longer valid, it will be removed from the node.
CockroachDB’s node shutdown behavior does not match any of the PostgreSQL server shutdown modes.

Prepare for graceful shutdown

Each of the node shutdown steps is performed in order, with each step commencing once the previous step has completed. However, because some steps can be interrupted, it’s best to ensure that all steps complete gracefully.Before you perform node shutdown, review the following prerequisites to graceful shutdown:

Load balancing

Your should use the to actively monitor node health and direct SQL client connections away from nodes that are not ready to receive requests.To handle node shutdown effectively, the load balancer must be given enough time by the server.shutdown.initial_wait duration.

Cluster settings

server.shutdown.initial_wait

Alias: server.shutdown.drain_waitserver.shutdown.initial_wait sets a fixed duration for the “unready phase” of node drain. Because a load balancer reroutes connections to non-draining nodes within this duration (0s by default), this setting should be coordinated with the load balancer settings.Increase server.shutdown.initial_wait so that your load balancer is able to make adjustments before this phase times out. Because the drain process waits unconditionally for the server.shutdown.initial_wait duration, do not set this value too high.For example, uses the default settings inter 2000 fall 3 when checking server health. This means that HAProxy considers a node to be down (and temporarily removes the server from the pool) after 3 unsuccessful health checks being run at intervals of 2000 milliseconds. To ensure HAProxy can run 3 consecutive checks before timeout, set server.shutdown.initial_wait to 8s or greater:

server.shutdown.connections.timeout

Alias: server.shutdown.connection_waitserver.shutdown.connections.timeout sets the maximum duration for the “connection phase” of node drain. SQL client connections are allowed to close or time out within this duration (0s by default). This setting presents an option to gracefully close the connections before CockroachDB forcibly closes those that remain after the “SQL drain phase”.Change this setting only if you cannot tolerate connection errors during node drain and cannot configure the maximum lifetime of SQL client connections, which is usually configurable via a . Depending on your requirements:
  • Lower the maximum lifetime of a SQL client connection in the pool. This will cause more frequent reconnections. Set server.shutdown.connections.timeout above this value.
  • If you cannot tolerate more frequent reconnections, do not change the SQL client connection lifetime. Instead, use a longer server.shutdown.connections.timeout. This will cause a longer draining process.

server.shutdown.transactions.timeout

Alias: server.shutdown.query_waitserver.shutdown.transactions.timeout sets the maximum duration for the “SQL drain phase” and the maximum duration for the “DistSQL drain phase” of node drain. Active local and distributed queries must complete, in turn, within this duration (10s by default).Ensure that server.shutdown.transactions.timeout is greater than:
  • The longest possible transaction in the workload that is expected to complete successfully.
  • The sql.defaults.idle_in_transaction_session_timeout cluster setting, which controls the duration a session is permitted to idle in a transaction before the session is terminated (0s by default).
  • The sql.defaults.statement_timeout cluster setting, which controls the duration a query is permitted to run before it is canceled (0s by default).
server.shutdown.transactions.timeout defines the upper bound of the duration, meaning that node drain proceeds to the next phase as soon as the last open transaction completes.
If there are still open transactions on the draining node when the server closes its connections, you will encounter errors. You may need to adjust your application server’s settings.
Use instead of the sql.defaults.* . This allows you to set a default value for all users for any that applies during login, making the sql.defaults.* cluster settings redundant.

server.shutdown.lease_transfer_iteration.timeout

Alias: server.shutdown.lease_transfer_waitIn the “lease transfer phase” of node drain, the server attempts to transfer all and from the draining node. server.shutdown.lease_transfer_iteration.timeout sets the maximum duration of each iteration of this attempt (5s by default). Because this phase does not exit until all transfers are completed, changing this value affects only the frequency at which drain progress messages are printed.In most cases, the default value is suitable. Do not set server.shutdown.lease_transfer_iteration.timeout to a value lower than 5s. In this case, leases can fail to transfer and node drain will not be able to complete.

kv.allocator.recovery_store_selector

When a node is dead or decommissioning and all of its range replicas are being up-replicated onto other nodes, this setting controls the algorithm used to select the new node for each range replica. Regardless of the algorithm, a node must satisfy all available constraints for replica placement and survivability to be eligible.Possible values are good (the default) and best. When set to good, a random node is selected from the list of all eligible nodes. When set to best, a node with a low range count is preferred.

server.time_until_store_dead

server.time_until_store_dead sets the duration after which a node is considered “dead” and its data is rebalanced to other nodes (5m0s by default). In the node shutdown sequence, this follows process termination.Before temporarily stopping nodes for planned maintenance (e.g., upgrading system software), if you expect any nodes to be offline for longer than 5 minutes, you can prevent the cluster from unnecessarily moving data off the nodes by increasing server.time_until_store_dead to match the estimated maintenance window:
During this window, the cluster has reduced ability to tolerate another node failure. Be aware that increasing this value therefore reduces fault tolerance.
After completing the maintenance work and , you would then change the setting back to its default:

Drain timeout

When draining manually with cockroach node drain, all drain phases must be completed within the duration of --drain-wait (10m by default) or the drain will stop. This can be observed with an ERROR: drain timeout message in the terminal output. To continue the drain, re-initiate the command.A very long drain may indicate an anomaly, and you should manually inspect the server to determine what blocks the drain.CockroachDB automatically increases the verbosity of logging when it detects a stall in the range lease transfer stage of node drain. Messages logged during such a stall include the time an attempt occurred, the total duration stalled waiting for the transfer attempt to complete, and the lease that is being transferred.--drain-wait sets the timeout for all draining phases and is not related to the server.shutdown.initial_wait cluster setting, which configures the “unready phase” of draining. The value of --drain-wait should be greater than the sum of server.shutdown.initial_wait, server.shutdown.connections.timeout, server.shutdown.transactions.timeout times two, and server.shutdown.lease_transfer_iteration.timeout.

Termination grace period

On production deployments, a process manager or orchestration system can disrupt graceful node shutdown if its termination grace period is too short.Do not terminate the cockroach process before all of the phases of draining are complete. Otherwise, you may experience latency spikes until the that were on that node have transitioned to other nodes. It is safe to terminate the cockroach process only after a node has completed the drain process. This is especially important in a containerized system, to allow all TCP connections to terminate gracefully.If the cockroach process has not terminated at the end of the grace period, a SIGKILL signal is sent to perform a “hard” shutdown that bypasses CockroachDB’s node shutdown logic and forcibly terminates the process.To determine an appropriate termination grace period:
  • Run cockroach node drain with --drain-wait and observe the amount of time it takes node drain to successfully complete.
  • In general, we recommend setting the termination grace period to the sum of all server.shutdown.* settings. If a node requires more time than this to drain successfully, this may indicate a technical issue such as inadequate .
  • Increasing the termination grace period does not increase the duration of a node shutdown. However, the termination grace period should not be excessively long, as this can mask an underlying hardware or software issue that is causing node shutdown to become “stuck”.

Perform node shutdown

After preparing for graceful shutdown, do the following to temporarily stop a node. This both drains the node and terminates the cockroach process.
This guidance applies to manual deployments. In a Kubernetes deployment or a CockroachDB Advanced cluster, terminating the cockroach process is handled through Kubernetes. Refer to Decommissioning and draining on Kubernetes and Decommissioning and draining on CockroachDB Advanced.

Drain the node and terminate the node process

If you passed the --shutdown flag to , the cockroach process terminates automatically after draining completes. Otherwise, terminate the cockroach process.Perform maintenance on the node as required, then restart the cockroach process for the node to rejoin the cluster.
To drain the node without process termination, see Drain a node manually.
Cockroach Labs does not recommend terminating the cockroach process by sending a SIGKILL signal, because it bypasses CockroachDB’s node shutdown logic and degrades the cluster’s health. From the point of view of other cluster nodes, the node will be suddenly unavailable.
  • If a decommissioning node is forcibly terminated before decommission completes, and the cluster is at risk of if an additional node experiences an outage in the window before up-replication completes.
  • If a draining or decommissioning node is forcibly terminated before the operation completes, it can corrupt log files and, in certain edge cases, can result in temporary data unavailability, latency spikes, , , or query timeouts.
  • On production deployments, use the process manager, orchestration system, or other deployment tooling to send SIGTERM to the process. For example, with systemd, run systemctl stop {systemd config filename}.
  • If you run CockroachDB in the foreground for local testing, you can use ctrl-c in the terminal to terminate the process.

Monitor shutdown progress

After you initiate a node shutdown or restart, the node’s progress is regularly logged to the until the operation is complete. The following sections provide additional ways to monitor the operation’s progress.

OPS

During node shutdown, progress messages are generated in the . The frequency of these messages is configured with server.shutdown.lease_transfer_iteration.timeout. , the OPS logs output to a cockroach.log file.Node drain progress is reported in unstructured log messages:

cockroach node status

Draining status is reflected in the output:
is_draining == true indicates that the node is either undergoing or has completed the draining process.

stderr

When CockroachDB receives a signal to drain and terminate the node process, this message is printed to stderr:
After the cockroach process has stopped, this message is printed to stderr:

Examples

These examples assume that you have already prepared for a graceful node shutdown.

Stop and restart a node

To drain and shut down a node that was started in the foreground with :
  1. Press ctrl-c in the terminal where the node is running.
  2. Filter the logs for draining progress messages. , the OPS logs output to a cockroach.log file:
    The server drained and shutdown completed message indicates that the cockroach process has stopped.
  3. Start the node to have it rejoin the cluster. Re-run the command that you used to start the node initially. For example:

Drain a node manually

You can use to drain a node separately from decommissioning the node or terminating the node process.
  1. Run the cockroach node drain command, specifying the ID of the node to drain (and optionally a custom drain timeout to allow draining more time to complete). You can optionally pass the --shutdown flag to to automatically terminate the cockroach process after draining completes.
    You will see the draining status print to stderr:
  2. Filter the logs for shutdown progress messages. , the OPS logs output to a cockroach.log file:
    The drain request completed without server shutdown message indicates that the node was drained.

Decommissioning and draining on Kubernetes

Most of the guidance in this page is most relevant to manual deployments that don’t use Kubernetes. If you use Kubernetes to deploy CockroachDB, draining and decommissioning work the same way for the cockroach process, but Kubernetes handles them on your behalf. In a deployment without Kubernetes, an administrator initiates decommissioning or draining directly. In a Kubernetes deployment, an administrator modifies the desired configuration of the Kubernetes cluster and Kubernetes makes the required changes to the cluster, including decommissioning or draining nodes as required.
  • Whether you deployed a cluster using the CockroachDB operator, Helm, or a manual StatefulSet, the resulting deployment is a StatefulSet. Due to the nature of StatefulSets, it’s safe to decommission only the Cockroach node with the highest StatefulSet ordinal in preparation for scaling down the StatefulSet. If you think you need to decommission any other node, consider the following recommendations and contact Support for assistance.
    • If you deployed a cluster using the , the best way to scale down a cluster is to update the specification for the Kubernetes deployment to reduce the value of nodes: and apply the change using a rolling update. Kubernetes will notice that there are now too many nodes and will reduce them and clean up their storage automatically.
    • If you deployed the cluster using or a , the best way to scale down a cluster is to interactively decommission and drain the highest-order node. After that node is decommissioned, drained, and terminated, you can repeat the process to further reduce the cluster’s size.
    Refer to .
  • There is generally no need to interactively drain a node that is not being decommissioned, regardless of how you deployed the cluster in Kubernetes. When you upgrade, downgrade, or change the configuration of a CockroachDB deployment on Kubernetes, you apply the changes using a rolling update, which applies the change to one node at a time. On a given node, Kubernetes sends a SIGTERM signal to the cockroach process. When the cockroach process receives this signal, it starts draining itself. After draining is complete or the termination grace period expires (whichever happens first), Kubernetes terminates the cockroach process and then removes the node from the Kubernetes cluster. Kubernetes then applies the updated deployment to the cluster node, restarts the cockroach process, and re-joins the cluster. Refer to .
  • Although the kubectl drain command is used for manual maintenance of Kubernetes clusters, it has little direct relevance to the concept of draining a node in a CockroachDB cluster. The kubectl drain command gracefully terminates each pod running on a Kubernetes node so that the node can be shut down (in the case of physical hardware) or deleted (in the case of a virtual machine). For details on this command, see the Kubernetes documentation.
Refer to Termination grace period on Kubernetes. For more details about managing CockroachDB on Kubernetes, refer to and .

Termination grace period on Kubernetes

After Kubernetes issues a termination request to the cockroach process on a cluster node, it waits for a maximum of the deployment’s terminationGracePeriodSeconds before forcibly terminating the process. If terminationGracePeriodSeconds is too short, the cockroach process may be terminated before it can shut down cleanly and client applications may be disrupted. If undefined, Kubernetes sets terminationGracePeriodSeconds to 30 seconds. This is too short for the cockroach process to stop gracefully before Kubernetes terminates it forcibly. Do not set terminationGracePeriodSeconds to 0, which prevents Kubernetes from detecting and terminating a stuck pod. For clusters deployed using the CockroachDB Public operator, terminationGracePeriodSeconds defaults to 300 seconds (5 minutes). For clusters deployed using the CockroachDB Helm chart or a manual StatefulSet, the default depends upon the values file or manifest you used when you created the cluster. Cockroach Labs recommends that you:
  • Set terminationGracePeriodSeconds to no shorter than 300 seconds (5 minutes). This recommendation has been validated over time for many production workloads. In most cases, a value higher than 300 seconds (5 minutes) is not required. If CockroachDB takes longer than 5 minutes to gracefully stop, this may indicate an underlying configuration problem. Test the value you select against representative workloads before rolling out the change to production clusters.
  • Set terminationGracePeriodSeconds to be at least 5 seconds longer than the configured drain timeout, to allow the node to complete draining before Kubernetes removes the Kubernetes pod for the CockroachDB node.
  • Ensure that the sum of the following server.shutdown.* settings for the CockroachDB cluster do not exceed the deployment’s terminationGracePeriodSeconds, to reduce the likelihood that a node must be terminated forcibly. A client application’s connection pool should have a maximum lifetime that is shorter than the Kubernetes deployment’s server.shutdown.connections.timeout setting.

Decommissioning and draining on CockroachDB Advanced

Most of the guidance in this page is most relevant to manual deployments, although decommissioning and draining work the same way behind the scenes in a CockroachDB Advanced cluster. CockroachDB Advanced clusters are deployed with the server.shutdown.connections.timeout setting at its default value of 0s, and have a termination grace period that is slightly longer than 30 minutes. This grace period is not configurable. You can adjust the server.shutdown.connections.timeout setting for client applications or application servers that connect to CockroachDB Advanced clusters. Ensure that the connection pool maximum lifetime is shorter than that value, as per the Cluster settings guidance.

Known limitations

  • There is no guaranteed state switch from DECOMMISSIONING to DECOMMISSIONED if is interrupted in one of the following ways:
    • The cockroach node decommission --wait-all command was run and then interrupted
    • The cockroach node decommission --wait=none command was run
    This is because the state flip is effected by the CLI program at the end. Only the CLI (or its underlying API call) is able to finalize the “decommissioned” state. If the command is interrupted, or --wait=none is used, the state will only flip to “decommissioned” when the CLI program is run again after decommissioning has done all its work.

See also