All articles
Risk·May 23, 2026·5 min read

How to Build a Kill Switch for Your Solana Trading Bot

A kill switch is the last line of defense when a bot goes rogue. This guide walks through implementing a hardware and software kill switch that halts all open orders and cancels positions on Solana within milliseconds.

Your bot runs fine for six weeks. Then one morning a stale price feed combines with a reorg edge case and it starts opening positions on the wrong side of a 40% move. By the time you wake up and read the alert, the damage is already measured in SOL. A kill switch does not prevent bugs — it limits how much a bug costs you.

This guide covers what a production kill switch actually looks like: the software path, the out-of-band hardware path, and the on-chain cancellation mechanics that determine whether you flatten in 80ms or 8 seconds.

What "Kill" Actually Means on Solana

There are two distinct operations most engineers conflate: stop sending orders and cancel existing orders. Stopping the bot process handles the first one. The second requires active RPC calls because Solana has no native "cancel all by authority" instruction — you must cancel each open order explicitly, or drain the account if you are using a custodial margin program.

On Serum/OpenBook, every open order lives in an OpenOrders account keyed to your wallet and the market. To cancel you call cancelOrderByClientId or cancelOrder per order, then settleFunds to sweep back to your SPL token accounts. Depending on position count, this is anywhere from 1 to 30 transactions. Batch them using sendAll and parallel RPC submission — do not await each one sequentially or you will spend 15 seconds on something that should take 400ms.

The Software Kill Switch

The minimum viable software kill switch is a shared atomic flag and a dedicated cancellation routine that owns the RPC path.

// TypeScript pseudo-structure
const KILL = new SharedArrayBuffer(4);
const killFlag = new Int32Array(KILL);

// In your main bot loop
if (Atomics.load(killFlag, 0) === 1) {
  await cancelAllAndExit();
}

// Triggered by signal, webhook, or watchdog
Atomics.store(killFlag, 0, 1);

For multi-threaded bots using Node.js workers or Rust tokio tasks, Atomics or an AtomicBool propagates the halt across all threads without a mutex. The cancellation routine should be the only code path that holds the signing keypair during shutdown — everything else should fail-safe to a no-op rather than retry.

Watchdog process: run a separate lightweight process (systemd service or a second container) that polls a heartbeat endpoint your bot publishes every 500ms. If three consecutive heartbeats miss, the watchdog triggers the kill flag via a Unix socket or HTTP call to localhost. This catches process hangs, not just explicit shutdowns.

The Hardware Path

Software kill switches fail when the machine is compromised, the process is deadlocked, or your cloud instance is unreachable. A hardware path removes the dependency on the bot machine entirely.

The pattern that works in practice: a small Raspberry Pi Zero 2W (or equivalent) sits on your local network with a single responsibility — it holds a separate signing keypair with authority only to cancel orders, not to open them. It runs a loop that calls your bot's health endpoint and, on failure, submits cancellation transactions independently using its own RPC connection.

This costs roughly $18 in hardware and $0 in cloud. The critical design constraint is least privilege: the hardware device must never have authority to open positions, only to cancel and settle. If it is ever compromised, the worst outcome is a forced flat, not a rogue position.

For teams running on VPS infrastructure without physical access, replicate this with a second VPS in a different provider and region, using a Shamir-split signing key so no single machine can open positions unilaterally.

RPC Reliability Under Stress

The moment you most need your kill switch is the moment the Solana network is most congested. Plan for this explicitly.

  • Use at least two RPC endpoints from different providers (Helius, Triton, QuickNode) and fan out cancellation transactions to all of them simultaneously.
  • Set maxRetries: 0 and handle retries yourself — the default retry behavior in @solana/web3.js introduces unbounded latency during congestion.
  • Pre-compute and cache transaction messages for your most common cancellation patterns at startup. Signing a pre-built transaction is ~2ms; building it from scratch under load can be 20ms per instruction.
  • Use processedCommitment for the kill path — you want the transaction in flight, not confirmed. Confirmation can come later. The goal is submitting to the validator pool, not waiting for finality.

Measured against a 32-order book on a busy market, a well-implemented kill sweep runs in 80-200ms end-to-end. A naive sequential implementation on the same order book takes 4-8 seconds — an eternity during a price shock.

Testing the Switch in Production

A kill switch you have never triggered is a kill switch you do not trust. Build drills into your deployment runbook:

  1. Staging test on devnet — full position open, manual kill trigger, verify all orders cancelled and funds settled.
  2. Canary kill on mainnet — once per month, open a dust-size position (0.01 SOL notional), trigger the kill switch, verify latency and outcome. Log the round-trip time.
  3. Watchdog isolation test — kill the bot process without triggering the kill flag. Verify the watchdog fires within its detection window (should be 1.5-2x the heartbeat interval).

Document the expected output for each test. If the actual output diverges, that is a production bug, not a test failure.

Position Sizing as a Complementary Control

A kill switch handles the emergency case. Position sizing handles everything before the emergency.

The kill switch should be the last layer, not the first. Hard limits on single-position notional, per-market exposure, and drawdown over a rolling window should fire well before the kill switch is needed. In the bots we design and run at TierZero, the kill switch has triggered in production twice in 18 months — both times it worked correctly because it was the fifth layer of protection, not the second.

If your risk stack currently consists of "alert me on Telegram and I will cancel manually," you are not running a risk stack — you are running a prayer.


If you want a second opinion on your current kill-switch architecture, or need help building one from scratch, reach out to the TierZero team — we have shipped these on Solana, Hyperliquid, and Polymarket and can review your setup in a single call.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#risk#solana#trading-bots#infrastructure#order-management