One host,
one job.
Everything that has to run while a game is live runs in AWS us-east-1, a short hop from the exchange, on small ARM machines that each do one thing. A research job can never take memory or CPU from the order path, and a bad deploy on one host cannot reach another.
Orders leave only from the Execution host (black). Every other arrow carries data, and the control room reads each host through read-only calls.
| Host | Instance | Disk | Last started | Runs | Talks to |
|---|---|---|---|---|---|
| Execution | t4g.nano · 2 vCPU · 0.5 GiB | 16 GB | Oct 17 | The trading bots: compiled Rust, run as systemd services. | Exchange REST and WebSocket. The only host with code that can place an order. |
| Market data | t4g.medium · 2 vCPU · 4 GiB | 300 GB | Oct 27 | A Rust collector for every order book, an agent for the league and ESPN feeds, a normalizer and a status publisher. | Exchange WebSocket with its own key, used only to sign the connection; league feed, ESPN, S3. |
| Live simulation | t4g.small · 2 vCPU · 2 GiB | 20 GB | Oct 20 | MACHINE's in-game model, re-run at every timeout and period break. | League feed in, S3 out. |
| Portfolio | t4g.small · 2 vCPU · 2 GiB | 20 GB | Oct 20 | The ledger and risk service behind the Results and Accounting pages. | Exchange account channels and GET-only REST. |
| Shadow research | t4g.small · 2 vCPU · 2 GiB | 30 GB | Oct 7 | A second strategy on live data in shadow mode. Its only order sink is a simulator. | Exchange WebSocket with a key that signs the connection only. |
43 GB
of order books.
Raw exchange messages for every market on each NBA game, archived since Oct 16, 2026, plus 1.5 GB of play-by-play and ESPN feeds. The exchange keeps no history of its order books, so anything not captured live is gone for good. This host is the reason the research has market depth at all, and the October 26 outage below shows what a gap costs.
From the host's own status file, Oct 27, 2026.
No open doors
No security group on any host has an inbound rule. Hosts are administered through AWS Systems Manager, and keys on cloud hosts come from AWS Secrets Manager; none is ever written into code or a repository. Only the Execution host runs code that can place an order. The others are read-only in code, and tested to stay that way.
Running ≠ healthy ≠ executing
A process being up says little. Each system declares its own checks, such as feed freshness, sequence gaps, reconciliation and time since the last fill. An HTTP 200 alone never counts as healthy, and whether a bot is armed is reported next to its health, not folded into it.
Observe, don't touch
The control room reads every host but cannot act on trading systems, the order path or live capture. Anything it can change is allowlisted, confirmed and written to an audit log.
Deliberate deploys
Releases are built from a pinned checkout and recorded with their commit. On the market-data host a service restarts only when its binary or unit file changed, so a routine redeploy never drops the live feed. Since week 1: no deploys while games are live.
Time
Hosts sync to Amazon Time Sync. Every captured record keeps the time we first saw it as well as the time the source says it happened, and research acts on the first, never the second.
Small on purpose
The trading bot runs on a nano instance, the smallest size AWS sells. Compiled Rust needs little, and fewer moving parts on that host means fewer ways to fail during a game.
Local jobs that recover
Nightly research jobs on the Mac run under a supervisor that catches up after sleep or power loss, waits for the network and retries with a cap, so a missed night shows up as a retry, not a hole.
Order rejected
Opening-night markets sat in a different collateral pool from the one the bot was funded in, so its order was refused and the trade was placed by hand. A fix that checks each market's pool before trading is written.
Rate-limited check
A new account check ran into the exchange's rate limit and kept the bot disarmed for most of the day. It re-armed in time for the night's signal, a couple of minutes late.
Deploy during a game
A fix deployed while a game was live restarted the bot and cost one signal. New rule: no deploys while games are live.
Disk full
Raw tape grew 7–8 GB a day with no retention job, and the disk alarm went to a topic nobody was subscribed to. Capture stopped at 5:27 PM PT for about seven hours: three games lost entirely, six cut off mid-game. Trading was not affected. Fix: a 300 GB disk and a larger instance; a retention job and alarm delivery are next.
Trading incidents are from the weekly report, where each is written up with what it cost.