Open-Source Wikis

/

etcd

/

Systems

/

Lease

etcd-io/etcd

Lease

Source: server/lease/.

Purpose

Leases are TTL tokens. A client grants a lease, attaches one or more keys to it, and either renews it or lets it expire. When a lease is revoked or expires, all attached keys are atomically deleted. Leases are the foundation for client-side primitives like distributed locks (client/v3/concurrency/Mutex) and elections (concurrency/Election).

Directory layout

server/lease/
├── lessor.go           # Lessor interface, lessor struct, Promote/Demote
├── lease.go            # Lease object
├── lease_queue.go      # min-heap by expiration
├── leasehttp/          # Server-to-server lease forwarding HTTP API
├── leasepb/            # protobuf for the bbolt encoding
└── metrics.go

Key abstractions

Symbol File Description
Lessor interface server/lease/lessor.go The leader exposes Grant, Revoke, Renew, Lookup, Leases, Promote, Demote
lessor struct same Holds the in-memory lease map, the expiration heap, the checkpointer
Lease server/lease/lease.go One lease: ID, TTL, remaining TTL, attached itemSet keys
LeaseQueue server/lease/lease_queue.go Min-heap keyed by next-expiry time
Checkpointer server/lease/lessor.go Function reference to EtcdServer.LeaseCheckpoint (proposed via Raft)
RangeDeleter server/lease/lessor.go Function returning a TxnDelete; used to delete all attached keys atomically when a lease expires

How it works

graph TD
    grpc[v3rpc/lease.go] -->|Grant| server[EtcdServer]
    server -->|Propose LeaseGrant| raft[Raft]
    raft -->|toApply| apply[apply pipeline]
    apply --> les[lessor.Grant]
    les --> heap[LeaseQueue]
    les --> bolt[(lease bucket)]

    timer[expiration loop] --> heap
    heap --> les2[lessor.expireExists]
    les2 -->|propose LeaseRevoke| raft
    raft --> apply2[apply LeaseRevoke]
    apply2 --> rd[RangeDeleter]
    rd --> mvcc[(mvcc.DeleteRange attached keys)]
    apply2 --> les3[lessor.Revoke]
    les3 --> bolt

Key behaviors:

  • The lessor on the leader is the primary. Followers run a "demoted" lessor that does not expire leases; on leader change the new leader's lessor is Promote()d.
  • TTL is rounded up to the resolution of the lease loop tick.
  • LeaseRenew is a non-Raft RPC on the leader: it just bumps the in-memory expiry. To survive failover, the lessor periodically checkpoints remaining TTL via a Raft proposal — see defaultLeaseCheckpointInterval = 5 * time.Minute.
  • Followers handle LeaseRenew by forwarding the request to the leader over lease/leasehttp/.

Configuration knobs

Flag / constant Default Effect
MaxLeaseTTL 9_000_000_000 s Server-side TTL cap
defaultLeaseRevokeRate 1000 leases/s Throttle for expiration storms
leaseCheckpointRate 1000 entries/s Throttle for batched checkpoints
defaultLeaseCheckpointInterval 5 min How often remaining TTL is durably checkpointed
defaultExpiredleaseRetryInterval 3 s Retry cadence for already-expired-but-not-yet-revoked leases

Integration points

  • Raft + apply: every lease lifecycle event (grant, revoke, attach, detach) is a Raft entry. Renewal is the only non-Raft path.
  • MVCC: RangeDeleter is supplied by EtcdServer so the lessor can delete attached keys without circular imports.
  • Backend (bbolt): leases are persisted in the lease bucket (server/storage/schema/lease.go).
  • gRPC: server/etcdserver/api/v3rpc/lease.go wraps the lessor for clients.

Entry points for modification

  • New lease attribute → server/lease/leasepb/lease.proto (regenerate), then plumb through lessor.go.
  • New expiration policy → LeaseQueue and lessor.runLoop (in lessor.go).
  • New API method (e.g. listing leases by attached key) → lessor.go + server/etcdserver/api/v3rpc/lease.go.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Lease – etcd wiki | Factory