Skip to content
The witness

The witness and the availability arithmetic

qfence’s quorum needs an odd number of voters, none sharing a failure domain with another. Three is the smallest such cluster: a majority is two, so any one voter can be lost and the other two still decide. Most deployments have two sites, not three. The witness is the third voter: a small process in a third place, such as another region or another cloud, that takes part in raft and nothing else. It is an ordinary raft voter; no safety logic treats it specially (spec §8).

    flowchart LR
  o1["Site dc1<br/>orchestrator<br/>calls dc1's controllers"]
  w["A third place<br/>witness<br/>calls no controller"]
  o2["Site dc2<br/>orchestrator<br/>calls dc2's controllers"]
  o1 <-->|raft| w
  w <-->|raft| o2
  o1 <-->|raft| o2
  

All three are raft voters, so any two of them are a majority. Each site’s orchestrators call that site’s controllers; the witness calls none.

What a witness holds

A witness:

  • votes in leader elections and stores the replicated log, and does nothing else;
  • holds no controller configuration, no credentials and no plan definitions;
  • never starts a fence or a promotion.

It stores the whole raft log, as every voter does, but can read only what spec §8 lists, such as each plan’s owner, generation and state, and raft’s own membership. Everything else that passes through raft reaches it sealed under keys only the orchestrators hold. That covers the orchestrators’ reports (their API addresses, certificate pins and controllers’ states), the detail of fence debts, replicated configuration and cluster secrets. The witness is never given the cluster keyring, so it can open none of them (ADR 0016).

So a compromised witness is worth no more than any other single voter: one vote in an election. It is not a way into your infrastructure.

The availability arithmetic

A witness changes what stays available when things fail. Know what to expect in every case, including the one where it does not help. With your two sites and the witness, a majority is two of three:

Site ASite BWitnessResult
upupupNormal operation
downupupQuorum (2 of 3): a failover to site B can go ahead
updownupQuorum (2 of 3): a failover to site A can go ahead
upupdownQuorum (2 of 3): the witness adds nothing in this, the common, case
downupdownNo quorum (1 of 3). Nothing fails over and nothing is promoted until one of the two comes back
updowndownThe same, the other way round

Read the last two rows carefully. The witness’s own uptime matters in exactly one case: a site is down and a promotion has to be decided, which is the case it exists for. If the witness is down at that moment too, there is no quorum and no failover. That is qfence refusing to guess, by design: without a majority it fails closed.

Two tests prove these rows against a real three-voter cluster, in tests/e2e/witness_topology_test.go: TestWitnessTopologyWitnessAloneDownKeepsQuorum and TestWitnessTopologyWitnessAndOneSiteDownFailsClosed.

Placing it

  • Somewhere neither site’s failure takes with it: another region or cloud, with its own power and network. A small VM is enough; there is no load to size for.
  • Watched like anything whose downtime you would notice, since the one time it matters is when a site is already down. Its status endpoint is for that (the witness’s install guide).
  • Five voters, two sites and two witnesses in different places, keep a quorum through the loss of a site and a witness together. Nothing new is needed for it, only two more voters; the install tooling here sets up three.

A witness run for you by a provider is added to your sites like any other voter. The self-hosted witness stays free and complete: a safe two-site deployment never depends on anyone else’s service (spec §56).

To install one, see the witness, and two sites and a witness for the whole topology.