pub struct Config {Show 28 fields
pub cluster_name: String,
pub election_timeout_min: u64,
pub election_timeout_max: u64,
pub heartbeat_interval: u64,
pub heartbeat_min_interval: Option<u64>,
pub install_snapshot_timeout: u64,
pub send_snapshot_timeout: u64,
pub max_payload_entries: u64,
pub max_append_entries: Option<u64>,
pub replication_lag_threshold: u64,
pub snapshot_policy: SnapshotPolicy,
pub snapshot_max_chunk_size: u64,
pub max_in_snapshot_log_to_keep: u64,
pub purge_batch_size: u64,
pub api_channel_size: Option<u64>,
pub api_batch_capacity: u64,
pub api_batch_linger_ms: u64,
pub notification_channel_size: Option<u64>,
pub state_machine_channel_size: Option<u64>,
pub log_stage_capacity: Option<u64>,
pub enable_tick: bool,
pub enable_heartbeat: bool,
pub enable_elect: bool,
pub removed_leader_step_down: StepDownPolicy,
pub enable_pre_vote: Option<bool>,
pub backoff: String,
pub allow_log_reversion: Option<bool>,
pub enable_leader_restore: Option<bool>,
}Expand description
Runtime configuration for a Raft node.
Config controls tunable parameters for Raft operation including election timeouts, heartbeat
intervals, replication settings, snapshot policies, and log compaction behavior.
§Usage
Create a configuration, optionally customize fields, validate it, and pass to Raft::new:
use openraft::Config;
use std::sync::Arc;
let config = Config {
cluster_name: "my-cluster".to_string(),
heartbeat_interval: 50,
election_timeout_min: 150,
election_timeout_max: 300,
..Default::default()
};
let config = Arc::new(config.validate()?);
let raft = Raft::new(node_id, config, network, log_store, state_machine).await?;§Timing Constraints
Follow the Raft timing inequality: broadcastTime ≪ electionTimeout ≪ MTBF
Rule of thumb: Set heartbeat_interval ≈ election_timeout / 3 and ensure election timeout
is 10-20× your typical network round-trip time.
§See Also
- Raft specification §5.6 for timing guidance
SnapshotPolicyfor snapshot triggering strategies
Fields§
§cluster_name: StringThe application-specific name of this Raft cluster
election_timeout_min: u64The minimum election timeout in milliseconds
election_timeout_max: u64The maximum election timeout in milliseconds
heartbeat_interval: u64The heartbeat interval in milliseconds at which leaders will send heartbeats to followers
heartbeat_min_interval: Option<u64>The minimum interval in milliseconds between two heartbeats to the same follower.
A successful replication response proves the same liveness facts as a heartbeat response
and also updates the leader lease clock. When a follower has acknowledged an RPC
(replication or heartbeat) that was sent within the last heartbeat_min_interval
milliseconds, the periodic heartbeat to this follower is suppressed, since it would be
redundant. Under sustained writes this eliminates most heartbeat RPCs; heartbeats resume
automatically once replication idles.
It must hold that heartbeat_interval + heartbeat_min_interval < election_timeout_min,
so that suppression can never delay a heartbeat past a follower’s election timeout.
Defaults to 0, meaning heartbeats are always sent at heartbeat_interval.
Since: 0.10.0
install_snapshot_timeout: u64The timeout for sending then installing the last snapshot segment,
in millisecond. It is also used as the timeout for sending a non-last segment if
send_snapshot_timeout is 0.
send_snapshot_timeout: u64Sending snapshot by chunks is deprecated; Use install_snapshot_timeout instead
The timeout for sending a non-last snapshot segment, in milliseconds.
It is disabled by default by setting it to 0.
The timeout for sending every segment is install_snapshot_timeout.
max_payload_entries: u64The maximum number of entries per payload allowed to be transmitted during replication
If this is too low, it will take longer for the nodes to be brought up to consistency with the rest of the cluster.
max_append_entries: Option<u64>The maximum number of log entries per append I/O operation.
When multiple AppendEntries commands are queued, Openraft can merge them into
a single storage write to improve throughput. This setting limits the batch size
to prevent excessively large writes that could cause high storage latency.
This is separate from max_payload_entries which controls network replication payload size.
Storage typically has higher throughput than network, so this value can be larger.
Defaults to 4096.
Since: 0.10.0
replication_lag_threshold: u64The distance behind in log replication a follower must fall before it is considered lagging
- Followers that fall behind this index are replicated with a snapshot.
- Followers that fall within this index are replicated with log entries.
This value should be greater than snapshot_policy.SnapshotPolicy.LogsSinceLast, otherwise transmitting a snapshot may not fix the lagging.
snapshot_policy: SnapshotPolicyThe snapshot policy to use for a Raft node.
snapshot_max_chunk_size: u64The maximum snapshot chunk size allowed when transmitting snapshots (in bytes)
max_in_snapshot_log_to_keep: u64The maximum number of logs to keep that are already included in snapshot.
Logs that are not in a snapshot will never be purged.
purge_batch_size: u64The minimal number of applied logs to purge in a batch.
api_channel_size: Option<u64>The size of the bounded API channel for sending messages to RaftCore.
This controls backpressure for client requests. When the channel is full, new API calls will block until space becomes available.
Since: 0.10.0
api_batch_capacity: u64RaftMsg::ClientWrite batch before it is processed.
Then the batched ClientWrite requests will be submitted to RaftStorage in one shot.
Since: 0.10.0
api_batch_linger_ms: u64Maximum amount of milliseconds to wait for additional client requests before flushing a partially filled batch.
Since: 0.10.0
notification_channel_size: Option<u64>The size of the bounded notification channel for internal events.
This channel carries internal notifications like IO completion, replication progress, and tick events. When full, internal components will block until space is available.
Since: 0.10.0
state_machine_channel_size: Option<u64>The size of the bounded channel for sending commands to the state machine worker.
This channel carries commands like Apply, BuildSnapshot, and InstallSnapshot. When full, RaftCore will block until space becomes available, providing backpressure when the state machine is slow.
Since: 0.10.0
log_stage_capacity: Option<u64>The capacity of the ring buffer used to track lifecycle latency per stage.
Each of the 6 lifecycle stages (proposed, received, submitted, persisted,
committed, applied) maintains a fixed-capacity ring buffer of this size.
Only used when the runtime-stats feature is enabled.
Defaults to 1024 if not specified.
Since: 0.10.0
enable_tick: boolEnable or disable tick.
If ticking is disabled, timeout-based events are all disabled: a follower won’t wake up to enter candidate state, and a leader won’t send heartbeat.
Critical for elections: When false, followers cannot detect leader failures and will
never trigger elections, even with enable_elect = true. The tick mechanism provides the
timing infrastructure that allows followers to detect when election_timeout_max has passed
without receiving heartbeats from the leader.
This flag is mainly used for testing or to build a consensus system that does not depend on wall clock. The value of this config is evaluated as follows:
- being absent: true
--enable-tick: true--enable-tick=true: true--enable-tick=false: false
enable_heartbeat: boolWhether a leader sends heartbeat logs to following nodes, i.e., followers and learners.
enable_elect: boolWhether a follower will enter candidate state if it does not receive any messages from the leader for a while.
When enabled (true), followers automatically trigger elections by entering the Candidate
state when they don’t receive AppendEntries messages (heartbeats) from the leader for
longer than election_timeout_max. This is essential for automatic failover when a leader
becomes unavailable.
When disabled (false), followers will never initiate elections, even if the leader fails.
This setting is primarily for testing or building custom consensus systems.
Important: This setting only works when enable_tick is also true. Elections require
time-based events to detect leader absence.
removed_leader_step_down: StepDownPolicyThe policy for stepping down a Leader that is removed from a committed membership config.
After(ms): when the membership config that removes this Leader is committed andmsmilliseconds have elapsed, the Leader transfers leadership to the most up-to-date voter, then reverts itself to a learner. During the delay it keeps serving as a Leader, so that in-flight requests and the commit notification of the membership log entry can still reach the followers.Never: the removed Leader keeps leading, until the application reverts it manually withTrigger::refresh_server_state().
In CLI it is either a “never” literal (never, no, none, off or false,
case-insensitive) or the number of milliseconds, e.g.,
--removed-leader-step-down=never or --removed-leader-step-down=150.
Defaults to After(150).
Since: 0.10.0
enable_pre_vote: Option<bool>Whether a follower runs a Pre-Vote round before incrementing its term and starting a real election.
When enabled (Some(true)), a follower whose election timer fires first asks peers whether
they would grant it a vote at term + 1, without persisting any vote or bumping its term.
Only after a quorum would grant does it run the real election. This prevents a node that
cannot currently win — e.g. one that was partitioned, restarted, or has a stale log — from
inflating its term and disrupting a healthy leader once it reconnects.
When disabled (Some(false)), a follower increments its term and votes for itself
immediately on election timeout, the historical Openraft behavior. The leader-lease already
rejects such a candidate’s vote requests, so Pre-Vote is an optional refinement rather than
a correctness requirement.
None (the default) leaves the choice to Openraft, which currently treats it as disabled.
Leaving it unset lets a future release change this default without breaking configs that
never opted in.
Pre-Vote uses a separate network RPC
(RaftNetworkV2::pre_vote). A peer whose
network does not implement it is counted as granting the Pre-Vote, so a cluster mid-upgrade
stays live.
Since: 0.10.0
backoff: StringDefault backoff policy used when
RaftNetworkV2::backoff returns None.
The string lists the first few retry delays explicitly. After those, the sequence
continues automatically — smoothly extended from at most the last three explicit
delays by either an exponential k · aˣ + t or linear k · x + t form, whichever
fits the tail. A trailing ..<max> or ...<max> caps every extrapolated delay at
<max> (defaults to 1000ms).
§Syntax
<dur> values separated by , or whitespace; an optional .. or ... before the
last value marks it as the max cap. <dur> is a number with a unit suffix:
ns, us, ms, s, m, h.
§Examples
Doubling from a single anchor — this is the default, "200ms":
200 400 800 1000 1000 1000 … (ms; cap = 1000)Exponential growth, "100ms 200ms 400ms ...5s":
100 200 400 800 1600 3200 5000 5000 … (ms; cap = 5000)Linear growth, "1ms 2ms 3ms ...1500ms" — the tail has constant difference, so the
sequence continues that line until it hits the cap:
1 2 3 4 5 6 … 1499 1500 1500 1500 … (ms; cap = 1500)Constant delay, "500ms 500ms 500ms" — a flat tail stays flat:
500 500 500 500 … (ms)Short warm-up, then extrapolate, "10ms 20ms ...2s" — two anchors imply a doubling
rate, extended automatically:
10 20 40 80 160 320 640 1280 2000 2000 … (ms; cap = 2000)Because only the last few explicit delays shape what follows, you can prepend any number of custom warm-up values without changing the long-run behavior.
Since: 0.10.0
allow_log_reversion: Option<bool>Whether to allow to reset the replication progress to None, when the
follower’s log is found reverted to an early state. Do not enable this in production
unless you know what you are doing.
Although log state reversion is typically seen as a bug, enabling it can be useful for testing or other special scenarios. For instance, in an even number nodes cluster, erasing a node’s data and then rebooting it(log reverts to empty) will not result in data loss.
For one-shot log reversion, use
Raft::trigger().allow_next_revert().
Since: 0.10.0
enable_leader_restore: Option<bool>Whether to allow a restarted leader to restore leadership without a vote.
When enabled (true), if a node that was leader before a restart comes back quickly
enough, before any other node triggers and election, it can continue serving as leader
without re-election. This differs from standard Raft, but can help improve availability
after a leader restart.
When disabled (false), a restarted leader must always trigger a new election to become
leader again.
Important: When this setting is enabled, it can introduce inconsistencies when the following conditions are true:
- The state machine does not flush state to disk before returning from
[
openraft::storage::RaftLogStorage::apply]. - The last committed log id is not persisted.
When the above conditions are met and this setting is enabled, then a leader can restart with a stale state machine and restore itself as leader without any mechanism to detect the staleness.
When the above conditions are met and this setting is disabled, then a restarted leader can learn the current commit log id by participating in a new election or receiving a message from the new leader.
See: docs::data::log_pointers.
Since: 0.10.0
Implementations§
Source§impl Config
impl Config
Sourcepub fn new_rand_election_timeout<RT: AsyncRuntime>(&self) -> u64
pub fn new_rand_election_timeout<RT: AsyncRuntime>(&self) -> u64
Generate a new random election timeout within the configured min and max values.
Sourcepub fn install_snapshot_timeout(&self) -> Duration
pub fn install_snapshot_timeout(&self) -> Duration
Get the timeout for sending and installing the last snapshot segment.
Sourcepub fn send_snapshot_timeout(&self) -> Duration
👎Deprecated since 0.9.0: Sending snapshot by chunks is deprecated; Use install_snapshot_timeout() instead
pub fn send_snapshot_timeout(&self) -> Duration
Sending snapshot by chunks is deprecated; Use install_snapshot_timeout() instead
Get the timeout for sending a non-last snapshot segment.
Sourcepub fn validate(self) -> Result<Config, ConfigError>
pub fn validate(self) -> Result<Config, ConfigError>
Validate the state of this config.
Sourcepub fn build_backoff(&self) -> Backoff ⓘ
pub fn build_backoff(&self) -> Backoff ⓘ
Build a Backoff iterator from the backoff policy string.
Panics if the policy is invalid — callers should obtain Config through Config::build
or Config::validate, which reject invalid policies up-front.
Since: 0.10.0
Source§impl Config
impl Config
Sourcepub fn build(args: &[&str]) -> Result<Config, ConfigError>
pub fn build(args: &[&str]) -> Result<Config, ConfigError>
Build a Config instance from a series of command line arguments.
The first element in args must be the application name.
Only available when the clap feature is enabled (default).
§Examples
use openraft::Config;
let config = Config::build(&[
"myapp",
"--election-timeout-min", "300",
"--election-timeout-max", "500",
])?;Trait Implementations§
Source§impl Args for Config
impl Args for Config
Source§fn augment_args<'b>(__clap_app: Command) -> Command
fn augment_args<'b>(__clap_app: Command) -> Command
Source§fn augment_args_for_update<'b>(__clap_app: Command) -> Command
fn augment_args_for_update<'b>(__clap_app: Command) -> Command
Command so it can instantiate self via
FromArgMatches::update_from_arg_matches_mut Read moreSource§impl CommandFactory for Config
impl CommandFactory for Config
Source§impl<'de> Deserialize<'de> for Config
impl<'de> Deserialize<'de> for Config
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl FromArgMatches for Config
impl FromArgMatches for Config
Source§fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
Source§fn from_arg_matches_mut(
__clap_arg_matches: &mut ArgMatches,
) -> Result<Self, Error>
fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>
Source§fn update_from_arg_matches(
&mut self,
__clap_arg_matches: &ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§fn update_from_arg_matches_mut(
&mut self,
__clap_arg_matches: &mut ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches_mut( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§impl Parser for Config
impl Parser for Config
Source§fn parse_from<I, T>(itr: I) -> Self
fn parse_from<I, T>(itr: I) -> Self
Source§fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
Source§fn update_from<I, T>(&mut self, itr: I)
fn update_from<I, T>(&mut self, itr: I)
Auto Trait Implementations§
impl Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnsafeUnpin for Config
impl UnwindSafe for Config
Blanket Implementations§
impl<T> AppDataResponse for Twhere
T: OptionalFeatures + 'static,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more