The market was open the whole time: Kalshi sharding and 'market not found'
Kalshi is splitting its exchange into shards. Crypto moved on 24 August and our bot spent nine hours getting 'market not found' for markets that were open and quoting. What changed, why the error points the wrong way, and whether it moved the spread.
Our crypto bot stopped trading at 03:40 UTC on Monday and we did not
notice for nine hours. Every order came back market not found, for
markets that were open and quoting. Nothing crashed. No service went down, no alarm
fired, and the dashboard stayed green. The bot kept placing orders the
entire time and the exchange kept answering with the same four words.
market not found
The market was open. You could pull it up on the site, watch the book
move, and trade it by hand. Kalshi returned that error four hundred and
six times in two hours for contracts that were active and quoting.
The reason is worth publishing, because it is going to happen to
somebody else this week and the error message points in exactly the
wrong direction.
What actually changed
Kalshi is splitting its exchange into shards. Instead of one matching
engine handling everything, there are now several, each one carrying a
category. Their published timeline runs like this. Transfers into shard
one opened on the sixth of August. Combos moved there over the tenth and
the seventeenth. Then on the twenty fourth, crypto moved to shard two,
and tennis and baseball moved to shard three.
Every market now carries a field called exchange index saying which
engine it lives on. Ticker formats did not change. Nothing about the
contract you are looking at tells you it moved. Our BTC and ETH and SOL
markets went from engine zero to engine two overnight and looked
identical from the outside.
Orders carry the same field. If you do not set it, you are talking to
engine zero. So from Monday morning our bot was politely asking an
engine that no longer hosted crypto whether it could rest an order on a
crypto contract, and that engine was answering, accurately enough, that
it had never heard of it.
Why we did not catch it
Because the bot did not stop. It trades oil alongside crypto, and oil
stayed on engine zero. So through the whole outage there were fills
landing, orders resting, and a P and L ticking along. Every health check
we have looked at the lane as a whole and the lane was alive.
What we should have been watching is fills per family, not fills. Oil is
about a fifth of our volume, so four fifths of the desk went silent and
the top line barely flinched. That is now a check.
The thing that finally found it was mundane. We printed the full ticker
next to the error instead of the last ten characters. Every crypto
ticker ends in the same ten characters as every other one, something
like G250700 dash 00, so four hundred failures across seven different
markets had been rendering as what looked like one market misbehaving.
Once the whole ticker was in the log the pattern was obvious in about a
minute.
The part that cost us the most time
We fixed the routing and nothing happened.
Collateral does not follow your order. Their documentation says it
plainly once you know to look for it, that programmatic traders must
preallocate collateral on a given shard before placing orders there. Our
entire balance sat on engine zero. Crypto now trades on engine two,
where we had nothing, so correctly addressed orders failed just as
completely as misaddressed ones.
Moving money between shards has its own endpoint and three small traps
in it. Amounts are in centicents, so a dollar is ten thousand. The
source and destination fields are not shard numbers, they are instance
types, and the only valid values are event contract and margined. The
shard numbers go in two separate optional fields that are easy to miss.
Read the field names the obvious way and you get a four hundred back.
One more thing, and we would like to be careful about how we say it. The
documentation states that leaving the exchange index off an order will
route it automatically using the ticker. That did not work for us. With
twenty dollars sitting on shard two and the field omitted, the errors
continued unchanged. We tested one order endpoint, not all of them, so
it is possible this behaves differently elsewhere or has changed since.
We set the field explicitly now and it works.
The diagnostic that generalises
If something on Kalshi is returning market not found for a market you
can see, compare the exchange index on a contract that works against one
that does not. Ours read zero for oil and two for crypto and that single
line explained everything else. There is also a status endpoint that
lists every shard with a plain English description, which reads Default,
Combos, Crypto, Tennis and Baseball. Three minutes with those two calls
would have saved us the day.
Does it make the trading better or worse
The honest answer on the part that matters is neither, and we can show
that rather than assert it.
Splitting an exchange could plausibly change the thing a maker actually
lives on, which is the spread you are paid and the depth you sit behind.
So we measured both across the migration, using oil as a control,
because oil stayed on engine zero while crypto moved.
One thing to get right before the numbers. Oil does not quote at
weekends and crypto quotes around the clock, so a before window that
includes a Saturday compares oil's empty book against crypto's busy one
and produces a difference that is purely the calendar. Both windows below
are weekdays only. Before is Monday the eighteenth to Thursday the
twenty first, after is Monday the twenty fourth and Tuesday the twenty
fifth, and crypto moved on the Monday between them.
| market | window | quotes | median spread | share at 1c |
|---|---|---|---|---|
| BTC | before | 3,288 | 1.0c | 99% |
| BTC | after | 1,894 | 1.0c | 98% |
| ETH | before | 3,404 | 1.0c | 79% |
| ETH | after | 1,891 | 1.0c | 81% |
| WTI (control) | before | 4,243 | 1.0c | 54% |
| WTI (control) | after | 2,357 | 1.0c | 65% |
Spreads are unchanged, and not just at the median. The share of quotes
sitting at a one cent spread holds across the move on both coins, so the
whole distribution stayed where it was rather than the middle of it
happening to land in the same place.
Depth at the touch fell over the same period, on crypto and on oil
alike, by a broadly similar proportion. Oil never moved, so that is the
time of day rather than the shard. Two notes of caution on that row,
because it is weaker than the spread one. It is a day and a half of
data. And it comes from our own archived recordings rather than a live
query: Kalshi's book history is short and the before half of it has
already aged out of what the API will serve, so unlike the spread rows
above, a reader cannot go and check it. The spread result is the clean
one and it is the one that decides whether the trade still works.
Where it does cost something is capital. Collateral is per engine and it
does not move by itself, so money parked on one shard cannot back an
order on another. At our current size that is free. Crypto needs about
nine dollars of working capital at the moment and we put twenty on that
shard. But it caps how large any one engine can get. A book four times
this size would need more collateral on the crypto shard alone than the
whole account holds, and it would have to be moved there by hand.
Which points at the part we find genuinely lopsided. Kalshi offers
automatic rebalancing between shards, where you set a target allocation
and free margin gets moved to hold it. That is for institutional
clients. Everyone else does it manually. So a change that is close to
neutral for a large desk is a standing chore for a small one, and it is
the small account that can least afford collateral stranded on the wrong
engine.
Set against that, there is a real benefit we are probably undervaluing.
A surge of volume in tennis or combos can no longer slow the engine our
crypto sits on. We have never been limited by speed, so it is worth
little to us, but for anyone who is, isolation is the whole point of
doing this.
Net, for a book our size, slightly worse. Not because it touched the
edge, which it demonstrably did not, but because it added a manual job
and a new way to fail quietly.
What it cost
Nine hours of crypto downtime, and honestly not much money, because the
lane it took offline is running at roughly break even anyway. We will
write about that separately and it is a less comfortable piece.
The lesson we are actually taking is not about sharding. It is that our
monitoring watched whether the desk was alive rather than whether each
part of it was, and a platform migration is exactly the kind of failure
that leaves the patient breathing while most of it stops working. An
error that says the market does not exist, about a market that plainly
does, is the sort of thing you can stare straight at for hours. We did.
If this was useful, the rest of it is written down. Operations
collects what this exchange charges you before your strategy matters at all:
the two fee schedules and which 130 series charge makers, the shard table and
the collateral trap above, how settlement actually resolves and why it is not
the price on your chart, the tickers that mean the opposite of what they read
like, and the measured gap between what a backtest promises and what real
fills deliver. It is kept current, because every one of those changed this
year.
It sits behind the Desk tier alongside the per-trade files. The studies stay
free and always will.