Skip to main content

ServerConfig

Struct ServerConfig 

Source
pub struct ServerConfig {
Show 43 fields pub bind: SocketAddr, pub journal: PathBuf, pub snapshot: Option<PathBuf>, pub cores: PipelineCores, pub group_commit_us: u64, pub heartbeat_interval_secs: u64, pub connection_timeout_secs: u64, pub max_connections: u64, pub accounts: u32, pub instruments: u32, pub authorized_keys: PathBuf, pub max_journal_mib: u64, pub journal_writer: JournalWriterMode, pub max_orders_per_account: u32, pub max_orders_per_second: u32, pub max_orders_burst: u32, pub replication_bind: Option<SocketAddr>, pub standalone: bool, pub replica_of: Option<SocketAddr>, pub replication_key: Option<PathBuf>, pub replication_batch_size: usize, pub max_journal_batch: usize, pub replication_heartbeat_secs: u64, pub replication_pipeline_depth: usize, pub replication_ring_size: usize, pub durability_mode: DurabilityMode, pub yield_idle: bool, pub dpdk_eal_args: String, pub dpdk_ports: Vec<u16>, pub dpdk_ip: String, pub dpdk_prefix_len: u8, pub dpdk_gateway: Option<String>, pub dpdk_peer_ip: Option<String>, pub dpdk_gateway_mac: Option<String>, pub dpdk_mtu: usize, pub dpdk_vlan: Option<u16>, pub event_bind: Option<SocketAddr>, pub health_bind: Option<SocketAddr>, pub admin_bind: Option<SocketAddr>, pub snapshot_interval_ms: u64, pub snapshot_path: Option<PathBuf>, pub tick_interval_ms: u64, pub no_mlock: bool,
}
Expand description

Server configuration, parsed from CLI arguments via clap.

Fields§

§bind: SocketAddr

Address to bind the TCP listener.

§journal: PathBuf

Path to the journal file for durable event sourcing.

§snapshot: Option<PathBuf>

Path to a snapshot file for faster recovery.

§cores: PipelineCores

Pipeline core IDs: journal,matching,response,reader,repl-sender,event-publisher,shadow,repl-handler-0,repl-handler-1 (comma-separated). Core 0 is reserved for OS/IRQ handling. reader pins the io_uring reader (TCP) or DPDK poll thread. repl-sender is used when replication is enabled, event-publisher when --event-bind is set, shadow when --snapshot-interval-ms > 0. repl-handler-0/1 are for the per-replica TCP handler threads (0 = unpinned).

§group_commit_us: u64

Group commit coalescing delay in microseconds. Keep at 0 for TCP.

§heartbeat_interval_secs: u64

Heartbeat interval in seconds. The server sends a heartbeat to idle connections after this many seconds of silence. Set to 0 to disable.

§connection_timeout_secs: u64

Connection timeout in seconds. The server disconnects clients that have not sent any data within this window. Set to 0 to disable.

§max_connections: u64

Maximum number of concurrent authenticated connections. New connections are rejected (closed immediately) when this limit is reached. 0 means unlimited. Prevents fd/memory exhaustion (SEC-02).

§accounts: u32

Number of accounts to seed on first startup. Uses the ProvisionAccount event for O(accounts) seeding (~0.5s for 1M).

§instruments: u32

Number of instruments to seed on first startup.

§authorized_keys: PathBuf

Path to the authorized keys file for Ed25519 challenge-response authentication. Every connection must authenticate before trading. Required for primary mode; ignored in replica mode (–replica-of). See AuthorizedKeys for file format.

§max_journal_mib: u64

Maximum journal size in MiB before automatic rotation at startup. When the journal exceeds this threshold, the server saves a snapshot and starts a fresh journal. Set to 0 to disable. Default: 256 MiB.

§journal_writer: JournalWriterMode

Journal writer mode. buffered (default) writes through the page cache and calls fdatasync per batch — honest durability on any drive. sector (EXPERIMENTAL) uses O_DIRECT with sector- aligned writes — lowest latency on enterprise NVMe with capacitor-backed PLP (VWC=0), but silently loses acknowledged writes on power loss without PLP, and shows unresolved ~1 Hz tail latency spikes on some NVMe firmware. Not recommended for production. See docs/journal-writer-modes.md.

§max_orders_per_account: u32

Maximum number of open orders (resting limits + pending stops, across all instruments) per account. New submissions are rejected with ExceedsMaxOpenOrders once an account hits this cap. 0 means unlimited. Bounds the per-account contribution to engine memory (SEC-03). Must be set to the same value on the primary and every replica — the cap shapes Rejected reports, so a mismatch causes replay divergence.

§max_orders_per_second: u32

Per-account sustained order-submission rate (orders/sec). Token bucket refills at this rate; clients exceeding it (after burning the burst) are rejected with ExceedsOrderRate. 0 disables the limiter. Prevents a single client from monopolizing matching throughput (SEC-04). Must match across primary and every replica — same determinism caveat as --max-orders-per-account. Default (1000/s) is a conservative mid-tier ceiling: comfortable for algorithmic and retail flow, but tight for active market-makers who routinely re-quote past 1k/s on liquid instruments. Operators running with significant MM presence should raise this (and the burst) to match their book’s quote-update profile.

§max_orders_burst: u32

Per-account burst capacity (max consecutive orders allowed after a quiet period). Paired with --max-orders-per-second. 0 disables the limiter. Default (5000) lets normal trading bursts through — e.g. a market open or a strategy initialization batch — without false positives, while still capping the absolute spike a single account can produce.

§replication_bind: Option<SocketAddr>

Address to listen for replica connections (enables synchronous replication). Mutually exclusive with --standalone and --replica-of.

§standalone: bool

Disable replication (dev/test mode). The replica quorum cursor stays at its no-replica sentinel (health reports zero replication lag) and the durability policy evaluates against the primary’s journal alone. Mutually exclusive with --replication-bind and --replica-of.

§replica_of: Option<SocketAddr>

Run as a replica connected to the given primary address. In replica mode, the server does not accept client connections. Mutually exclusive with --replication-bind and --standalone.

§replication_key: Option<PathBuf>

Path to the Ed25519 private key for replication authentication. Required in replica mode (--replica-of). The corresponding public key must be listed in the primary’s authorized_keys file with permission replication.

§replication_batch_size: usize

Maximum number of replication ring batches to coalesce into a single TCP write+flush. Higher values reduce syscall overhead but increase per-write latency. Default: 128.

§max_journal_batch: usize

Maximum events per journal fsync batch. Smaller values reduce tail latency (less work per sync), larger values improve throughput (fewer fsyncs). Default: 4096.

§replication_heartbeat_secs: u64

Replication heartbeat interval in seconds. The primary sends a heartbeat to the replica after this many seconds of idle. Used for disconnect detection. Default: 5.

§replication_pipeline_depth: usize

Number of receive batches the replica can have awaiting local journal fsync before the receiver applies backpressure. Must be a power of two. Higher values allow the primary to stay further ahead of the replica’s fsync, which helps when group-commit delay is non-zero. Default: 8.

§replication_ring_size: usize

Number of slots in each replication ring buffer. Must be a power of two. Each slot holds up to 512 KiB. More slots = more buffering before eviction. Default: 256 (128 MiB per ring, 256 MiB dual-repl).

§durability_mode: DurabilityMode

Durability mode that gates client responses. One of:

  • local persisted>=1. Single-node durability; required with --standalone. Dev/staging deployments.
  • hybrid (default) persisted>=1 && in_memory>=2. Primary’s disk plus an in-memory ack from a second node. Single-failure- safe with a brief RAM-only window on the secondary copy. The default — typical live trading deployments. Saves ~50–80 µs per fill vs durably-replicated.
  • durably-replicated persisted>=2. Two durable copies before client ack. Zero RAM-only window; the gate stalls when no replica is connected. Compliance-driven venues.

--standalone requires local. With hybrid or durably-replicated and no connected replica the gate stalls — the correct behaviour for a serious deployment that has lost its replicas. See docs/replication.md for the operational menu.

§yield_idle: bool

Yield to the OS scheduler when pipeline threads are idle instead of busy-spinning. Use on shared machines without isolated cores to avoid starving other processes. Default (no flag) is busy-spin, which gives lowest latency on isolated cores (isolcpus).

§dpdk_eal_args: String

DPDK EAL arguments (space-separated). Example: “-l 0-7 –huge-dir /dev/hugepages”. Passed directly to rte_eal_init. Only used when compiled with –features dpdk.

§dpdk_ports: Vec<u16>

DPDK port IDs (comma-separated). For LACP bonds, pass both VF ports (e.g., “0,1”) so traffic arriving on either bond member is received.

§dpdk_ip: String

IPv4 address for the DPDK interface (e.g., “10.0.0.1”).

§dpdk_prefix_len: u8

IPv4 prefix length for the DPDK interface. Default: 24.

§dpdk_gateway: Option<String>

IPv4 gateway for the DPDK interface (optional, needed for cross-subnet traffic).

§dpdk_peer_ip: Option<String>

Peer IPv4 used for the bifurcated rte_flow steering rule. When set, the DPDK port opens in isolated mode and only IPv4 packets sourced from this address are delivered into DPDK queue 0 — everything else stays with the kernel netdev. Required for L3 setups that share the public NIC with the kernel (SSH, etc.).

§dpdk_gateway_mac: Option<String>

Gateway MAC (aa:bb:cc:dd:ee:ff) seeded into smoltcp for the --dpdk-gateway IP. Required in L3 bifurcated mode because the gateway’s ARP reply would not match the steering rule and would be eaten by the kernel. Source from ip neigh on the host.

§dpdk_mtu: usize

MTU for the DPDK interface. Use 9000 for jumbo frames (6x fewer TCP segments). Requires switch and PF MTU to be set accordingly.

§dpdk_vlan: Option<u16>

VLAN ID for hardware VLAN strip/insert. Required in dedicated NIC mode (dpdk-setup-dedicated.sh) where the kernel doesn’t handle VLAN tags. Not needed for SR-IOV mode (the PF handles VLAN tagging).

§event_bind: Option<SocketAddr>

Address for the output event publisher. Subscribers connect here to receive a real-time stream of all execution events (market data, fills, cancellations). Ed25519 auth required (ReadOnly or above). Omit to disable (ring has 1 consumer — identical to before).

§health_bind: Option<SocketAddr>

Address for the health/liveness TCP endpoint. On connect, returns a one-line status (OK <conns> <journal_seq> <repl_lag>\n) and closes. No auth required. Set to empty string to disable.

§admin_bind: Option<SocketAddr>

TCP address for the operator admin endpoint. Authenticated with operator keys (Ed25519 challenge-response, same as all other admin handshakes). Accepts:

  • PROMOTE\n — replica → primary leadership transition (replica nodes only; rejected with ERR on a primary).
  • ROTATE\n — archive the current journal segment at the next fsync boundary (any node where runtime rotation is enabled).

Unset means no admin endpoint is listening; operators can still rely on the size-driven rotation trigger (--max-journal-mib) without exposing a port.

§snapshot_interval_ms: u64

Interval in milliseconds between automatic shadow snapshots. The shadow stage replays journaled events on a cloned A and saves a consistent snapshot at this cadence — no hot-path stall. Set to 0 to disable shadow snapshots entirely. Default: 3 000 000 ms (50 min).

§snapshot_path: Option<PathBuf>

Path for shadow snapshots. Defaults to the journal path with a .snapshot extension (same as the startup snapshot path).

§tick_interval_ms: u64

Cadence in milliseconds for the engine-internal scheduler tick. The ingress thread (io_uring reader or DPDK poll thread) publishes a JournalEvent::Tick { now_ns } at this interval so time-driven tasks (GTD expiry, volatility halts, session transitions) fire in deterministic, journaled lockstep. There is no separate tick thread on either transport. Set to 0 to disable tick generation entirely (useful for benchmarks that don’t exercise time-driven features).

Defaults to 250 ms. Under load the matching stage advances its scheduler clock at every-event resolution from slot.timestamp_ns (microsecond precision), so the tick is only the safety net for quiet periods. 250 ms keeps quiet-market scheduler firings within a quarter-second of their deadline at a cost of ~4 events/sec of journal traffic.

§no_mlock: bool

Disable mlockall(MCL_CURRENT | MCL_FUTURE) at startup.

By default the server locks all current and future pages into RAM to prevent rare multi-millisecond stalls from page faults or swap activity on the matching hot path. Locking requires CAP_IPC_LOCK (or running as root) and RLIMIT_MEMLOCK raised to a value larger than the process’s RSS — the server raises the rlimit itself, but only succeeds with the capability.

Use --no-mlock for development / containerised runs where the privilege isn’t available; on a bare-metal exchange host leave it on.

Implementations§

Source§

impl ServerConfig

Source

pub fn group_commit_delay(&self) -> Duration

Group commit delay as a Duration.

Source

pub fn heartbeat_interval(&self) -> Option<Duration>

Heartbeat interval as a Duration. Returns None if disabled (0).

Source

pub fn connection_timeout(&self) -> Option<Duration>

Connection timeout as a Duration. Returns None if disabled (0).

Source

pub fn shadow_snapshot_path(&self) -> PathBuf

Snapshot path for the shadow stage. Uses the explicit --snapshot-path if set, otherwise derives from the journal path with .snapshot extension.

Source

pub fn tick_interval(&self) -> Option<Duration>

Tick generator cadence as a Duration. Returns None when the tick thread is disabled (--tick-interval-ms 0).

Trait Implementations§

Source§

impl Args for ServerConfig

Source§

fn group_id() -> Option<Id>

Report the ArgGroup::id for this set of arguments
Source§

fn augment_args<'b>(__clap_app: Command) -> Command

Append to Command so it can instantiate Self via FromArgMatches::from_arg_matches_mut Read more
Source§

fn augment_args_for_update<'b>(__clap_app: Command) -> Command

Append to Command so it can instantiate self via FromArgMatches::update_from_arg_matches_mut Read more
Source§

impl CommandFactory for ServerConfig

Source§

fn command<'b>() -> Command

Build a Command that can instantiate Self. Read more
Source§

fn command_for_update<'b>() -> Command

Build a Command that can update self. Read more
Source§

impl Default for ServerConfig

Delegates to clap so #[arg(default_value...)] is the single source of truth for every default. Used by the bench crate for struct-literal construction with ..ServerConfig::default().

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl FromArgMatches for ServerConfig

Source§

fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>

Instantiate Self from ArgMatches, parsing the arguments as needed. Read more
Source§

fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>

Instantiate Self from ArgMatches, parsing the arguments as needed. Read more
Source§

fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

fn update_from_arg_matches_mut( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

impl Parser for ServerConfig

Source§

fn parse() -> Self

Parse from std::env::args_os(), exit on error.
Source§

fn try_parse() -> Result<Self, Error>

Parse from std::env::args_os(), return Err on error.
Source§

fn parse_from<I, T>(itr: I) -> Self
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Parse from iterator, exit on error.
Source§

fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Parse from iterator, return Err on error.
Source§

fn update_from<I, T>(&mut self, itr: I)
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Update from iterator, exit on error. Read more
Source§

fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Update from iterator, return Err on error.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more