Skip to main content

Why does withdrawing from a prediction market take minutes, not seconds?

· 8 min read
BlockTrader365

A token transfer on a modern chain confirms in a couple of seconds and costs a fraction of a cent. So when a platform tells you a withdrawal is "processing" for several minutes, the natural assumption is that something is stuck.

Usually nothing is stuck. The transfer really does take seconds — it is the two questions on either side of it that take the time, and both of them are questions a platform has to get right or lose your money.

The balance has to stop moving first

You cannot send a balance while it is still arriving.

On a prediction market, closing out is not a single event. Resolved positions redeem, resting orders fill or cancel, and the proceeds land in the account over some stretch of time rather than all at once. If a withdrawal snapshots the balance in the middle of that, it moves whatever happened to be there at that instant and leaves the rest behind — which the user experiences as a withdrawal that quietly shortchanged them.

So the first stage does not move anything. It watches. BT365 reads the account balance every five seconds and waits for three consecutive readings that differ by less than fifty cents before treating the number as final. Three readings rather than two, because a single pair can be stable by coincidence between two payouts. Fifty cents rather than exact equality, because insisting on an unchanging number means waiting on rounding dust forever.

That watch is capped at five minutes. If the balance is still visibly moving after that, the process stops waiting and works with what it has — an unbounded wait is not patience, it is a hang.

Most of the "processing" time you see is this stage, and it is doing something: establishing that there is nothing left to wait for.

Below five dollars, moving it destroys it

Once the balance is settled, it gets checked against a floor. Under five dollars, the withdrawal is skipped.

This is not a fee we are charging. It is an observation that a withdrawal touches at least one chain, that touching a chain costs gas, and that below some amount the gas is larger than the balance — so executing the withdrawal leaves the user with less than not executing it.

The part that matters is what happens next. A skipped withdrawal is marked as a completed outcome, with the reason recorded, rather than left as a failure for a recovery process to retry forever against an economic constraint that will never change. The floor is checked twice, too — once when the balance settles, and again immediately before the transfer, because a balance can drain between the two.

If you are testing a platform with small real amounts, this threshold is the one to know about. It is the difference between "nothing happened and I do not know why" and "this was too small to be worth moving".

Doing it exactly once

Now the transfer, and the problem that makes withdrawals genuinely hard.

Requesting a withdrawal and sending the funds are separate steps, and a process can die between them. The dangerous version is dying after submitting a transfer but before recording that it did — because the obvious recovery, retrying, sends the money twice.

The defence is to write down the intention before acting on it. BT365 persists the fact that a transfer is about to be submitted, with a timestamp, before submitting it. On restart, a record that says "a transfer was submitted but no transaction was recorded" is an instruction to go and look: scan the chain around that timestamp for a transfer matching the expected source and destination, and if one is there, adopt it as the transfer that already happened rather than sending a second one.

The same discipline covers the request that precedes it. The withdrawal is requested from the bridge once per record, carrying an idempotency key that is generated on the first attempt and deliberately reused on every retry, so a retried request is recognised as the same request rather than treated as a new one.

None of this is visible when it works. It is entirely about the case where something fails halfway.

What counts as "it arrived"

The last stage is the one most likely to be done badly, because there is an easy answer that is almost right.

The easy answer is to watch the destination balance and call it delivered when it goes up by about the right amount. That works until the destination is a wallet that does other things — receives funds from another position, a manual transfer, an unrelated settlement — during the same window. Then the balance rises by roughly the expected amount for a reason that has nothing to do with this withdrawal, and the platform marks it delivered while the actual funds are still in flight.

So delivery is established two ways. The bridge's own status is asked first, and when it reports the withdrawal delivered, the transaction it names is verified against the chain rather than taken on trust. Only if that is unavailable does the balance check apply — and even then a matching delta is not enough on its own. The delta has to fall inside a band of ninety-five to a hundred and ten percent of the expected amount, and the specific transfer that delivered it has to be found on-chain. If the balance moved by the right amount but no matching transfer can be identified, the withdrawal is flagged as unverified rather than completed. An unexplained credit is not proof.

Why your balance still shows the old number

One last piece, and it is a deliberate asymmetry worth explaining because it looks like a bug.

Throughout all of this, the balance shown on the account does not change. It is zeroed at one moment only: after delivery is confirmed. Not when the withdrawal is requested, not when the transfer is submitted — after the funds are established as arrived.

The alternative is to zero the balance up front, which produces a cleaner interface: the money leaves the account the moment you ask for it and there is no phantom balance sitting there during the transfer. BT365 does exactly that for perps withdrawals, where the path is mature and well understood.

For prediction markets it does the opposite, and the reason is the failure case. If the balance is zeroed first and the withdrawal then fails, the platform's record says the user has nothing while the funds are still sitting on the other chain — a phantom debit, which is far worse than a phantom credit. Zeroing late means that on failure the balance is still there, still correct, and the recovery process has something to work with.

Seeing your old balance during a withdrawal is not the system lagging. It is the system declining to write down a payout it has not yet confirmed.

The short version

A withdrawal that takes minutes is usually spending them on two things: waiting for a balance that is still moving, and refusing to declare victory on a delivery it has not verified. Both are indistinguishable from being slow, right up until the moment one of them saves you from a withdrawal that silently moved the wrong amount or was marked complete without arriving.

The platforms that return your money in seconds every time are generally the ones that have not thought about the failure cases yet.


Part of our guide to how prediction markets actually work.

BT365 runs prediction markets, perps, and spot from one self-custodial account. Explore the platform or read the documentation.