# Dragonboat CheckQuorum: Ensuring Leader Availability in Raft Clusters

> Learn how Dragonboat CheckQuorum prevents split-brain and ensures leader availability in Raft clusters. Discover how it enables faster failover and improves cluster resilience.

- Repository: [lni/dragonboat](https://github.com/lni/dragonboat)
- Tags: internals
- Published: 2026-03-06

---

**CheckQuorum is a Dragonboat Raft feature that forces a leader to voluntarily step down when it loses contact with a majority of nodes, preventing split-brain scenarios and enabling faster failover to improve cluster availability.**

In distributed systems built on the Raft consensus algorithm, maintaining leader availability is critical for processing client requests. Dragonboat, a high-performance Go implementation of Raft, provides the **CheckQuorum** mechanism to automatically monitor quorum connectivity and trigger leader step-down when network partitions isolate the leader from the majority. This self-monitoring capability prevents stale leaders from accepting writes that can never be committed, directly contributing to higher system availability.

## What Is CheckQuorum in Dragonboat?

CheckQuorum is a safety mechanism that allows a Raft leader to periodically verify it can still communicate with a majority of the cluster (the **quorum**). When enabled, the leader checks whether it has received recent communication from enough followers to form a majority. If the leader determines it has lost quorum connectivity, it voluntarily steps down by transitioning to the follower state. This prevents the isolated leader from continuing to accept client requests that cannot be replicated to a majority, thereby avoiding **split-brain** conditions and reducing downtime during network partitions.

## Configuring CheckQuorum in Dragonboat

### Configuration Flag Location

The `CheckQuorum` feature is controlled via the node configuration struct defined in [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go). The boolean flag determines whether the leader performs periodic quorum verification:

```go
// CheckQuorum specifies whether the leader node should periodically check
// non‑leader node status and step down to become a follower node when it no
// longer has the quorum.
CheckQuorum bool

```

*Source: [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go) – lines 71‑74*

### Timing and ElectionRTT

When CheckQuorum is enabled, the check interval is coupled with the election timeout mechanism. The frequency of quorum checks is tied to `ElectionRTT` (the number of message round-trip times that trigger an election timeout):

*Source: [`config/config.go`](https://github.com/lni/dragonboat/blob/main/config/config.go) – lines 88‑90 (comment)*

This design ensures that the leader checks for quorum presence at roughly the same cadence that followers would use to trigger new elections, creating a consistent timing model across the cluster.

### Enabling CheckQuorum in Practice

To activate CheckQuorum when starting a Dragonboat node, set the boolean field in the configuration struct:

```go
import (
    "github.com/lni/dragonboat/v4/config"
)

rc := config.Config{
    ReplicaID:      1,
    ShardID:        100,
    CheckQuorum:    true,        // Enable periodic quorum checks
    ElectionRTT:    10,          // Check interval tied to election timeout
    HeartbeatRTT:   2,
    // ... other configuration fields
}

```

## How Dragonboat Implements CheckQuorum

### Timing the Quorum Check

The Raft engine determines when to perform a quorum check using the `timeForCheckQuorum` method. As noted in the Raft thesis (page 69), the check is performed when an election timeout elapses:

```go
// p69 of the raft thesis mentions that check quorum is performed when an
// election timeout elapses
func (r *raft) timeForCheckQuorum() bool {
    return r.electionTick >= r.electionTimeout
}

```

*Source: [`internal/raft/raft.go`](https://github.com/lni/dragonboat/blob/main/internal/raft/raft.go) – lines 51‑55*

### Leader Tick Processing

During each leader tick, Dragonboat evaluates whether it is time to check quorum status. If the election tick counter reaches the timeout threshold, the leader resets the counter and, if CheckQuorum is enabled, sends a `CheckQuorum` message to itself for processing:

```go
if r.timeForCheckQuorum() {
    r.electionTick = 0
    if r.checkQuorum {
        if err := r.Handle(pb.Message{
            From: r.replicaID,
            Type: pb.CheckQuorum,
        }); err != nil {
            return err
        }
    }
}

```

*Source: [`internal/raft/raft.go`](https://github.com/lni/dragonboat/blob/main/internal/raft/raft.go) – lines 22‑33 (inside `leaderTick`)*

### Message Type Definition

The `CheckQuorum` message type is defined in the protocol buffer types file as a distinct Raft message type:

*Source: [`raftpb/types.go`](https://github.com/lni/dragonboat/blob/main/raftpb/types.go) – line 19 (enum definition) and line 51 (name mapping)*

### Message Handling and Step Down

When the leader processes the `CheckQuorum` message, it executes `handleLeaderCheckQuorum`. This method verifies quorum connectivity via `leaderHasQuorum()`. If the leader no longer maintains contact with a majority of nodes, it logs a warning and voluntarily transitions to the follower state, clearing the leader designation:

```go
func (r *raft) handleLeaderCheckQuorum(m pb.Message) error {
    r.mustBeLeader()
    if !r.leaderHasQuorum() {
        plog.Warningf("%s has lost quorum", r.describe())
        r.becomeFollower(r.term, NoLeader)
    }
    return nil
}

```

*Source: [`internal/raft/raft.go`](https://github.com/lni/dragonboat/blob/main/internal/raft/raft.go) – lines 84‑91*

## Impact on Leader Availability and Cluster Safety

CheckQuorum directly improves leader availability by reducing the time required to detect and recover from leader isolation. The following comparison illustrates the operational differences:

| Situation | Without CheckQuorum | With CheckQuorum |
|-----------|---------------------|------------------|
| **Leader loses quorum** (network partition) | The isolated leader continues accepting writes that cannot be committed, risking data inconsistency and client errors. | The leader detects the loss within one `ElectionRTT` period and steps down, allowing a reachable replica to assume leadership quickly. |
| **Temporary heartbeat pause** | Followers cannot elect a new leader until the original leader's lease expires or times out, potentially causing long unavailability windows. | The periodic quorum check shortens the detection window to roughly the `ElectionRTT` interval, enabling faster failover. |
| **Re-joining after partition** | Risk of conflicting leaders if the old isolated leader never stepped down, requiring complex reconciliation. | The old leader has already transitioned to follower, allowing the re-joined node to synchronize safely without split-brain conflicts. |

By acting as a self-health monitor that couples detection with the election timeout, CheckQuorum ensures that leadership transitions happen within bounded timeframes when network issues occur, maintaining high availability even during partial network failures.

## Summary

- **CheckQuorum** is a Dragonboat configuration flag (`config.Config.CheckQuorum`) that enables leaders to periodically verify connectivity with a majority of the cluster.
- The check is triggered every `ElectionRTT` ticks via `timeForCheckQuorum()` in [`internal/raft/raft.go`](https://github.com/lni/dragonboat/blob/main/internal/raft/raft.go), aligning with Raft thesis recommendations.
- When triggered, the leader sends itself a `CheckQuorum` message; if `leaderHasQuorum()` fails, `handleLeaderCheckQuorum()` calls `becomeFollower()` to step down.
- This mechanism prevents split-brain scenarios by ensuring isolated leaders relinquish authority quickly, allowing healthy replicas to elect a new leader and maintain service availability.

## Frequently Asked Questions

### What happens if CheckQuorum is disabled in Dragonboat?

When `CheckQuorum` is set to `false` (the default in some configurations), a leader that becomes network-partitioned from the majority will continue to accept client requests indefinitely. Since it cannot replicate entries to a quorum, these writes will hang or fail to commit, and the cluster cannot elect a new leader until the partition heals or the leader crashes, significantly degrading availability.

### How does CheckQuorum relate to ElectionRTT?

CheckQuorum uses the `ElectionRTT` configuration parameter to determine the check interval. As implemented in [`internal/raft/raft.go`](https://github.com/lni/dragonboat/blob/main/internal/raft/raft.go), the leader increments an `electionTick` counter each tick; when it reaches `electionTimeout` (derived from `ElectionRTT`), the `timeForCheckQuorum()` function returns true, triggering the quorum verification. This couples the check frequency with the election timeout mechanism described in the Raft thesis.

### Can CheckQuorum cause unnecessary leader changes?

While CheckQuorum can trigger leader step-down during transient network hiccups, this is generally the desired behavior for maintaining consistency. The leader only steps down if `leaderHasQuorum()` returns false, meaning it has not received recent communication from a majority. In stable networks with proper `HeartbeatRTT` and `ElectionRTT` tuning, false positives are rare, and the safety benefits outweigh the minimal risk of unnecessary transitions.

### Does CheckQuorum affect write performance?

CheckQuorum introduces negligible overhead to write performance. The check occurs periodically (every `ElectionRTT`) and involves only in-memory state verification via `leaderHasQuorum()`—no network round-trips are added to the write path. The mechanism primarily consumes a small amount of CPU for the tick counter and message handling, making it suitable for high-throughput workloads requiring strong leader availability guarantees.