One writer, one queue, 63 crates

A single dedicated OS thread owns the execution engine and is the only code that mutates it. Everything else reaches it through one totally-ordered ingest queue — determinism by construction rather than by locking. Underneath sits a library of 63 crates in 18 layers whose dependency direction is not a convention but a build failure.

VIKE TRADER
Rust trading platform · system schematic · 2 sheets
63crates
18layers
14venue bridges
3inbound lanes
1writer thread

01The live core— runtime · one thread · one queue

One dedicated OS thread — vt-core — owns the ExecutionEngine and is the only mutator. Everything reaches it through one totally-ordered ingest queue, so determinism is by construction rather than by locking. The three inbound lanes do not behave alike, and that asymmetry is the design.

INBOUND · THREE LANES · THREE BACK-PRESSURE SEMANTICS THE SINGLE WRITER OUTBOUND · OBSERVER VENUE ADAPTERS 14 × own thread(s) canonical events fills · order updates · account funding · liquidation ① EXEC EVENTS LOSSLESS back-pressures the VENUE thread — never the GUI GUI · CLI · DAEMON place · cancel · flatten ② COMMANDS try_send NEVER BLOCKS REJECTION returned to the caller + counted in the snapshot it can never be silent MARKET FEEDS quotes · bars · book unbounded arrival rate ③ MARKET DATA n ticks in · 1 value out CONFLATION SLOT latest-wins overwrite LATEST-WINS ≤ 1 MARKER IN FLIGHT drops counted → snapshot LANE KEY lossless · blocking send never blocks · try_send rejects, never waits latest-wins · conflated, one marker only ONE TOTALLY-ORDERED INGEST QUEUE pop vt-core SINGLE WRITER · ONE OS THREAD · THE ONLY MUTATOR DISPATCH LOOP for msg in queue { catch_unwind(…) } ExecutionEngine the only mutator of this state ACCOUNT ORDER REGISTRY RISK GATE denies all when halted VENUE CLIENT live or paper DIRTY FLAG · COALESCED PUBLISH the snapshot build never runs per event arc_swap · store(one immutable value) SAFE-STATE entered on ANY panic inside dispatch — TRADING HALTED · risk gate denies all — best-effort CANCEL of working orders — fault SURFACED in the snapshot the core does not die · and does not keep trading ON PANIC publish NOT PRESENT no message bus no shared mutable cache the ONE queue is the design COALESCED PUBLISH CADENCE ≤ ~16 ms WHILE BUSY immediate when the queue goes idle arc_swap CELL one coalesced SNAPSHOT carries counters: rejected · dropped · fault read on repaint GUI · repaint reads whatever is current LOSSY OBSERVER never blocks the core ONE QUEUE · TOTAL ORDER · DETERMINISM BY CONSTRUCTION, NOT BY LOCKING PERIPHERALS — SAME SEAM PAPER EXCHANGE an execution client like any venue the same seam · no special path JOURNAL persistence written from the writer thread RECON DRIVER per-venue · on an interval diffs venue reports vs local state VENUE ADAPTERS ×14 each on its own thread(s) push canonical events into lane ①

◂ drag to pan the drawing ▸

Exec events

venue adapter threads
LOSSLESS

fills, order updates, account, funding, liquidation — nothing is dropped.

Back-pressure → the venue task waits. Never the GUI.

Commands

GUI · CLI · daemon
NEVER BLOCKS

place, cancel, flatten — sent with try_send. A full-queue rejection is returned to the caller and counted in the snapshot.

Back-pressure → refused, loudly. It can never be silent.

Market data

quotes · bars · book
LATEST-WINS

a conflation slot plus a marker message. At most one marker in flight, so a slow core sees the freshest price rather than an unbounded queue.

Back-pressure → overwrite in place. Drops are counted.

Outbound — the lossy observer

~16 ms COALESCED

A dirty flag drives the publish: at least every ~16 ms while busy, immediately when the queue goes idle, into an arc_swap cell the GUI reads on repaint. The snapshot build never runs per event.

Failure path — safe-state

CATCH_UNWIND

Every dispatch runs under catch_unwind. On a panic the core does not die and does not keep trading: trading halts (the risk gate denies every new order), all working orders get a best-effort cancel, and the fault surfaces in the snapshot.

What the absences cost

Ordering is a property of the one queue rather than of a broker, and nothing outside the core mutates core state. That is a trade, not a free win: it buys determinism and a tail a lock cannot spike, and it costs the fan-out a bus would give you — every new observer is another reader of one snapshot, not a new subscriber on a topic.

02The crate ladder— dependency direction, machine-checked

63 crates over 18 layers, highest at the top. Dependency direction is down only — and the same spine runs through it.

Machine-checked, not hand-drawn. Every manifest declares [package.metadata.vike] layer = N, and CI fails a pull request whose non-dev dependency does not declare a strictly lower layer. The ordering below is therefore a verified fact about the tree.
▮ anchor crate ┄ venue adapters · 14 names shown without their vike- prefix
A layer number is a floor, not a rank. It says only that everything a crate depends on declares a strictly lower number. It does not say a crate higher on the spine sits above one lower down — unless one actually depends on the other, their order means nothing. 7 of the 63 crates depend on no vike crate at all, so nothing constrains them from below and their number is a free choice. Of the rest, aster sits at L41 because binance at L40 forces it there — the tightest fit on the sheet, and the reason one bridge is a rung above the others — while report sits 25 layers above core, the highest crate it depends on. Same rule both times, and neither gap means anything.
L90
app
└ the desktop GUI · top of the stack
L80
app-core studio
L75
chart cockpit connections data-manager panels
L70
ui-theme
L68
vike
L65
agent-eval cli datahub recorder tradehub
└ cli — the command line; recorder — the market-data recorder; tradehub — the headless daemon
L62
run
L60
mount
└ arms a venue — or leaves it on paper
L55
ai backfill ops report studio-core
L50
alerting backtest tradehub-client
L41
└ aster — drawn in the venue-bridge box below, with the other 13
L40
user-strategies
Venue bridges — 14 · each on its own thread(s) · the adapters feeding lane ① · 1 at L41
alpaca binance bybit ctrader deribit dukascopy fxcm hyperliquid ibkr ig oanda okx polymarket asterL41
L35
user-research
L30
bridge-core core datahub-client paper script strategy
└ the single-writer runtime
L25
boot
L20
analytics catalog config data exec fills indicators ml mm options orderflow
└ the order ledger and the risk gate
L15
buildinfo log secrets
L10
model
└ the bottom · pure domain types · no I/O

Every dependency points down this spine. The bottom rung is the most depended-upon crate in the tree; the top depends on the most and is depended on by nothing.

The 14 bridges are the same 14 adapter threads feeding lane ① on sheet 01. Layer numbers are declared in each manifest — they are not inferred from the graph.

03The same 63 crates, by what they are

The bands above answer “what may depend on what”. This answers the question a reader actually arrives with — what is this crate. The layer rides on every chip, because that is the half a machine checks.

Role is a human grouping; the number is the machine-checked part. Nothing verifies that chart belongs under Desktop, and nothing verifies the one-line gloss on an anchor crate either. What CI does verify is that every dependency declares a strictly lower number — and that survives whatever grouping you choose.

Domain & primitives

the pure bottom — types, the venue roster, no I/O L10–L25 · 9
modelL10 buildinfoL15 logL15 secretsL15 catalogL20 configL20 fillsL20 optionsL20 bootL25

Engines & analytics

the machinery a strategy is run by L20–L30 · 10
analyticsL20 dataL20 execL20 indicatorsL20 mlL20 mmL20 orderflowL20 paperL30 scriptL30 strategyL30

Runtime

the single-writer core and the shared venue scaffolding L30–L62 · 5
bridge-coreL30 coreL30 datahub-clientL30 mountL60 runL62

Venue bridges

one adapter per venue, each on its own thread L40–L41 · 14
alpacaL40 binanceL40 bybitL40 ctraderL40 deribitL40 dukascopyL40 fxcmL40 hyperliquidL40 ibkrL40 igL40 oandaL40 okxL40 polymarketL40 asterL41

Research & ops

backtesting, reporting, collection, alerting L35–L55 · 10
user-researchL35 user-strategiesL40 alertingL50 backtestL50 tradehub-clientL50 aiL55 backfillL55 opsL55 reportL55 studio-coreL55

Binaries

what actually ships and runs L65–L68 · 6
agent-evalL65 cliL65 datahubL65 recorderL65 tradehubL65 vikeL68

Desktop

the GUI shell and its panels L70–L90 · 9
ui-themeL70 chartL75 cockpitL75 connectionsL75 data-managerL75 panelsL75 app-coreL80 studioL80 appL90

Layers, the bridge flag and each crate’s forcing dependency are read from the workspace manifests, so a crate joins this page by joining the workspace. The roles and the anchor glosses are the hand-made part, and this page says so rather than letting them look derived.

Sheet 01 — live core Sheet 02 — crate ladder Projection: dependency-down Writers: 1

Every venue starts on paper.

Credentials arm a venue; your policy file caps it. Nothing goes live by accident.