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 your Polymarket position in a market is shared by every Bot on the account — 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.
Bots lost after a runner restart
A Locus container restart can lose the runner's Bots when its local disk is replaced. This differs from restarting one Bot's process or a Studio-managed rebuild that re-ships the Bot bundle. Once Studio confirms a previously running Bot is missing, it closes the Bot's recorded run and any active Paper session. When the available runner boot and snapshot evidence indicates a restart, Run History and Library show Runner Restarted (runner_restarted) and ask you to redeploy.
The recorded end time uses the runner's boot time when available; if the boot line is gone and the runner lists no Bots, it uses the Bot's last snapshot instead. Detection can happen later, so this time is not proof of uninterrupted trading up to that point. Bots without sufficient restart evidence can retain the more general runner_missing reason.
Studio does not automatically redeploy these Bots or close their exchange positions. Check positions and resting orders on the venue, then redeploy the strategies you want to run. Kalshi per-fill exits in a new deployment do not adopt the previous deployment's contracts; close those positions before redeploying. See Per-fill exits.
Upgrading a runner
Turbine updates the runner from time to time. Two paths reach a new build, with different effects on running Bots.
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 or Update Software action in Studio stops all live and paper Bots on that runner and provisions a fresh, idle runner. Exchange credentials are preserved. Redeploy the Bots you want to run after the update; their strategy code is not compiled or copied during the upgrade. Stopping Bots does not automatically close exchange positions.
What that empty disk costs after an in-place rebuild, or when you redeploy after an explicit upgrade:
- 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 before it trades again: its order prefix survives the move, so it finds its own orders in Kalshi's order history and adds up their fills, however old. It places neither entries nor exits until that is done, usually within its first check. If Kalshi's order history no longer lists an order, or the fills can't be read, the Bot logs
Position rebuild incompleteand trades on what it could rebuild, 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 sessions and starting balances survive an in-place rebuild through Studio. An explicit upgrade ends active paper sessions; redeploy a paper Bot to start it again. Anything else that has to outlive a rebuild 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.