1---
2layout: "docs"
3page_title: "Sessions"
4sidebar_current: "docs-internals-sessions"
5description: |-
6  Consul provides a session mechanism which can be used to build distributed locks. Sessions act as a binding layer between nodes, health checks, and key/value data. They are designed to provide granular locking and are heavily inspired by The Chubby Lock Service for Loosely-Coupled Distributed Systems.
7---
8
9# Sessions
10
11Consul provides a session mechanism which can be used to build distributed locks.
12Sessions act as a binding layer between nodes, health checks, and key/value data.
13They are designed to provide granular locking and are heavily inspired by
14[The Chubby Lock Service for Loosely-Coupled Distributed Systems](http://research.google.com/archive/chubby.html).
15
16## Session Design
17
18A session in Consul represents a contract that has very specific semantics.
19When a session is constructed, a node name, a list of health checks, a behavior,
20a TTL, and a `lock-delay` may be provided. The newly constructed session is provided with
21a named ID that can be used to identify it. This ID can be used with the KV
22store to acquire locks: advisory mechanisms for mutual exclusion.
23
24Below is a diagram showing the relationship between these components:
25
26<div class="center">
27![Consul Sessions](consul-sessions.png)
28</div>
29
30The contract that Consul provides is that under any of the following
31situations, the session will be *invalidated*:
32
33* Node is deregistered
34* Any of the health checks are deregistered
35* Any of the health checks go to the critical state
36* Session is explicitly destroyed
37* TTL expires, if applicable
38
39When a session is invalidated, it is destroyed and can no longer
40be used. What happens to the associated locks depends on the
41behavior specified at creation time. Consul supports a `release`
42and `delete` behavior. The `release` behavior is the default
43if none is specified.
44
45If the `release` behavior is being used, any of the locks held in
46association with the session are released, and the `ModifyIndex` of
47the key is incremented. Alternatively, if the `delete` behavior is
48used, the key corresponding to any of the held locks is simply deleted.
49This can be used to create ephemeral entries that are automatically
50deleted by Consul.
51
52While this is a simple design, it enables a multitude of usage
53patterns. By default, the
54[gossip based failure detector](/docs/internals/gossip.html)
55is used as the associated health check. This failure detector allows
56Consul to detect when a node that is holding a lock has failed and
57to automatically release the lock. This ability provides **liveness** to
58Consul locks; that is, under failure the system can continue to make
59progress. However, because there is no perfect failure detector, it's possible
60to have a false positive (failure detected) which causes the lock to
61be released even though the lock owner is still alive. This means
62we are sacrificing some **safety**.
63
64Conversely, it is possible to create a session with no associated
65health checks. This removes the possibility of a false positive
66and trades liveness for safety. You can be absolutely certain Consul
67will not release the lock even if the existing owner has failed.
68Since Consul APIs allow a session to be force destroyed, this allows
69systems to be built that require an operator to intervene in the
70case of a failure while precluding the possibility of a split-brain.
71
72A third health checking mechanism is session TTLs. When creating
73a session, a TTL can be specified. If the TTL interval expires without
74being renewed, the session has expired and an invalidation is triggered.
75This type of failure detector is also known as a heartbeat failure detector.
76It is less scalable than the gossip based failure detector as it places
77an increased burden on the servers but may be applicable in some cases.
78The contract of a TTL is that it represents a lower bound for invalidation;
79that is, Consul will not expire the session before the TTL is reached, but it
80is allowed to delay the expiration past the TTL. The TTL is renewed on
81session creation, on session renew, and on leader failover. When a TTL
82is being used, clients should be aware of clock skew issues: namely,
83time may not progress at the same rate on the client as on the Consul servers.
84It is best to set conservative TTL values and to renew in advance of the TTL
85to account for network delay and time skew.
86
87The final nuance is that sessions may provide a `lock-delay`. This
88is a time duration, between 0 and 60 seconds. When a session invalidation
89takes place, Consul prevents any of the previously held locks from
90being re-acquired for the `lock-delay` interval; this is a safeguard
91inspired by Google's Chubby. The purpose of this delay is to allow
92the potentially still live leader to detect the invalidation and stop
93processing requests that may lead to inconsistent state. While not a
94bulletproof method, it does avoid the need to introduce sleep states
95into application logic and can help mitigate many issues. While the
96default is to use a 15 second delay, clients are able to disable this
97mechanism by providing a zero delay value.
98
99## K/V Integration
100
101Integration between the KV store and sessions is the primary
102place where sessions are used. A session must be created prior to use
103and is then referred to by its ID.
104
105The KV API is extended to support an `acquire` and `release` operation.
106The `acquire` operation acts like a Check-And-Set operation except it
107can only succeed if there is no existing lock holder (the current lock holder
108can re-`acquire`, see below). On success, there is a normal key update, but
109there is also an increment to the `LockIndex`, and the `Session` value is
110updated to reflect the session holding the lock.
111
112If the lock is already held by the given session during an `acquire`, then
113the `LockIndex` is not incremented but the key contents are updated. This
114lets the current lock holder update the key contents without having to give
115up the lock and reacquire it.
116
117Once held, the lock can be released using a corresponding `release` operation,
118providing the same session. Again, this acts like a Check-And-Set operation
119since the request will fail if given an invalid session. A critical note is
120that the lock can be released without being the creator of the session.
121This is by design as it allows operators to intervene and force-terminate
122a session if necessary. As mentioned above, a session invalidation will also
123cause all held locks to be released or deleted. When a lock is released, the `LockIndex`
124does not change; however, the `Session` is cleared and the `ModifyIndex` increments.
125
126These semantics (heavily borrowed from Chubby), allow the tuple of (Key, LockIndex, Session)
127to act as a unique "sequencer". This `sequencer` can be passed around and used
128to verify if the request belongs to the current lock holder. Because the `LockIndex`
129is incremented on each `acquire`, even if the same session re-acquires a lock,
130the `sequencer` will be able to detect a stale request. Similarly, if a session is
131invalided, the Session corresponding to the given `LockIndex` will be blank.
132
133To be clear, this locking system is purely *advisory*. There is no enforcement
134that clients must acquire a lock to perform any operation. Any client can
135read, write, and delete a key without owning the corresponding lock. It is not
136the goal of Consul to protect against misbehaving clients.
137
138## Leader Election
139
140The primitives provided by sessions and the locking mechanisms of the KV
141store can be used to build client-side leader election algorithms.
142These are covered in more detail in the [Leader Election guide](https://learn.hashicorp.com/consul/developer-configuration/elections).
143
144## Prepared Query Integration
145
146Prepared queries may be attached to a session in order to automatically delete
147the prepared query when the session is invalidated.
148