Locus Deployments
Turbine partnered with Locus (YCF25) to give each Studio user private servers for strategy execution. The result is a deployment flow that feels simple in the browser while preserving a permissionless execution model.
What Locus provides
Locus provides the compute environment where your runners live. A runner is where an approved strategy evaluates markets, reads the configured data sources, and submits venue actions using your credentials.
From the user's perspective:
- Studio builds the strategy,
- Studio helps backtest the strategy,
- Studio deploys the strategy as a Bot,
- Locus hosts one private runner per venue family for each user,
- each runner executes that family's bots as isolated processes.
A venue family is the set of venues one runner trades. Kalshi events, Kalshi Perps, Polymarket US, Turbine, and Kalshi + Polymarket US arbitrage all run on your Kalshi runner. Polymarket has a runner of its own because it executes from a different region.
The words Studio uses
| Term | Meaning |
|---|---|
| Strategy | The code of a trading idea in a Studio chat. It has no running state of its own. |
| Bot | One running instance of a Strategy on one venue, live or paper. Deploying starts a Bot; stopping ends it. |
| Runner | Your private execution host for one venue family. It hosts that family's Bots, each isolated from the others. |
| Bot cap | How many Bots your plan lets you run at once, across all venues, paper Bots included. |
| Runner capacity | The engineering limit on how many Bots a single runner can host. |
| Bot label | The name a Bot gets when it deploys — "Bot 2". Labels are never reused. |
The same Strategy can run as two Bots at once; each keeps its own orders, fills, and results.
Why private runners matter
A runner hosts isolated Bots. Your live execution never shares a process with another user, and inside a runner each Bot runs as its own process:
- users do not need to share a pooled trading process,
- live credentials are scoped to your runner,
- deploying, updating, or stopping one Bot leaves its siblings running, as long as the runner is healthy and current,
- a Bot that crashes is retried in place: the runner restarts only that Bot's process, never a sibling's,
- runner state is easier to reason about.
The product should feel easy, but the boundary matters: Turbine Studio is the build and control surface; the runner is the execution surface.
Studio is not required to push code. The runner also accepts a code payload signed by its authorized wallet directly at /code; see Run a strategy programmatically for a complete Python example.
How many Bots you can run
The Bot cap is a plan entitlement, counted across every venue and including paper Bots: Starter 1, Basic 3, Pro 5. The sidebar header shows where you stand — "Running 2 / 3".
At the cap, the next deploy is refused: Studio names the limit it hit, and the tier that raises it when there is a higher one. Going over the cap — after a plan change, say — never stops a Bot that is already running. It also never blocks an update to a Bot you already run; the cap only stands between you and a new Bot.
Runner capacity is a separate limit on how many Bots one runner can host: five today, the same as the Pro cap. A runner's capacity is shared by its whole venue family. If you ever hit that limit instead of your cap, stop a Bot on that runner or deploy on the other runner (a Polymarket runner exists only where Polymarket is available to you).
Running several Bots
Deploy from a Strategy chat as usual. When that Strategy already has a Bot running, you get two actions:
- Update Bot 2 — the Run button takes the selected Bot's label — pushes the new code to that Bot in place: same Bot label, same run.
- Deploy as new Bot starts a second, independent Bot from the same Strategy.
An update reaches only its own Bot as long as that venue's runner is healthy and on the current version. If the runner is out of date, the update is refused and queued rather than pushed; upgrade the runner from the runner panel to let it through. If the runner cannot be reached at all — or you start a new Bot on an out-of-date one — the deploy falls back to rebuilding the runner, which restarts every Bot on it once.
Balance and margin on a venue are shared by every Bot on that venue's runner, so several Bots there draw on one pot of money. Size them together, not as if each had the account to itself.
The same goes for the money figure each Bot reports. "Account equity change (since this Bot started)" — in the terminal header, the Analytics tab, and the copilot's summary — is the whole account's equity minus the balance captured when that Bot started, not the Bot's own P&L. Deposits, withdrawals, your manual trades, and every sibling Bot on the runner move it, so five Bots on one runner show five readings of one account that differ only by their start times. There is no per-Bot P&L on Kalshi event markets: a Bot's fills are tagged with its identity, but most of an event Bot's P&L is realised at settlement, which is not a fill and carries no Bot tag. To judge one Bot, read its own fills and positions in the Analytics tab and its Orders and Fills filter, not the equity figure.
Telling your Bots apart
Every Bot carries its label wherever it appears:
- the Running list gives each Bot a line with its label, Strategy name, venue, Live or Paper, and uptime; the dashboard's copy of that list adds the short hash of the code the Bot is running and when it was deployed,
- the terminal is titled "Bot 2 · Dip Reverter" and shows that Bot's log lines only — the Bot chips above it switch which Bot you are watching,
- Orders and Fills default to the Bot you are looking at; switch the filter to All to see sibling Bots' rows, each labelled "Bot 2 · Dip Reverter", alongside your own manual trades,
- the Analytics tab's Open Orders and Trade History tables use the same filter and the same labels, so a Bot that has never traded shows no trades, not its siblings'; an older run's order that no running Bot claims stays in view as "Untracked bot order".
Each Bot's orders and fills carry its identity, so two Bots running the same Strategy stay distinguishable.
Stopping a Bot
Stopping a Bot ends its run. On its own it sells nothing: open positions stay on your venue account until you deal with them. Resting orders stay too — except on Kalshi Perps, where the Bot cancels its own open orders as it shuts down.
Selling is opt-in and Kalshi-only. A live Kalshi Bot's stop dialog offers a "sell all Kalshi positions" checkbox; on any other venue the request is refused. When you do tick it, the sale cancels resting orders first, and what it sells depends on what else is running:
- stopping the only Bot on that venue's runner sells the whole account, including positions you opened by hand,
- stopping one Bot beside siblings sells only that Bot's own net position and leaves siblings and manual positions alone.
If the shared account can only reduce by less than the Bot's ledger claims — other exposure points the other way, or part of the position settled or you closed part of it by hand — Studio lists the shortfall with the reason account_cannot_reduce. A position the account no longer holds at all, because it settled or you closed it by hand, produces no row: there is nothing left to sell.
A per-Bot sale that fails is finished, not pending: the Bot's resting orders have already been cancelled, except any the report lists as a failure, and its runner slot is gone, so the stop cannot be retried. Close whatever the report lists as remaining yourself, on the venue.
To flatten a whole venue on purpose — every Bot plus manual positions — use stop all on that venue instead of stopping Bots one at a time. Its sell is the same opt-in, and Kalshi-only in the same way.
Arbitrage Bots
Two arbitrage Bots never share a Polymarket market. If a market is already traded by an arbitrage Bot on that runner, Studio refuses a second Bot on it; point the new Bot at a different market. That refusal only looks at one runner, while Polymarket cancels are account-wide — so keeping arbitrage Bots on different runners off one market is left to you.
Adding a second arbitrage Bot to a runner also demotes the first from the shared order namespace it had to itself. Its own orders already carried a per-Bot prefix, so nothing changes about how it places them; what changes is what it still owns. The fills it made under the shared prefix drop out of its P&L immediately — bounded to the fills of its current run, which is all its P&L counts — and from its next restart it stops cancelling the orders it left resting under that prefix, as does every other Bot. Cancel those resting orders before you add the second arbitrage Bot.
Kalshi Perpetuals Bots
Perps Bots run on your Kalshi runner, beside your Kalshi event-market Bots: they share its capacity and its stop all. That stop all ends every Bot on the runner, and the sale it offers covers event-market positions only — perps positions stay open.
Several Perps Bots can run on one runner, and deploying one puts it on a single margin account, cross-margined with every other Perps Bot there:
- each Bot tracks its own Position — the net of its own fills — and its TP/SL closes only that Position,
- the exchange's account-level position and margin belong to the account, not to any one Bot,
- a close is clamped to what the shared account can actually reduce, so a Bot whose Position the account no longer carries closes nothing; it says so once in its terminal and stays quiet until the account's position changes,
- liquidation is account-wide: one Bot's losses can liquidate what the others are holding.
Watch margin usage across the venue as a whole, not per Bot.
Upgrading a runner
Turbine updates the runner from time to time. Two paths reach a new build, and both restart every Bot on the runner once.
An update that ships as a git push rebuilds the runner in place: the Bots running on it are picked back up and keep their labels, but per-Bot state files written on the runner's disk do not survive the rebuild.
The explicit Upgrade action in Studio provisions a fresh runner, moves every Bot from the old one onto it, and pushes their code again. Nothing is stopped for good and there is nothing to redeploy afterwards — but each Bot starts again on an empty disk, exactly as in a rebuild. (If a Strategy's draft has changed since its Bot was deployed, the upgrade refuses rather than quietly shipping newer code to a running Bot.)
What that empty disk costs, on either path:
- a halted arbitrage Bot forgets that it halted and resumes with the unhedged leg it stopped on — resolve the halt and close that leg before upgrading,
- a Kalshi Perps Bot rebuilds its Position from the margin fills feed when it restarts — its order prefix survives the move — but only as far back as that walk reaches; fills older than the walk, or a feed the Bot cannot read, leave a position in no Bot's ledger, so check each Perps Bot's Position after an upgrade and flatten anything no Bot claims,
- Polymarket fills from before the upgrade lose their Bot attribution and drop out of that Bot's P&L,
- each Bot's risk state — the running loss its max-loss limit counts, and any risk halt it recorded — starts over from the limits it was deployed with.
Paper Bots are the exception: their session and starting balance come back from Studio. Anything else that has to outlive an upgrade lives in Studio, not on the runner.
Manage your server in Locus
If you'd like to manage your server directly through Locus's interface, Locus's Build docs show how. They cover projects, services, deployments, variables, domains, and other infrastructure without Turbine's interface.
Deployment lifecycle
Provision
Studio creates the venue's runner the first time you deploy there.
Configure
The runner receives the Bot's code, environment, and required credentials.
Start
The runner starts the Bot as its own process, beside any siblings already running.
Observe
Studio surfaces each Bot's status, logs, orders, and fills.
Update
A revised Strategy can update the Bot in place, or deploy as a new Bot beside it.
Stop
Stop a Bot when the thesis breaks, limits are reached, or you want to revise behavior.
Credential boundary
Venue credentials should be treated as live trading secrets. The intended model is:
- the user supplies the credentials needed for their strategy,
- credentials are passed to the user's runner and used by every Bot on it,
- credentials are not a Turbine-owned trading account,
- credentials should not be exposed in docs, logs, prompts, or screenshots,
- users remain responsible for the permissions and safety of their venue accounts.
AI agents should never ask a user to paste credentials into a public prompt or doc. Use the Studio credential flow.
Permissionless execution
The deployment flow is designed so a user can run strategies without asking Turbine to manually operate a bot for them. The user approves the strategy, provides credentials, deploys it as a Bot on their runner, and can stop or revise it.
This does not remove trading risk. It changes who controls execution.
What stays private
These docs expose the public wallet-signing contract needed for portability, but not private deployment internals or Turbine's control-plane architecture. AI agents do not need those internals to use Studio safely.
The public model is enough:
- Studio drafts and tests strategies.
- Locus hosts one private runner per venue family for each user.
- Runners execute each Bot as its own process with user-scoped configuration.
- Users monitor and control every Bot they are running.