What happens when you press Buy on a crypto exchange
In the second after Buy, an exchange holds the user's money, places the order in the book, matches it against the best sellers, records both legs and the fee in a ledger, and issues a receipt.
In the second after a user presses Buy, a crypto exchange does five things: it checks the money and holds it, puts the order on the order book, matches it against the best sellers, records both sides and the fee in a double-entry ledger, and returns a receipt. Each step has one job, and each has to happen exactly once, even if a server fails halfway through. This guide walks through that second with one worked example, for anyone building or buying an exchange.
Step 1: the balance check and the hold
First the exchange checks that the user has enough of what they are paying with. A check alone is not enough: two orders arriving in the same instant could both pass it against the same balance.
So the exchange moves the amount out of the user's available balance and into a hold tied to that one order. Held funds cannot be withdrawn, put on another order or used to pay another fee, which is what stops the same money being spent twice. When the order fills, the hold pays for it, and anything left over is released.
How much is held depends on the order:
A limit buy holds its price times its quantity, plus the largest fee it could pay.
A market buy for an amount ("500 USDT of Bitcoin") holds that amount.
A market buy for a quantity holds the quantity times a protection price, the worst price the order will accept, plus the fee.
The same moment carries the other checks: the market is open, the order is within its minimum and maximum size, and its price is inside the market's price band. In the EU, MiCA asks a trading platform's systems to be able to "reject orders that exceed pre-determined volume and price thresholds or are clearly erroneous" (Article 76(7)(d)).
Step 2: market or limit
Every order is one of two kinds, whether the user knows it or not:
A market order says "buy now, at the best prices available". It never waits, so its final price is not known until it fills.
A limit order says "buy at this price or better". If no seller offers that price, the order waits on the book until one does, or until the user cancels it.
A simple Buy button usually sends a market order with a protection price behind it, which makes it a limit order in all but name: buy now, but not at any price. How the simple screen and the trading terminal share one market is covered in simple or pro.
Step 3: the order book and the spread
The order book is every resting offer to buy or sell one asset for another, sorted by price. Buy orders (bids) are ranked from the highest price down; sell orders (asks) from the lowest price up. The best buyers sit on one side, the best sellers on the other.

The gap between the best bid and the best ask is the spread. In our example market, BTC/USDT, the best bid is 59,990 and the best ask is 60,000, so the spread is 10 USDT. A narrow spread means a buyer pays little above the middle price; a wide one means the market is thin.
The other side of the trade is other users and market makers, who keep orders resting on both sides. Under MiCA the operator is not one of them: an operator of a trading platform "shall not deal on own account on the trading platform for crypto-assets they operate", and may use matched principal trading only where the client has consented (Article 76(5) and (6)). The operator's wider obligations are in the MiCA checklist.
Step 4: the matching engine and price-time priority
The matching engine owns the order book of each market and takes orders one at a time, in a single sequence. For each incoming order it looks for a resting order on the other side at an acceptable price.
It answers by price-time priority:
Price first. A buy is matched against the lowest ask before any higher one.
Then time. Among resting orders at the same price, the one that arrived first fills first.
The rule is mechanical on purpose: the same orders in the same sequence always produce the same trades, and no one chooses who gets filled. The incoming order that trades at once is the taker; the resting order it meets is the maker. A limit order that does not cross the spread simply joins the book and waits to be a maker.
Because there is one engine per market, a buy from the web and a buy from a phone meet the same book at the same price.
Step 5: partial fills and slippage
Our user buys 0.5 BTC at market, with a protection price of 60,050 USDT. The best ask offers only 0.20 BTC, so the engine takes it and moves to the next seller, and the next, until the order is filled.
Resting sell order | Price (USDT) | Offered (BTC) | Filled for this buy (BTC) | Cost (USDT) |
|---|---|---|---|---|
A | 60,000 | 0.20 | 0.20 | 12,000.00 |
B | 60,010 | 0.25 | 0.25 | 15,002.50 |
C | 60,025 | 0.40 | 0.05 | 3,001.25 |
Total | 0.50 | 30,003.75 |
One order became three trades, each with its own price and trade ID. Seller C's order stays on the book with 0.35 BTC left, at the same place in the queue.
The average price is 30,003.75 / 0.5 = 60,007.50 USDT. The screen showed 60,000, so the order paid 7.50 USDT per Bitcoin more, 3.75 USDT in all: that difference is slippage. Had the book run out of sellers below 60,050, the protection price would have stopped the order there, and the unfilled part would have been cancelled or left resting, depending on the exchange's rules.
Step 6: the ledger records both legs, and the fee
A double-entry ledger records every movement twice: taken from one account, given to another. For each asset, the entries of a trade add up to zero, so nothing is created or lost.
For our buy, with an illustrative fee of 0.1% (fees are the operator's choice, as how exchanges make money explains), the entries are:
Fill A: 12,000.00 USDT from the buyer's hold to seller A; 0.20 BTC from seller A's hold to the buyer.
Fills B and C: the same pattern, at their own prices and sizes.
The fee: 30.00 USDT from the buyer's hold to the exchange's fee account. Each seller's own fee is recorded the same way.
The release: the hold was 30,055.03 USDT (0.5 x 60,050, plus the largest possible fee). The trades and the fee used 30,033.75, so 21.28 USDT returns to the buyer's available balance.

Nothing in this touches a blockchain. The coins stay in the exchange's wallets, held by the operator or a custodian it appoints, and the ledger says whose they are; a transaction appears on chain only when someone deposits or withdraws. That is why reconciliation, checking the ledger against the wallets and the engine's trades, is routine work rather than an audit-time task.
Step 7: the receipt
The receipt is read from the ledger, not from the screen's estimate, so it shows what actually happened:
Paid: 30,033.75 USDT, the trades plus the fee
Received: 0.5 BTC
Fee: 30.00 USDT
Average price: 60,007.50 USDT
Order ID and time, which tie the receipt to every fill behind it
Put next to the preview, the receipt makes any difference visible: here, the slippage. The order ID also serves the regulator: MiCA asks a trading platform to keep the data on all orders for at least five years, including what links an order with the transactions that stem from it (Article 76(15)).
You can see this in Marengo, our exchange: each fill lands on a double-entry ledger with its order ID, price, fee and time, and the receipt shows what was paid, what was received, the fee, the average price, the order ID and the time.
Why exactly-once processing and recovery matter
Everything above can fail in the middle. A user taps Buy twice, a phone retries on a weak connection, or a server restarts between the second fill and the third. An order processed twice buys twice; an order lost halfway leaves money held and no coins.
Exchanges handle this with a few well-known techniques:
An idempotency key. The app gives each order a unique ID before sending it, and a repeat with the same ID returns the first result instead of creating a second order.
One log in front of the engine. Orders are written to a sequenced log and the engine reads them in that order. A deterministic engine turns the same sequence into the same trades every time.
Snapshots and replay. The engine saves its book at intervals. After a restart it loads the last snapshot and replays the log since, arriving at exactly the state it had.
Change and event together. Each service writes its change and the event announcing it in one database transaction, and every consumer ignores an event it has already seen, so nothing is lost or counted twice between the engine, the ledger and the wallets.
Reconciliation as the last line, catching anything the first four missed.
Marengo, our exchange, works this way: its web and phone apps send orders to one deterministic matching engine, which processes each order exactly once on Kafka and recovers from snapshots by replaying its log.
FAQ
Does buying on a centralised exchange create a blockchain transaction? No. A trade moves balances between accounts on the exchange's ledger, while the coins stay in its wallets. A blockchain transaction happens when coins are deposited or withdrawn.
What happens to a limit order that only partly fills? The filled part becomes trades, and the rest stays on the book at its price and place in the queue. Its hold shrinks with each fill, and cancelling the rest releases what remains.
Why did I pay more than the price on the screen? Two reasons, both on the receipt: the fee, and slippage, when the order had to fill against several sellers at rising prices. A protection price caps the second.
What if the exchange restarts while an order is being matched? A well-built engine restarts from its last snapshot, replays its log and reaches the same state, so the order fills once.
See the second for yourself
The clearest way to follow the second after Buy is to press it. Open Marengo at marengo.paynoramic.com, buy in Lite, then switch to Pro and find the same trade among your fills. If you are planning an exchange of your own, the white-label crypto exchange page sets out what is built and handed over.



