← All Articles

System design guide · NexusTrade case study

How to Design an Algorithmic Trading System

Start with the smallest trading loop that can place one correct order. Then evolve it from a junior-level MVP into a small production system and finally into a fault-tolerant platform built for bursty research, live execution, and real brokerage side effects.

By Austin Starks Junior → mid-level → senior 45-minute answer plan Interactive current architecture
Explore the system map ↓

Section 1 · Final design and TL;DR

Start with the current platform design

Here is the finished design first. Online requests, background jobs, market data, research, and live execution can scale and fail independently. Durable state connects them. Order intent is recorded before a broker call, and every broker response is reconciled afterward.

Start with a guided path, then select a node when you want the deeper explanation. The sections below rebuild this platform from one process to the production design. You can also follow the consumer path in NexusTrade, then inspect the public contract in the developer portal. The production implementation is proprietary.

Interactive system map · 19 technical dossiers

Follow one real path through the platform

Choose a path for the full flow, then select any node for its role and boundary.

Full map view. Choose a path or component to open its technical dossier.
Interactive NexusTrade platform architecture Clickable services, data stores, content delivery networks, execution fleets, market-data providers, and brokerages. Edge and online request path Asynchronous work and durable state Elastic execution and external systems Optional asset fetch approval + risk inside execution roles Users + APIs browser · REST · WebSocket PUBLIC EDGE Cloudflare eligible HTML cache INGRESS Fly Proxy Anycast · health routing ONLINE TIER nexustrade-web React · Express · native WS stateless browser boundary PUBLIC ASSETS DO Spaces CDN media · logos · downloads MongoDB system of record · job ownership Redis cache sessions · hot data ASYNC BOUNDARY Work + event bus Redis · BullMQ DURABLE WORK nexustrade-workers agents · orders · pipelines NexusGenAI prompts · model gateway ISOLATED COMPUTE Agent sandboxes Run Compute · tools ELASTIC RUST Research compute Rust backtests · optimization Semantic search Postgres · pgvector Historical lake Parquet · Tigris Analytical SQL DuckDB · MotherDuck Data providers market · filings · news EPHEMERAL JOBS Data refresh jobs short-lived Fly machines CONTROLLED EXECUTION Rust live trading three userId shards Brokerages Alpaca · TradeStation · Public · Tradier
deployed service event or execution role persistent data edge or CDN
Junior · prove correctness

One explicit loop

Design
One process, one durable store, and one broker adapter.
Cost shape
One small always-on process and a paper account.
Upgrade when
Long jobs block live work, concurrent users collide, or a restart loses in-flight ownership.
Mid-level · separate workloads

Small production service

Design
Stateless web, durable workers, Redis delivery, bounded data jobs, and separate backtest and live roles.
Cost shape
Warm online capacity plus ephemeral data and research jobs.
Upgrade when
Synchronized events burst, optimizer runtimes skew, or one live process can no longer own every account safely.
Senior · control ownership

Fault-tolerant platform

Design
Sharded live execution, recoverable ownership, immutable data publication, backpressure, and reconciliation.
Cost shape
Reserved live capacity; burst research scales independently and can return to zero.
Correctness test
Every user has one live owner, stale work cannot commit, and every external side effect is reconciled.
Static index of all 19 component boundaries
Component Owns Failure and recovery boundary
Users and API clients Authenticated browser, REST, MCP, SDK, and WebSocket intent. Reconnect and reread durable product state after transport loss.
Cloudflare Public DNS, TLS, and eligible HTML edge caching. Private traffic always continues to origin; authenticated HTML comes from current application state.
Fly Proxy Anycast ingress and health-aware web-machine routing. Removes unhealthy machines; product truth remains outside the proxy.
nexustrade-web React, Express, authentication, REST, SDK, MCP, and browser WebSockets. A different stateless machine resumes from MongoDB and job state.
DigitalOcean Spaces CDN Public images, audio, logos, and downloads referenced by explicit URLs. Asset failure leaves the application request path independent.
MongoDB Users, portfolios, strategies, agents, orders, approvals, and recoverable job ownership. Expired leases are reclaimed from the last persisted lifecycle state.
Redis cache Sessions and explicitly cached hot derived reads. Loss increases latency; owning durable records remain authoritative.
Work and event delivery Durable background jobs, live progress updates, and request/reply channels. NexusTrade uses BullMQ and Redis Pub/Sub. Missed events recover from durable state; timed-out RPCs remain unresolved.
nexustrade-workers Agent, order, pipeline, compute, and notification loops in one deployment. Leases, retry metadata, and reconciliation recover bounded work.
NexusGenAI Versioned prompts and model access. Model failures remain bounded step failures; NexusTrade retains tool authority.
Agent sandboxes Isolated external computation with scoped data access. Durable waiting state survives expiration or machine cleanup.
Research compute Independent backtest and optimizer workers sharing the same deterministic strategy rules. NexusTrade implements these workers in Rust. Each worker reserves durable work for a limited time and persists its result. NexusTrade stores that lease and job state in MongoDB, while brokerage credentials stay confined to live execution.
Semantic search User-scoped retrieval across source passages and agent memory. NexusTrade combines Postgres full-text search with pgvector similarity. An empty retrieval result leaves MongoDB product state unchanged.
Historical object lake Immutable, versioned market-data files. NexusTrade stores Parquet generations in Tigris behind a published manifest. A failed upload leaves the current generation readable.
Analytical SQL mirror A query-optimized copy for end-of-day screening. NexusTrade uses DuckDB-compatible SQL through MotherDuck. A failed refresh leaves the previous complete analytical table readable.
Data providers External prices, options, filings, fundamentals, and news. Coverage failures are quarantined before publication or execution.
Bounded data refresh jobs One scheduled dataset operation per short-lived compute instance. NexusTrade launches a Fly Machine for each job. Failure is isolated from web and leaves the prior manifest active.
Rust live-trading shards Deterministic deployed-strategy evaluation across three userId shards. Lifecycle commands route to the owning shard and time out explicitly.
Brokerages External account truth, accepted order IDs, statuses, and fills. NexusTrade reconciles venue truth before replaying uncertain effects.

The main design rule is one owner per responsibility. The web tier owns online requests. Workers own durable asynchronous orchestration. Rust owns deterministic strategy execution. MongoDB owns product state, and Tigris owns the streaming research lake. Brokerage access is confined to controlled order workers, brokerage adapters, and the live strategy runtime.

Interview mode

Build the answer in 45 minutes

The diagrams below are the answer. This clock shows when to draw each layer, when to estimate load, and when to stop adding boxes.

Scope Users, assets, cadence, paper or live, and broker authority.
Requirements Correct orders, durable history, latency, safety, and recovery.
Draw the MVP One loop from observation through decision, intent, and fill.
Separate load Online requests, workers, research, data, and live execution.
Test failure Retries, stale data, broker ambiguity, shard loss, and backpressure.
Defend choices State each tradeoff, consequence, and measurable upgrade trigger.
Incomplete answer to the same prompt

Draw only the happy path

Read pricesRun strategySend orderUpdate portfolio

It describes the trading workflow, but an ambiguous broker timeout can duplicate an order because durable intent, approval, stable order identity, and reconciliation remain undefined.

Interview-ready answer to the same prompt

Add the correctness contracts

Pin snapshotEvaluatePersist intentRisk + approvalSubmitReconcile

The same flow now pins its market-data version, records intent before the broker call, submits with a stable client order ID, and reconciles acknowledgements, fills, and unknown outcomes.

Interview tradeoff = context → choice → reason → consequence → upgrade trigger

Junior-level interview · MVP

Build one correct loop

Start with a trading bot that can survive one order

Start smaller than most candidates expect. One process is enough if it can read current prices, evaluate one strategy, record an order intent, check risk, submit through one broker, and reconcile the result.

Goal Complete one auditable decision and order cycle.
Hard constraint Paper trading first; one stable identity per order intent.
Upgrade trigger Concurrent users or long jobs begin competing with the loop.

Functional requirements

Functional requirements define what the system must do. For this MVP, the required behaviors are market-data ingestion, strategy evaluation, portfolio accounting, risk validation, brokerage submission, and fill reconciliation.

Market and strategy

  • Read prices for a defined universe and interval.
  • Evaluate deterministic entry, exit, and sizing rules.
  • Track cash, positions, and open orders.
  • Backtest the same strategy contract on historical data.

Orders and control

  • Create a durable order intent before submission.
  • Check freshness, buying power, position limits, and duplicates.
  • Submit, cancel, and inspect one brokerage order.
  • Record acknowledgement, rejection, fill, and error state.

Non-functional requirements

Non-functional requirements define how safely and predictably those behaviors operate. A trading system needs deterministic decisions, stable order identity, an audit trail, safe handling of uncertain broker outcomes, and restart recovery.

Requirement MVP target Why it matters
Correctness The same input snapshot produces the same strategy decision. Testing and debugging require reproducible behavior.
Idempotency One decision produces one stable client order identity. Every retry reuses that identity.
Auditability Persist the observation, decision, risk result, request, and broker response. Financial side effects need an explainable history.
Safety Default to paper trading and fail closed on stale or uncertain state. Unknown outcomes remain unresolved until reconciliation.
Recoverability Restart from durable portfolio and order state. Durable state preserves ownership and fills across restarts.
Junior-level MVP: one explicit decision loop Select any node to practice the responsibility, tradeoff, and failure answer
Minimum viable algorithmic trading system A scheduler reads market data, evaluates a strategy, checks risk, persists order intent, submits through a broker adapter, and reconciles the result into portfolio state. Clock + market data poll current observation Strategy condition → action Risk + intent validate, size, persist Broker adapter submit with client id Paper or live broker ack · reject · fill Local durable state portfolio + orders + audit RECONCILE EXTERNAL TRUTH BEFORE THE NEXT LOOP

The MVP can be one TypeScript process and one local database. It still needs stable order identities and a brokerage reconciliation step because network ambiguity exists before scale does.

Implementation evidence The original Live-Trader loop Interactive source walkthrough and the contracts it established
One controller owned the complete loop TypeScript · one controller per user · one brokerage instance · 2 second sleep after each completed loop
Inspect the preserved controller source
Architecture pseudocode

The controller serialized one paper-trading loop

initialize portfolios, price map, and brokerage
while development mode or the market is open:  portfolios = find updated active paper portfolios
  update prices(portfolios)  for each portfolio:
    pending = load unacknowledged orders(portfolio)
    for each strategy in portfolio.getStrategies():      pending = await buy flow(portfolio, strategy, pending)
      pending = await sell flow(portfolio, strategy, pending)
      await strategy.save()  await update unfilled orders, positions, and filled orders  await update portfolio history
  await sleep(2 seconds)
Runtime path

What the controller did in each iteration

Select a numbered step to match the runtime action to the preserved source.

1Initialize the user controller
2Reload active paper portfolios and prices
3Load pending orders and portfolio-owned strategies
4Await the buy and sell flows
5Update unfilled orders, positions, and fills
6Update history, finish the loop, then sleep
Source behavior · loop ownership

The next iteration waited

run() awaited runLoop(), then awaited the two-second sleep. The public source does not show overlapping loop iterations.

Source behavior · portfolio scope

Strategies came from the portfolio

Each iteration called portfolio.getStrategies() before executing buy and sell flows. The source keeps strategy evaluation inside the owning portfolio loop.

Source behavior · state refresh

Broker and portfolio state were refreshed

After evaluation, the controller updated paper and real orders, position values, filled orders, and portfolio history before completing the iteration.

Then

One polling process

Now: deterministic Rust live-trading shards own users.

Then

Direct brokerage submission

Now: the current system separates durable intent, approval, adapter submission, and reconciliation.

Then

portfolio.strategies

Now: one user and every portfolio they own route to the same Rust live-trading shard.

Then

updateFilledOrders()

Now: reconciliation is a first-class external truth boundary.

Repository boundary: the public NextTrade implementation supports the predecessor description above. The current NexusTrade platform is proprietary, so current behavior in this article is limited to public product contracts and implementation facts verified in the local source tree.

Junior interview signal: draw one complete loop before adding distributed infrastructure. State that the first release uses paper trading, assigns one stable client order ID per intent, and reconciles an ambiguous broker timeout before any retry.

Mid-level interview · Small production scale

Separate by responsibility

Preserve the decision loop as the bot becomes a service

The one-process bot works until web requests, data refreshes, backtests, and live evaluation compete for the same resources. Move slow work out of the request path, persist it, and let each workload recover independently.

Goal Return online requests quickly while durable work continues.
Hard constraint Caches and delivery channels can disappear without losing truth.
Upgrade trigger Bursts, runtime skew, or account ownership exceed one service.
Mid-level design: a small production trading platform Select any node to practice its ownership and failure boundary
Small-scale algorithmic trading platform Users reach Cloudflare, Fly Proxy, and stateless web. Web uses MongoDB and Redis. Workers consume durable work, launch hydration jobs, and coordinate separate backtest and live-trading services using separate market-data stores. ONLINE REQUEST PATH Users browser · SDK Cloudflare TLS · public HTML cache Fly Proxy health-aware ingress Stateless web React · API · WebSocket Object CDN images · audio · downloads MongoDB product + job state Redis cache · Pub/Sub · jobs ASYNCHRONOUS WORK AND MARKET DATA Workers orders · pipelines · alerts Hydration cron bounded provider jobs Historical lake versioned market data Analytical mirror screening · SQL Backtesting historical · no broker access Live trading current state · broker RPC Broker adapters account · order · fill SHARED STRATEGY SEMANTICS · SEPARATE CREDENTIAL BOUNDARIES

Cloudflare fronts Fly Proxy and the web tier. The object CDN is a separate optional asset path. Historical backtesting reads durable market data, while live trading owns the controlled brokerage path.

Decision walkthrough Open the small-production design decisions Edge routing, workers, caching, data boundaries, and bounded jobs

CDN, proxy, and stateless web

Cloudflare terminates the public edge and can satisfy eligible public HTML. Dynamic API and WebSocket traffic continues through Fly Proxy to a healthy web machine. DigitalOcean Spaces serves explicit media URLs such as article images, audio, logos, and downloads. Normal authenticated application traffic follows the Cloudflare, Fly Proxy, and web path.

The web tier authenticates, validates requests, writes durable state, and returns quickly. It avoids owning long-running research or order loops, so another machine can handle the next request after a restart.

Workers, Redis, and caching

Long-running workers keep slow or retryable work out of the web request. NexusTrade runs several bounded loops in one worker deployment. A loop becomes its own service only when its CPU, latency, or failure profile requires separate capacity.

Layer Cache or transport Correctness boundary
Cloudflare Eligible public HTML at the edge Authenticated HTML and API responses continue to origin.
Redis cache Sessions and explicitly cached hot derived reads MongoDB and published datasets remain authoritative.
Redis Pub/Sub Low-latency progress and cross-web fan-out Clients recover missed progress from durable state.
In-process cache Hot parsed market columns and strategy inputs The cache key includes the published dataset version.

Separate market data by access pattern

One database should not serve every access pattern. Product state needs small transactional reads. Backtests need wide historical scans. Screening and semantic retrieval need different indexes. NexusTrade fills those roles with MongoDB, Parquet in Tigris, MotherDuck, Postgres with pgvector, and Redis. Those products are examples; the design decision is to isolate workloads with different consistency and query requirements. The backtest corpus exposes the research-data boundary, while the Backtest Explorer consumes a pinned published generation through a read contract.

Publish data in bounded cron jobs

A refresh should be cheap to retry and impossible to publish halfway. The scheduler gives each bounded dataset job its own short-lived machine. NexusTrade uses a Fly Machine. The job moves the manifest only after the new version passes validation, so a failure leaves the previous complete version active.

Mid-level interview signal: trace one job from request acceptance to durable reservation, execution, result publication, and replay after a worker dies. Then explain how the same flow degrades when Redis or a data provider disappears. Compare that separation with the product's live-trading workflow, where execution remains distinct from research.

Senior-level interview · Large scale

Partition ownership and burst capacity

Give each workload its own scaling policy

At scale, the workloads stop looking alike. Web traffic is fairly steady. Data arrives in bursts. An optimization can launch thousands of backtests and then sit idle. Live trading still needs one owner per user, and adding machines does not increase brokerage API quotas.

Goal Scale online, research, data, and live execution independently.
Hard constraint One live owner per user; every external effect is reconciled.
Upgrade trigger Measured load or recovery targets exceed the current partition.

Back-of-the-envelope interview assumptions

Workload Illustrative load Verified implementation and design response
Minute bars
Interview assumption
At 5,000 instruments, each minute closes 5,000 bars: 1.95 million per session and 83 events per second on average. Provider batches sharpen the boundary burst, while concurrent backtests request overlapping historical slices. Publish one immutable columnar snapshot, then reuse decoded market columns from a memory-bounded least-recently-used cache. NexusTrade stores the snapshot as Parquet and implements the cache as UnifiedColumnarLru. Its key includes the dataset, partition, time range, selected columns, and symbol filter.
Strategy evaluation hot path
Interview assumption
At 100,000 portfolios, 5 ms per evaluation requires 500 CPU seconds per cycle. Recursive condition trees, repeated enum dispatch, asset hashing, and rebuilding equivalent indicator state multiply that cost before another machine helps. CompiledCondition and CompiledIndicator flatten trees into stack-machine programs; CachedIndicatorMap stores dense per-asset state. Profile release builds with cargo flamegraph, DTrace plus Inferno, or perf. Benchmark the widest frames, then partition the remaining work.
Optimization
Interview assumption
A 10,000-candidate sweep produces thousands of backtest work items inside one durable optimizer job. Candidate runtimes vary, so stragglers determine tail latency and heavy candidates may exhaust memory before CPU. If a worker disappears, the unfinished part of the sweep may need to run again. Let one worker reserve the optimizer job with an expiring lease, then reject writes from any older owner. NexusTrade stores the lease, ownership generation, and reservation token in MongoDB. A bounded Rust pool separates light and heavy candidates, while short-lived Fly Machines add capacity as demand grows. Dead worker reservations can be requeued up to three times. Live trading keeps separate capacity.
Persisted live events
Measured event shape plus capacity model
A live evaluation produces a small event set rather than one generic update. In a 48-hour sample of seven active constant-frequency RebalanceOption portfolios, a normal event-bearing second persisted three rows per portfolio. The median and 95th percentile were both three. Order activity briefly raised one live portfolio to 14 rows in a second. The five paper and two live-brokerage portfolios averaged 18.4 to 20.1 rows per event-bearing minute because Constant mode evaluated several times per minute. This supplies a concrete per-evaluation event shape for capacity planning. Show both planning rates. At the target cadence of one evaluation per wall-clock minute, 100,000 portfolios create 300,000 rows per minute, or 5,000 per second. Scaling the observed Constant-mode rate linearly produces 1.84 to 2.01 million rows per minute, or about 30,700 to 33,500 per second. Constant mode is a stress profile rather than the target once-per-minute rebalance cadence. Stagger evaluation clocks, partition ingestion and export, and keep browser projection outside the trading loop.
Broker submission
Current product contract
Strategy evaluation can create many order intents, while a live order still requires durable approval before any broker call. Unapproved orders wait in PendingUserApproval, so throughput depends on human review as well as venue quotas. Persist intent first and collect one explicit user approval per order or rebalance unit. A current portfolio policy can approve eligible actions after owner authorization and current consent, within its daily trade-action cap. Stable client IDs, per-account limits, and reconciliation protect the final broker boundary.

The 5,000-instrument, 100,000-portfolio, and 10,000-candidate figures are system-design capacity targets. The per-evaluation event shape was measured from anonymous persisted metadata between August 27 and August 29, 2026. Named classes and batching constants come from the current NexusTrade implementation; the larger workload shows how to turn those measurements into partition counts and scaling decisions.

Two planning rates, one measured event shape Target cadence sizes the baseline; Constant mode sizes stress headroom
5,000 rows/second 100,000 portfolios at one evaluation per minute
30,700–33,500 rows/second Observed Constant-mode rate, scaled linearly

Production target cadence

A normal evaluation persisted three typed rows: market context, option-close evaluation, and the decision outcome. Normalized to one wall-clock evaluation per minute, each portfolio contributes three events per minute. At 100,000 portfolios, the design target is 300,000 durable events per minute plus burst headroom.

Observed stress reference

Measured18.4 to 20.1 rows per event-bearing minute
CauseConstant mode runs several evaluations per minute
Scaled1.84 to 2.01 million rows per minute at 100,000
DesignPartition and backpressure for the faster profile
3 persisted events/evaluation Median and p95 in the measured event-bearing seconds
5,000 rows/second Target once-per-minute portfolio cadence
30.7k–33.5k rows/second Constant-mode reference, not a 100,000-book measurement
Senior-level design: elastic research and sharded execution Select a node to practice the scaling decision and its recovery control
Large-scale algorithmic trading system A control plane persists work, elastic research workers reserve durable jobs and can scale to zero, data pipelines publish immutable historical snapshots, and user-sharded live-trading services submit through rate-limited brokerage adapters. CONTROL PLANE Stateless web auth · API · WebSocket Workers orchestrate · lease · recover Durable job ownership leases stored in MongoDB Redis delivery cache · Pub/Sub · RPC ELASTIC RESEARCH PLANE Backtest fleet 0..N job workers Optimizer fleet 0..N candidate workers Versioned data lake Parquet · published manifest Warm columnar cache version-aware reuse CONTROLLED LIVE EXECUTION PLANE Live shard 0 stableHash(userId) % 3 Live shard 1 single owner per user Live shard 2 deterministic routing Risk + approval authority gate Brokers rate-limited truth RESEARCH SCALES WITH CPU DEMAND · LIVE EXECUTION SCALES WITH OWNERSHIP AND VENUE LIMITS

The current source defines independent Rust backtest and optimizer roles that reserve durable jobs stored in MongoDB. The checked-in Fly configuration defines three live-trading shards, and the routing code maps each user to one shard.

Senior deep dive Throughput, sharding, and market-state decisions Elastic research, single-owner live execution, recovery, and exchange controls Worked shard example ↓

High-throughput backtesting decisions

Follow one 10,000-candidate optimization sweep Select any stage to practice the throughput decision and its recovery control
High-throughput backtesting pipeline A parameter sweep becomes durable candidate jobs. Elastic research workers reuse one historical data version, decoded columns, and compiled strategy programs, then persist evidence without gaining access to brokerage credentials. CONTROL PLANE Parameter sweep 10,000 candidates · one request Optimizer job ownership · progress · budget Candidate jobs light lane · heavy lane · retries Research workers 0 → N machines · bounded pools HOT DATA AND EXECUTION PATH Historical snapshots Parquet · one published version Byte-bounded cache decoded columns · LRU eviction Compiled strategy conditions · indicators · dense state Research evidence statistics · events · portfolio draft AUTHORITY BOUNDARY Research can produce evidence and drafts Broker credentials remain in live execution

The online request creates one durable optimization job and returns. Workers reserve bounded candidate work, reuse one immutable data generation and compiled strategy semantics, then persist evidence. The optimization workspace exposes this lifecycle without giving research workers brokerage authority.

Sharding live trading

Live execution needs one answer to a basic question: which process is allowed to evaluate this user's portfolios? A stable routing function turns the same user ID into the same number on every service. Modulo then reduces that number to one valid shard. NexusTrade uses FNV-1a-64 as the stable routing function.

The checked-in live-trading shard count is 3. Three shards have ordinals 0, 1, and 2, so any user must map to exactly one of those three values.

ownerShard = stableHash(lowercase userId) % shardCount NexusTrade stableHash example: FNV-1a-64
1 · Stable identity 64b8f0a1c2d3e4f506172839

Every portfolio owned by this user starts with the same canonical MongoDB ObjectId.

2 · Stable hash 0x223133841e9e8821

The same ID produces the same number in every service. NexusTrade pins this FNV-1a result in TypeScript and Rust tests.

3 · Reduce to range hash % 3 = 2

Modulo guarantees an ordinal inside the range 0 through 2.

4 · Route and own Shard 2

Node publishes user commands to the shard 2 channel. Rust shard 2 accepts the user and evaluates every owned portfolio.

Shard 0 Non-owner. It skips the portfolios.
Shard 1 Non-owner. It skips the portfolios.
Shard 2 · owner Holds this user's portfolios, live caches, broker streams, and control-plane RPCs.
Why hash?

The same ID always produces the same owner while distributing many users across the available machines.

Why modulo at this scale?

Three fixed ordinals make the routing function small enough to reproduce byte-for-byte in TypeScript and Rust. Membership changes are rare and scheduled while markets are closed.

Why shard by user?

All portfolios and broker state for one account stay together, preventing competing processes from evaluating the same owner.

Why no hash ring yet?

Consistent hashing with virtual nodes reduces remapping when membership changes. At three long-lived shards it also adds a versioned ring, vnode placement, and a cross-language transfer protocol without improving steady-state routing.

Changing the divisor changes ownership. The example user maps to shard 2 when N = 3. The same user maps to shard 1 when N = 4. Node and every Rust machine must change the shard count together during a market-closed operation, and every ordinal must have exactly one running owner. A count mismatch can send a command to a process that rejects ownership for the user's portfolios.

Single-owner shard continuity

The current design favors duplicate prevention over automatic reassignment. Restarting the existing Fly machine preserves its configured ordinal. A separate coverage worker checks every 15 minutes whether each shard that owns active portfolios has written a recent portfolio snapshot. This detects a missing or wedged shard; it is separate from the market-data freshness gate used by strategy evaluation. Recovery verifies the full ordinal set, restarts or reassigns exactly one machine to the missing ordinal, hydrates its portfolios from durable state, and then resumes evaluation.

Shard-coverage monitor The worker periodically checks whether every configured shard is still writing portfolio snapshots. Missing coverage creates a critical system alert for operator recovery.
Why accept the pause? Starting a replacement before fencing the prior owner can evaluate the same user twice and duplicate brokerage effects. The current design keeps the ownership mapping fixed, pauses affected portfolios, repairs exactly one ordinal, and resumes from durable state.
DetectShard stops writing expected portfolio snapshots
FenceKeep the user mapped to the same ordinal; do not create a second owner
RepairVerify ordinals, restart or reassign one machine, then rehydrate
ResumeWrite a fresh portfolio snapshot and restore shard coverage

This is an active-passive continuity model for each shard ordinal. It deliberately preserves one trading owner while recovery verifies the ordinal, restores durable state, and resumes evaluation. A requirement for automatic market-hours reassignment triggers the next design: a versioned consistent-hash ring with virtual nodes, routing epochs, drain-and-hydrate handoff, and fenced writes from the former owner. Consistent hashing limits remapping; the epoch and handoff protocol preserve the single-owner invariant during migration.

Do not combine these freshness controls. The coverage monitor detects a missing live-trading owner. The evaluation path separately rejects stale quotes and incomplete market state before creating order intent. Faster shard recovery requires quicker detection plus a fenced handoff protocol.

Market state is an execution dependency

A senior design classifies each timestamp by exchange session and instrument state before the evaluation path admits an order.

Gate strategy evaluation on current market state Calendar and instrument events become versioned inputs to the same decision record as prices
Exchange calendar session · holiday · half day · auction
Instrument events halt · split · dividend · symbol change
Evaluation gate freshness · eligibility · strategy session
Order admission evaluate · hold · cancel · reconcile
Closed or shortened session

Use the venue calendar and timezone. Suppress scheduled evaluation outside the strategy's allowed session.

Halt or circuit breaker

Block new submissions for the affected instrument while order status and fills continue to reconcile.

Split or symbol change

Version adjusted data, positions, and identifiers together so cached history preserves consistent pre-event and post-event units.

Dividend or merger

Record the event effective time and cash or position effect, then rebuild any derived portfolio snapshot that depends on it.

Other senior-level decisions

  • Recoverable job ownership: reclaim stale research and agent jobs after a worker dies.
  • Conditional transitions: one worker wins the right to submit an approved order.
  • Stable external identity: reuse a client order ID after ambiguous timeouts and reconcile before replay.
  • Backpressure: limit work per provider, brokerage, account, and machine. Internal capacity leaves external quotas unchanged.
  • Degraded modes: keep read-only research available while live execution fails closed on stale prices or uncertain order state.
  • Cost-aware capacity: keep the web tier warm, suspend reserve web machines, and let bursty research compute scale to zero.

Each brokerage adapter has a named product boundary. NexusTrade presents separate connection and capability surfaces for Alpaca, TradeStation, Public, and Tradier. Each adapter normalizes venue-specific authentication, order states, rate limits, and reconciliation behind the same intent contract.

Senior interview signal: discuss how ownership changes during a rebalance, how an ambiguous broker timeout is reconciled, how stale market data blocks execution, and which workloads scale on CPU versus external rate limits.

Production extensions

Open the detail the interview calls for

Most interviews will stop at the core design above. Open these extensions when the interviewer asks about secrets, recovery, retention, storage, latency, or strategy configuration.

Senior interviewer probes Secrets, recovery, retention, and storage choices The questions that usually arrive after the main diagram

A senior answer should state the current boundary, then name the condition that would force a different design. These probes do not require another 20 boxes on the main diagram.

Brokerage secrets and OAuth rotation

Brokerage access and refresh tokens are stored encrypted and decrypted inside the adapter path. The model and research workers receive no brokerage credentials. A rotation design must support overlapping key versions, refresh-token updates, revocation, and an auditable reconnect path without exposing plaintext tokens to general workers.

Backup, restore, and recovery targets

The current backup job writes nightly compressed MongoDB dumps to Tigris, retains 30 days, and excludes regenerable market histories. Backup frequency is an implementation fact. An RPO or RTO requires a restore drill that measures data loss, restore time, index rebuilds, and reconciliation with brokers.

Region loss and live ownership

Stateless web and elastic research roles can be recreated from durable state. Live execution has the harder rule: one ordinal owns each user. A disaster-recovery design must fence the former owner, advance a routing epoch, hydrate the new owner, and reconcile brokerage state before evaluation resumes.

Audit identity and retention

Persist the observation time, market-data generation, strategy revision, decision, approval, stable client order ID, broker response, and reconciliation result. Retention is set per record class and jurisdiction. Do not turn an architectural event log into an unsupported compliance claim.

Choose storage by access pattern

Start with the workload: transactional updates, historical scans, or interactive analytics. The products below show how NexusTrade fills each role.

Workload Current choice Why it fits When another store wins
Historical simulation Versioned Parquet in Tigris Immutable columnar partitions are cheap to publish, cache, replay, and share across elastic Rust workers. ClickHouse becomes attractive when continuously ingested events need low-latency aggregates across many concurrent users.
Interactive research SQL MotherDuck analytical mirror DuckDB semantics fit columnar research and ad hoc screening without placing those scans on MongoDB. A dedicated time-series service wins when streaming windows, continuous materialization, and subsecond operational queries dominate the workload.
Online product state MongoDB plus Redis MongoDB owns durable product and workflow state. Redis owns derived cache entries and low-latency delivery. Keep this state outside the historical lake because user mutations, job reservations, and approvals need current ownership.

Strong interview answer: name the workload first, choose the store second, and finish with the threshold that would make you reconsider it.

Operations Monitoring, alerts, and financial-boundary latency SystemAlert flow, recovery signals, and trace points

A green HTTP health check proves that one route answers. Separate signals verify portfolio evaluation, data freshness, and order reconciliation across the user's financial workflow.

The current SystemAlert path Failures become durable records before notification policy is applied
poll every 5s · 10 alerts/batch · 3 delivery attempts
Rust + TypeScript detect a typed operational failure
systemalerts PENDING record in MongoDB
SystemAlertWorker oldest pending and failed alerts first
AlertGate per-key cooldown + global storm breaker
SENT or SUPPRESSED primary email, fallback, or audited suppression
Live-trading correctness Repeated tick failure, portfolio deactivation, invariant violation, or ambiguous position reconciliation
Research + data Backtest or optimizer queue starvation, failed pipeline work, publication lag, or split continuity failure
Storm control Default 60-minute key cooldown; trip at 10 distinct keys or 50 alerts inside five minutes

Producers persist a severity, source, stable alert key, subject, and diagnostic body. Notification happens downstream. The worker records whether the alert was sent, suppressed by key, suppressed by the global breaker, acknowledged, or failed. That audit trail becomes part of recovery.

Signal Alert condition First response
Data freshness Latest expected partition or quote exceeds its freshness budget. Block affected evaluations and identify provider or publication lag.
Scheduler lag A portfolio exceeds its evaluation cadence and grace period. Inspect shard ownership, loop heartbeat, and durable command state.
Ownership lease age A research, agent, or order worker is nearing the end of its reserved ownership window. Recover the owner or quarantine the job before replay.
Order uncertainty A submitted client order ID lacks a resolved broker state. Freeze duplicate submission and reconcile with the venue.
Broker health Latency, rejection rate, authentication errors, or rate limiting exceeds the adapter budget. Open the circuit for new submissions while reconciliation continues.
User risk Exposure, concentration, drawdown, or buying-power checks cross product policy. Require review, reduce authority, or stop the affected portfolio.

Measure latency at the financial boundary

Signal-to-broker trace points Record each boundary before calculating p50, p95, or p99
no production latency result is asserted in this article
t0market observation accepted with provider timestamp
t1strategy evaluation started
t2order intent persisted
t3manual or policy approval recorded
t4broker request sent
t5broker acknowledgement received

Report evaluation, approval wait, adapter time, and total latency separately. Split paper and live execution by brokerage and order type. Manual approval time is user wait time, so combining it with machine latency produces a misleading percentile.

Logs should carry the same identity chain across decision, portfolio, strategy, dataset generation, order, client order ID, brokerage account, and fill. Metrics show that a class of work is unhealthy. Traces and durable records explain one affected run.

Strategy interface A portable DSL across research and live execution Natural language, SDK, MCP, and REST entry points

A strategy should describe intent in a portable, typed model. The runtime decides whether that model is evaluated against historical data, a paper portfolio, or a live portfolio. This keeps the strategy authoring surface separate from execution authority.

Strategy {
  condition: And([
    RSI("SPY", 14 days) < 35,
    Price("SPY") > SMA("SPY", 200 days)
  ])
  action: OpenOption({
    underlying: "SPY",
    expiration: 30 to 45 days,
    targetDelta: 0.30,
    allocation: 5 percent of buying power
  })
}

The example is educational and excludes investment advice. The architectural point is that indicators, comparisons, composite conditions, actions, contract selection, and allocation live in a structured model. Arbitrary callback code stays outside the strategy contract.

Natural language

An agent or assisted builder translates intent into the typed model, validates it, and returns errors as structured feedback.

SDKs

The published Python SDK and TypeScript SDK create the same portfolios, conditions, actions, backtests, and data requests from code. Their public Python and TypeScript mirrors contain only the client libraries. The platform implementation remains proprietary.

MCP

External assistants call the permissioned MCP tool catalog and receive typed results. Raw database and brokerage access stay inside the product boundary.

REST API

Applications integrate through the versioned API contract, stable identifiers, validation errors, and asynchronous job status.

One internal model prevents the browser builder, SDK, MCP server, agent, backtester, and live runtime from inventing different strategy semantics.

Research validity Walk-forward analysis and independent holdouts Point-in-time data, validation windows, and paper trading

An optimizer can search thresholds, lookbacks, allocations, and contract parameters faster than a person. That speed also makes overfitting easier. The research contract should separate discovery, validation, and final holdout periods before paper trading.

1 · Point-in-time inputs2 · Training window3 · Parameter search4 · Validation window5 · Walk forward6 · Untouched holdout7 · Paper trading8 · Optional deployment
  • Use only data knowable at each simulated timestamp.
  • Apply splits, dividends, delistings, option-contract availability, fees, and slippage consistently.
  • Rank candidates on multiple objectives such as return, drawdown, turnover, and stability.
  • Record the dataset generation, strategy revision, parameter set, and engine version with every result.
  • Treat a failed out-of-sample result as a stop signal. Preserve the holdout for an independent decision.

NexusTrade exposes these stages separately: the corpus identifies the available evidence, the Backtest Explorer runs a fixed strategy, and Optimization searches parameter candidates.

Conclusion

The platform makes the agent useful

The progression is now complete: prove one correct loop, separate the competing workloads, then add ownership, recovery, and elastic capacity where the measurements require them.

Those boundaries give an autonomous agent somewhere safe to operate. The model proposes the next research step. The platform supplies the tools, data, durable execution, approval, and brokerage controls. You can follow that split in the NexusTrade agent.

The companion article traces the agent runtime: Router V5, Agent V6, durable ReAct steps, parallel tools, subagents, Run Compute, crash recovery, and the boundary between creating order intent and receiving authority to submit it.

The companion article, How to Design an AI Trading Bot, follows that runtime from the router through execution and recovery.

Put the architecture to work on a decision you actually care about. Give Aurora a company, strategy idea, research brief, filing question, or portfolio problem. NexusTrade can gather the evidence, run the analysis in an isolated compute environment, backtest when the question calls for it, and return an inspectable result. You get one workflow from question to evidence without giving a research process automatic authority to place a trade.
Try your own task with NexusTrade ↗

Build the strategy this article describes

Create a free account to backtest ideas against market history, inspect the risk, and deploy to paper or live markets when you're ready.

or

Free to browse. No credit card required.

Discussion

Sign in or create a free account to join the discussion.

No comments yet.