Skip to content

Status file

fastmm-live publishes its live state in a memory-mapped file that monitors such as fastmm-top read; fastmm-gateway publishes its own in the same layout (kind 1, the gateway block). Code: include/fastmm/core/status_segment.hpp. Usage: Monitor a session, Run behind a gateway.

Location and lifetime

  • The path is /dev/shm/fastmm-<engine name>.status, where the name is [engine] name; fastmm-live --status <path> chooses another path and --no-status turns it off. A gateway's is /dev/shm/fastmm-<engine name>.gw.status, with the same flags.
  • The writer (fastmm-live's control thread, the gateway's main thread) creates or truncates the file at startup and rewrites the snapshot every 250 ms. The file stays after exit; the last snapshot shows stopped and the final numbers.
  • The engine refreshes the counters and latencies it hands to the control thread every [engine] latency_publish_ms (default 1 s).

Reading it safely

The file holds an 8-byte sequence counter followed by one StatusSnapshot. The writer makes the counter odd, writes the snapshot, then makes it even again. A reader copies the snapshot when the counter is even and unchanged across the copy, and retries otherwise; it never blocks the writer.

  • magic (0x315441545353464D, "MFSSTAT1" little-endian) and version (currently 18) sit at the same offsets in every version. A reader of another version refuses the file: fastmm-top reports <file> was written by a different FastMM build (status segment version <n>, this fastmm-top reads version <m>).
  • The layout is internal (Public API); read it with fastmm-top from the same build.

Snapshot fields

Field Type Meaning
magic, version u64, u32 see above
pid u32 process id of the writer
session_id u64 the journal's session id
started_ns, updated_ns i64 wall-clock start and last publish, ns since the epoch
state u8 0 starting, 1 running, 2 stopping, 3 stopped
dry_run u8 1 in --dry-run
venue_count u8 entries used in venues
kill_reason u8 KillReason of the global kill switch, 0 while it is not set (below)
engine_name, strategy char[32] NUL-terminated
events, book_updates u64 events consumed, book updates applied
orders_sent, cancels_sent, replaces_sent u64 order messages sent
fills u64 executions
risk_rejects, venue_rejects u64 orders refused by the pre-trade checks, by a venue
risk_reject_reasons, venue_reject_reasons 6 x the most frequent RejectReasons, most frequent first; count 0 marks an unused entry
kills, kill_flags, venue_kills u64, u32, u32 global kill switch trips, the current flag word, per-venue kill switch trips
kill_latched u8 1 while a max_loss trip is latched in [engine] kill_file
flatten_state u8 operator flatten: 0 off, 1 working, 2 flat, 3 timed out, 4 stopped (Operating a running session)
flatten_instruments_left u32 instruments in the flatten's scope that still hold a position
flatten_orders u64 reduce-only orders the flatten has sent
kind u8 0 fastmm-live, 1 fastmm-gateway
realized_pnl_raw, unrealized_pnl_raw, fees_raw i64 settlement currency, or [accounting] reporting_currency when it is set; raw fixed point (divide by 1e8)
pnl_carry_raw i64 net PnL of earlier sessions that [risk] max_loss is measured against, from [engine] kill_file
max_loss_raw i64 [risk] max_loss as the engine applies it now (fastmm-ctl limits changes it), 0 when off; a gateway's is gateway.max_loss_raw
quoting_elapsed_ns, quoting_two_sided_ns i64 time since the first order rested, and how much of it had a live order on both sides; both summed over the instruments
param_updates, param_last_seq, param_last_ns, param_last_origin, param_last_source u64, u64, i64, u8, char[40] strategy parameter updates the engine has applied, and the last one: its publisher's sequence number, when it was applied (wall clock), its origin (0 the strategy's publisher, 1 the control socket) and its --source (Confirm a parameter change)
param_control_published, param_control_applied u64, u64 the sequence number of the last update the control socket sent, and of the last of those the engine has applied; equal once nothing is pending
risk_tokens, risk_token_wait_ns, risk_orders_per_sec, risk_burst i64, i64, u32, u32 the [risk] orders_per_sec bucket every account shares: whole tokens left (-1 with the limit off), how long until the next while it is empty, and its rate and burst as the engine applies them now
latency 7 x engine latency intervals, below
venues 8 x venue entry below
underlyings 8 x underlying entry [risk.underlying], in the order of the configuration's base assets: name (char[16], empty for an unused entry), known (u8: 0 while an inverse contract with a position has no mark), net_raw (i64, base units, signed), max_net_raw (i64, the limit applied now, 0 none)
balance_count, balances u32, 32 x balance entry the balance table (Balance check); a gateway's is the account's over every strategy: asset (char[12]), venue (u8, index into venues), account (u8: the venue's account-wide margin), known (u8: the venue has reported it), free_raw, locked_raw, total_raw, equity_raw, maintenance_raw (i64, asset units), as_of_ns (i64, venue time of the last report)
perp_count, perps u32, 32 x perp entry the venues' mark, index and funding per derivative that has reported (Perpetuals); a gateway's is the account's: symbol (char[24]), venue (u8), valued_at_mark (u8: the position is valued at the mark now), mark_stale, funding_stale (u8), mark_raw, index_raw (i64), funding_rate (f64, per interval), funding_interval_ns, next_funding_ns (venue time, 0 continuous), open_interest_raw (contracts), mark_age_ns, funding_age_ns (-1 never) (i64), reports (u64)
quote_count, quotes u32, 256 x quote entry the quote table, one entry per instrument in the table's order (below)
metric_count, metrics u32, 32 x the numbers the strategy publishes with ctx.metric, in the order it first named them
gateway gateway block kind 1 only, zero otherwise (below)

A fastmm-top session is STALE when state is running and updated_ns is more than 3 s old.

Kill flags

Bit Value Meaning
0 0x1 global kill switch: no new orders on any venue
1 + venue id 0x2 (venue 0), 0x4 (venue 1), ... one venue only; venues from id 30 share bit 31

Kill reasons

kill_reason and each venue's kill_reason hold a KillReason, the first reason the flag was set for; the values are listed in Errors and exit codes. fastmm-top shows it as KILLED (<reason>) next to the state and in each venue's kill column.

Latency intervals

Index order of latency, each from the named stamps (Architecture):

Index Interval Stamps
0 decode T0 (socket read) to T1 (decoded)
1 book apply T1 to T2 (book updated on the engine thread)
2 strategy T2 to T3 (hook returned)
3 serialize T3 to T4 (batch handed to the transport)
4 send T4 to T5 (push into the outbound ring; with spin_mode = "adaptive" also the eventfd write that wakes the network thread)
5 tick to trade T0 to T5
6 wire to book T0 to T2

Quote entry

What each side of an instrument asks for, what works there and what is in the way, as the engine published it (core/quote_diag.hpp). Prices and quantities are raw fixed point (divide by 1e8).

Field Type Meaning
symbol char[24] the instrument
instrument, venue u32, u8 its id and its venue's index
position_raw, avg_px_raw, realized_raw, unrealized_raw i64 the position, its average price and PnL, settlement currency
mid_raw i64 the book's mid, 0 without a two-sided book
sides 2 x side entry buy, then sell

Side entry:

Field Type Meaning
desired_px_raw, desired_qty_raw, desired_levels i64, i64, u8 what the last set_quotes asked for: level 0's price, the quantity over every level, the levels; asked even when the engine ignored it
working_px_raw, working_qty_raw, working_orders i64, i64, u16 the best working quote price, the leaves of the side's quotes, how many
account_qty_raw 8 x i64 those leaves by pool account (0 the primary)
block u8 the first obstacle: 0 quoting, 1 not wanted, 2 quoting off, 3 pulled, 4 venue killed, 5 feed lag, 6 backoff, 7 starved, 8 refused, 9 pending (Monitoring)
reason u8 with block 8, the RejectReason of the refusal
block_since_ns i64 when block began (wall clock)
note {reason char[24], budget_raw i64, set_ns i64} the strategy's last ctx.note_quote on the side: its reason, the budget it gave (settlement currency, 0 none) and when

Venue entry

Field Type Meaning
name char[24] [venues.<name>]
md, user, order u8 channel states: 0 down, 1 connecting, 2 live, 3 stale (market data only: a quiet user or order channel is normal and shows as live)
killed, kill_reason u8, u8 this venue's kill switch is engaged, and its KillReason
books_synced, books_total u32 books in sync out of subscribed
md_messages, resyncs u64 market-data messages, book resynchronisations
orders_sent, cancels_sent, replaces_sent, order_events u64 order traffic on this venue
reconnects, rest_errors, rate_limit_cooldowns u64 connection health
clock_offset_ms i64 venue clock minus local clock, ms
orders_10s, orders_1m, orders_1d, weight {window_ms, used, admits, limit} (i64 each) the account's order budget as its connector last published it (ctx.order_budget without the orders still on their way to it): each window's count, what the connector admits (its cap, below the venue's limit; 0 when the window is not known) and the venue's limit. These count requests in a time window, not open orders
budget_known, budget_paused u8, u8 the connector has published a budget; the venue asked for a pause (429, -1003) or REST is stopped (418)
refused_weight, refused_orders_10s, refused_orders_1m, refused_orders_1d, refused_paused u64 orders and replaces the connector's own limiter refused (VenueRateLimit, never sent), by the limit that refused them
fill_audits, fill_audit_failures u64 fill audits done, and not done (a side could not be read) (Fill audit)
fill_audit_missing, fill_audit_phantom, fill_audit_mismatched, fill_audit_duplicates u64 executions the venue has and the engine never booked, the engine booked and the venue does not have, that differ, that the store holds twice; each counted once
wire_tick_to_trade {count, p50_ns, p99_ns, p999_ns, max_ns} socket read to order write on the network thread (the return of the write that carried the order; one write per drain of the outbound ring)
wire_tick_to_trade_1m, wire_tick_to_trade_1h {count, p50_ns, p99_ns, p999_ns, max_ns} the same over the last minute (60 to 70 s) and the last hour (60 to 70 min)
feed feed entry multicast venues only (below); state 0 for the others

Multicast feed

The feed entry of a nasdaq_itch venue (Venue connectors); counters are cumulative for the session.

Field Type Meaning
state u8 0 none (not a multicast venue), 1 down, 2 snapshot (buffering while a GLIMPSE snapshot is taken), 3 live, 4 lost
backend, xdp_mode u8, u8 0 kernel, 1 af_xdp, 2 dpdk; the attach mode: 1 zerocopy, 2 native_copy, 3 generic
packets, bytes u64 MoldUDP64 packets accepted on every line, datagram payload bytes
line_packets, line_duplicates 2 x u64 per line A, B: packets, copies that arrived after the first copy
line_skew_mean_ns, line_skew_max_ns 2 x i64 per line: delay of a duplicate behind the first copy, ns
gaps, recovered, unrecovered u64 gaps declared, messages delivered from re-requests, sequences given up
snapshot_recoveries, recovery_overflows u64 GLIMPSE snapshots after the first, recovery buffer overflows
reorder_high_water, requests u64 most packets held ahead of a gap, re-request packets sent
malformed, book_errors u64 datagrams that are not MoldUDP64 packets (and bad frames on af_xdp and dpdk), L3 book inconsistencies
kernel_to_t0 {count, p50_ns, p99_ns, p999_ns, max_ns} kernel receive timestamp to T0 while live (kernel backend)
xdp_rx_dropped, xdp_rx_invalid_descs, xdp_rx_ring_full, xdp_fill_ring_empty u64 XDP_STATISTICS summed over the sockets; on dpdk, xdp_rx_dropped is the port's imissed plus rx_nombuf
xdp_fallback u64 subscribed datagrams passed to the kernel because their RX queue has no socket

Gateway block

A gateway (kind 1) fills the header (pid, times, state, dry_run, engine_name, venue_count, venues), kill_flags (bit 0 while the account is killed), kill_reason, kill_latched (the kill file records the trip, which needs [gateway] max_loss), and realized_pnl_raw, unrealized_pnl_raw, fees_raw, pnl_carry_raw with the account's. The engine counters and latencies stay zero.

Field Type Meaning
attachment_count, position_count u32, u32 entries used below
kill_active u8 the account's kill switch is tripped
net_pnl_raw, gross_raw, net_raw i64 the account's net PnL (carried + realized + unrealized − fees), gross and net exposure
trip_net_raw i64 the net PnL when it tripped
max_loss_raw, max_gross_raw, max_net_raw, max_open_notional_raw i64 [gateway] limits, 0 off
venues 8 x routing entry per venue: md_discarded, order_discarded, unrouted, gateway_cancels, untracked, stale_replays, account_skipped, account_md_lost (u64), refused (11 x u64), and the account on that venue: realized_raw, unrealized_raw, fees_raw, gross_raw, net_raw
attachments 16 x attachment engine (char[32]), pid, id (u32), epoch (u16), blocks (u8: its engine sleeps when idle), attached_ns (i64), md_dropped (u64: market data its rings dropped), refused (11 x u64), instruments (4 x u64: bit i set when it trades positions[i])
positions 256 x position one per instrument of the gateway's table: symbol (char[24]), venue (u8, index into venues), shared (u8, [gateway.shared]), owner_epoch (u16, the one attachment that trades it; 0 for none, and always for a shared one), traders (u16, attachments trading it), qty_raw (i64, the account's), unattributed_raw and unexplained_raw (i64, a shared one's: see Shared instruments)
underlyings 8 x underlying entry [gateway.underlying]: the account's net position per base asset over every venue, as the snapshot's underlyings

refused counts in the order GatewayNotOwner, GatewayAccountKilled, GatewayOpenNotional, GatewayGrossNotional, GatewayNetNotional, GatewayRateLimit, GatewayFxRateUnknown, GatewayUnderlyingNet, GatewayUnderlyingMarkUnknown, GatewaySelfTrade, GatewayBalanceShort (Reject reasons).

fastmm-top --json prints the snapshot as one JSON object, with states, kill reasons and latency intervals by name (Command lines); scripts/bench-e2e.sh reads it.