A friend of mine once spent ten minutes fighting an exchange because his limit buy kept getting rejected the moment he submitted it. Same order, same price, instant rejection every time, with an error code that explained nothing. He was convinced the venue was broken, and meanwhile the venue was doing exactly what he had told it to do. He had a post-only checkbox enabled from some earlier session, the market was ticking up through his price, and the matching engine was refusing to let his order take liquidity. Nobody had ever explained the flag to him, because nobody explains any of these flags. You get a dropdown with GTC, IOC, FOK, maybe a post-only toggle, the default is GTC, and that is what most people use for everything.
The flags are collectively called time in force, and the name undersells what they do. They do control how long an order stays alive, but the more useful framing is that each one is an instruction to the matching engine about what you are willing to accept. Rest on the book and wait as long as it takes. Take whatever is available right this second and cancel the rest. Fill everything at once or nothing at all. Rest only, never take. Pick the wrong instruction and the cost usually shows up somewhere quiet, in fees, in dust positions, in an order you forgot about filling three weeks later.
What each flag tells the matching engine
GTC, good till cancelled, is the resting order. It sits on the book at your price until it fills or you cancel it. On most crypto venues that genuinely means indefinitely, or at least until the exchange runs some periodic cleanup. Traditional brokers typically cap GTC orders at somewhere around 30 to 90 days, after which they expire on their own. The important property is persistence. A GTC order does not care that you closed the app, changed your mind, or forgot it exists.
IOC, immediate or cancel, is the opposite. When the order reaches the matching engine, it matches against whatever resting liquidity exists on the other side at your limit price or better, right at that instant. Anything left unfilled is cancelled immediately. An IOC order never rests on the book, not even for a millisecond. It is a snapshot trade against the book as it exists on arrival.
FOK, fill or kill, is IOC with an extra condition. Either the entire quantity can be filled immediately against resting liquidity or the whole order cancels and nothing executes at all. You never get a partial position out of a FOK order, which sounds strictly better than IOC right up until you notice how often the full size simply is not there.
Post-only is the odd one out. Strictly speaking it is an execution instruction rather than a duration, but every venue puts it in the same corner of the order ticket, so it belongs in this conversation. A post-only order is only allowed to rest. If the price you chose would cross the spread and match immediately against an existing order, the engine rejects it instead of filling it. You are telling the exchange you will provide liquidity or do nothing.
Why post-only rejections happen, and why IOC leaves slivers
The rejection that confused my friend is the standard case. Say the best ask is 100.05 and you submit a post-only buy at 100.10. That order would match instantly, which would make you the taker, which is exactly what the flag forbids, so it bounces. The frustrating version is the race. You saw the ask at 100.15 when you clicked, so your buy at 100.10 should have rested comfortably below it. But in the few hundred milliseconds between your click and the engine processing the order, someone else sold and the ask dropped to 100.08. Your order now crosses, and it gets rejected. In a fast market this can happen five times in a row and it starts to feel personal. Some venues offer a variant that reprices instead of rejecting, sliding your order one tick below the best opposite quote so it always rests. If your exchange has that option and you use post-only a lot, turn it on.
Why bother with post-only at all. Fees, mostly. Nearly every crypto exchange charges makers less than takers, and some pay makers a small rebate. If you trade at any real volume the maker-taker gap compounds into meaningful money, and for market-making strategies that gap is roughly the entire business model. Post-only is the one way to guarantee you land on the maker side of the fee schedule. It also works as a seatbelt, since a fat-fingered limit price that would have swept through the book just gets rejected instead.
The IOC sliver problem comes from the other direction. IOC takes whatever is there, and sometimes what is there is almost nothing. You send an IOC buy for 5 units at a limit just above the market, the book happens to be thin at that moment, and you fill 0.4 units before the rest cancels. Now you hold a position you never intended at that size. If it is small enough it can fall below the venue minimum order size, so you cannot even sell it back cleanly, and it lives in your account as dust. And if a strategy sized its risk assuming the full 5 units, a 0.4 unit fill quietly breaks the math downstream. This is the trade against FOK. FOK protects you from slivers but fails outright whenever full size is unavailable, so for anything large in a thin market FOK mostly returns nothing at all.
Which flag to actually use
Here is the mapping I use, roughly in order of how often each situation comes up.
- You want to rest at a level and wait. Use GTC, but treat open GTC orders as live positions and review them at least weekly. The classic failure is a forgotten bid from a month ago filling on a violent wick, and now you are long something at a price that made sense in a completely different market.
- You want to take liquidity now without surprises. Send a limit order priced slightly through the market with IOC attached. This behaves like a market order with a ceiling on how bad your fill can get, and whatever cannot fill inside your tolerance cancels instead of chasing the book down.
- A partial position is worse than no position. Use FOK. Hedge legs, spread trades, anything where half a fill leaves you carrying directional exposure you never wanted. Expect frequent kills and have a plan for when they happen.
- You are fee sensitive and resting anyway. Use post-only, ideally the repricing variant if the venue offers it, and accept the occasional rejection as the cost of never paying taker fees by accident.
- Your thesis expires at the close. If the venue supports day orders, which traditional brokers mostly do and crypto venues mostly do not, use them, and save GTC for levels you would still want next week.
One thing I would add from building the execution layer at Blockcircle, which routes orders across more than 150 exchanges. The flags are standard in name only. One venue rejects a crossing post-only order, another reprices it, a third silently converts it to a plain limit. IOC handling of minimum fill sizes differs from venue to venue. Some APIs default to GTC, others to day, and the documentation is wrong often enough that I stopped trusting it. Before you rely on any of these flags somewhere new, place one tiny order and watch what actually happens to it. Two minutes of testing beats discovering the difference with real size on.
Defaulting everything to GTC works often enough that most people never think about it, and that holds right up until a forgotten order fills. Match the flag to the intent instead. If you know whether you want to wait, take, or make before you hit submit, the dropdown stops being decoration.