--- layout: commands page_title: 'Commands: Lock' description: >- The lock command provides a mechanism for leader election, mutual exclusion, or worker pools. For example, this can be used to ensure a maximum number of services running at once across a cluster. --- # Consul Lock Command: `consul lock` The `lock` command provides a mechanism for simple distributed locking. A lock (or semaphore) is created at a given prefix in the KV store, and only when held, is a child process invoked. If the lock is lost or communication is disrupted, the child process is terminated. The number of lock holders is configurable with the `-n` flag. By default, a single holder is allowed, and a lock is used for mutual exclusion. This uses the [leader election algorithm](/consul/tutorials/developer-configuration/application-leader-elections?utm_source=docs). If the lock holder count is more than one, then a semaphore is used instead. A semaphore allows more than a single holder, but this is less efficient than a simple lock. This follows the [semaphore algorithm](/consul/tutorials/developer-configuration/distributed-semaphore?utm_source=docs). All locks using the same prefix must agree on the value of `-n`. If conflicting values of `-n` are provided, an error will be returned. An example use case is for highly-available N+1 deployments. In these cases, if N instances of a service are required, N+1 are deployed and use consul lock with `-n=N` to ensure only N instances are running. For singleton services, a hot standby waits until the current leader fails to take over. ## Usage Usage: `consul lock [options] prefix child...` The only required options are the key prefix and the command to execute. The prefix must be writable. The child is invoked only when the lock is held, and the `CONSUL_LOCK_HELD` environment variable will be set to `true`. If the lock is lost, communication is disrupted, or the parent process interrupted, the child process will receive a `SIGTERM`. After a grace period of 5 seconds, a `SIGKILL` will be used to force termination. For Consul agents on Windows, the child process is always terminated with a `SIGKILL`, since Windows has no POSIX compatible notion for `SIGTERM`. #### Command Options - `-child-exit-code` - Exit 2 if the child process exited with an error if this is true, otherwise this doesn't propagate an error from the child. The default value is false. - `-monitor-retry` - Retry up to this number of times if Consul returns a 500 error while monitoring the lock. This allows riding out brief periods of unavailability without causing leader elections, but increases the amount of time required to detect a lost lock in some cases. Defaults to 3, with a 1s wait between retries. Set to 0 to disable. - `-n` - Optional, limit of lock holders. Defaults to 1. The underlying implementation switches from a lock to a semaphore when increased past one. All locks on the same prefix must use the same value. - `-name` - Optional name to associate with the underlying session. If not provided, one is generated based on the child command. - `-shell` - Optional, use a shell to run the command (can set a custom shell via the SHELL environment variable). The default value is true. - `-pass-stdin` - Pass stdin to child process. - `-timeout` - Attempt to acquire the lock up to the given timeout. The timeout is a positive decimal number, with unit suffix, such as "500ms". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". The default value is 0. - `-verbose` - Enables verbose output. #### API Options @include 'http_api_options_client.mdx' @include 'http_api_options_server.mdx' ## SHELL Consul lock launches its children in a shell. By default, Consul will use the shell defined in the environment variable `SHELL`. If `SHELL` is not defined, it will default to `/bin/sh`. It should be noted that not all shells terminate child processes when they receive `SIGTERM`. Under Ubuntu, `/bin/sh` is linked to `dash`, which does **not** terminate its children. In order to ensure that child processes are killed when the lock is lost, be sure to set the `SHELL` environment variable appropriately, or run without a shell by setting `-shell=false`.