Skip to main content

ServerConfig

Struct ServerConfig 

Source
pub struct ServerConfig {
Show 42 fields pub bind: SocketAddr, pub journal: PathBuf, pub snapshot: Option<PathBuf>, pub cores: PipelineCores, pub reader_cores: usize, 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_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,repl-sender,event-publisher,shadow,repl-handler-0,repl-handler-1 (comma-separated). Core 0 is reserved for OS/IRQ handling. 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).

§reader_cores: usize

CPU core for the reader thread. In kernel TCP mode this pins the io_uring reader; in DPDK mode it pins the (first) poll thread. The matching stage is the throughput bottleneck — a single io_uring reader with multishot RECV easily multiplexes thousands of connections without becoming the limit.

§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). Sets the replication cursor to u64::MAX so min(journal_cursor, MAX) = journal_cursor. 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_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