Strasmore Research
Learn Matt ConnorBy Matt Connor

Why a Limit Order Didn't Fill: 5 Causes

The tape printed your price and your order is still open. Here are the five reasons a limit order didn't fill, in order of how often each one happens.

A limit order didn't fill even though the tape printed your price. That is the most common execution complaint a self-directed trader has, and the answer is mechanical rather than mysterious. A limit order fixes the worst price you will accept. It never promises that anybody will trade with you at that price.

Below are the five explanations, ordered roughly by how often each one turns out to be the real answer. If the two basic order types are still new to you, start with market order vs limit order and come back.

Why a limit order didn't fill when the tape hit your price

The first thing that trips up almost everyone: "the price" is not one place. US equities trade on more than a dozen exchanges plus a long tail of off-exchange venues, and the consolidated tape you watch stitches all of them into one stream of prints. Your order does not live on that stream. It rests on one specific book, wherever your broker routed it.

So a print at your price can happen several miles away, on a venue your order never reached, and your order will sit untouched while the quote on your screen flickers at exactly your number. The panel below splits one regular session of Apple trading by the venue that reported each print.

QueryWhere one session of AAPL prints actually happened, by venue
venueshares_millionspct_of_sharesprints
FINRA Alternative Display Facility11.4847.6381723
Nasdaq5.723.6112627
NYSE Arca, Inc.1.93858899
Cboe BZX1.295.434106
Investors Exchange0.933.923913
New York Stock Exchange0.83.321812
Cboe EDGX0.672.814560
Members Exchange0.411.710334
NYSE Texas, Inc.0.31.31310
Cboe BYX0.120.53199
Cboe EDGA0.120.54146
Nasdaq Texas, Inc.0.110.43516
MIAX Pearl0.070.31645
Texas Stock Exchange LLC0.060.31720
Nasdaq Philadelphia Exchange LLC0.050.21272
The exact SQL behind every number
SELECT
    venue,
    round(shares / 1e6, 2)                        AS shares_millions,
    round(100 * shares / sum(shares) OVER (), 1)  AS pct_of_shares,
    prints
FROM
(
    SELECT
        any(if(empty(x.name), concat('Venue ', toString(t.exchange)), x.name)) AS venue,
        sum(t.size)                                                           AS shares,
        count()                                                               AS prints
    FROM global_markets.stocks_trades AS t
    LEFT JOIN global_markets.stocks_exchanges AS x ON x.id = t.exchange
    WHERE t.ticker = 'AAPL'
      AND t.sip_timestamp >= '2026-09-15 00:00:00'
      AND t.sip_timestamp <  '2026-09-16 00:00:00'
      AND (toHour(toTimeZone(t.sip_timestamp, 'America/New_York')) * 60
           + toMinute(toTimeZone(t.sip_timestamp, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(t.sip_timestamp, 'America/New_York')) * 60
           + toMinute(toTimeZone(t.sip_timestamp, 'America/New_York'))) < 960
    GROUP BY t.exchange
)
ORDER BY shares_millions DESC
LIMIT 15
Run this yourself

On that single September 2026 session, Apple's regular-session prints landed across 15 separate venues. The busiest of them, FINRA Alternative Display Facility, carried 47.6% of the shares: 11.48 million shares over 381723 prints. Every other line in that table is a place where a trade at your limit price leaves your order exactly where it was.

Was I behind size at the same price?

The second explanation is a queue. At one price on one book, exchanges fill resting orders in arrival order. Price comes first, time stamp second, which is what traders mean by price-time priority (the mechanics, including the venues that split fills pro rata instead, are in price-time priority vs pro rata).

Take a hypothetical. You post 1,000 shares to buy at $50.00. At that moment 40,000 shares are already displayed at $50.00, posted ahead of you. A seller arrives with 5,000 shares to dump at the bid. Those 5,000 shares go to the front of the line, which is still 35,000 shares away from you. The tape prints $50.00 several times, your price is "trading", and your 1,000 shares have not moved an inch. To fill you, the market has to grind through 40,000 shares at that price without ever ticking up.

How likely is that? The panel below counts the shares that actually changed hands at each of the lowest cent levels Coca-Cola touched during one regular session.

QueryShares traded at KO's lowest price levels in one session
price_levelshares_tradedprints
$87.8101.0094273
$87.812.3462542
$87.821712.31826422
$87.83393.65438219
$87.842891.3864237
$87.858008.79809980
$87.8617872.195448161
$87.876140.333807106
The exact SQL behind every number
SELECT
    concat('$', toString(round(toFloat64(price), 2))) AS price_level,
    sum(size)                                         AS shares_traded,
    count()                                           AS prints
FROM global_markets.stocks_trades
WHERE ticker = 'KO'
  AND sip_timestamp >= '2026-09-15 00:00:00'
  AND sip_timestamp <  '2026-09-16 00:00:00'
  AND (toHour(toTimeZone(sip_timestamp, 'America/New_York')) * 60
       + toMinute(toTimeZone(sip_timestamp, 'America/New_York'))) >= 570
  AND (toHour(toTimeZone(sip_timestamp, 'America/New_York')) * 60
       + toMinute(toTimeZone(sip_timestamp, 'America/New_York'))) < 960
GROUP BY price_level
ORDER BY min(price)
LIMIT 8
Run this yourself

Across the 8 lowest levels that printed, the very bottom one, $87.8, saw 101.009427 shares change hands over 3 prints. One level up, at $87.81, the total was 2.346254 shares. A queue 40,000 deep does not clear on flow like that, and the reader whose order sat at the bottom level watched their price print all day. Estimating your queue position before you post is the practical defence.

Does an odd lot count as hitting my price?

An odd lot is a trade for fewer than 100 shares. Odd lots reach the consolidated tape like any other print, and they are left out of the national best bid and offer. A 37-share trade at your limit is a genuine trade that never disturbed the protected quote, and it was never required to interact with your order at all. Why odd lots don't set the NBBO covers the rule in full.

This matters more than it sounds, since odd lots dominate the print count on higher-priced names.

QueryOdd lots versus round lots in one AAPL session: prints and shares
trade_size_bucketprintspct_of_printspct_of_shares
1 to 99 (odd lot)61867893.345.3
100 to 499409366.227.4
500 to 99921090.35.7
1,000 to 9,99911860.29.1
10,000 and up26012.4
The exact SQL behind every number
SELECT
    bucket                                       AS trade_size_bucket,
    prints,
    round(100 * prints / sum(prints) OVER (), 1) AS pct_of_prints,
    round(100 * shares / sum(shares) OVER (), 1) AS pct_of_shares
FROM
(
    SELECT
        multiIf(size < 100,   '1 to 99 (odd lot)',
                size < 500,   '100 to 499',
                size < 1000,  '500 to 999',
                size < 10000, '1,000 to 9,999',
                              '10,000 and up') AS bucket,
        count()                                AS prints,
        sum(size)                              AS shares
    FROM global_markets.stocks_trades
    WHERE ticker = 'AAPL'
      AND sip_timestamp >= '2026-09-15 00:00:00'
      AND sip_timestamp <  '2026-09-16 00:00:00'
      AND (toHour(toTimeZone(sip_timestamp, 'America/New_York')) * 60
           + toMinute(toTimeZone(sip_timestamp, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(sip_timestamp, 'America/New_York')) * 60
           + toMinute(toTimeZone(sip_timestamp, 'America/New_York'))) < 960
    GROUP BY bucket
)
ORDER BY indexOf(['1 to 99 (odd lot)', '100 to 499', '500 to 999', '1,000 to 9,999', '10,000 and up'], trade_size_bucket)
Run this yourself

Over the same session, trades of fewer than 100 shares made up 93.3% of all prints and carried 45.3% of the shares. Read those two figures side by side rather than ranking them: whatever slice of the day's volume arrives in sub-100-share pieces, every one of those pieces is a print that sat outside the quote your order is pegged against.

Was I watching the NBBO instead of my own venue's book?

The number on a retail quote screen is usually the national best bid and offer: the highest bid and the lowest offer found anywhere across the venues, assembled from every exchange's feed. It is a composite. No single book necessarily shows it, and your order rests in exactly one book. The bid that "reached your price" may have belonged to a venue on the other side of the market from you. What the NBBO is walks through how that composite is built, and level 1 vs level 2 market data shows what you give up by watching one line instead of a book.

Two related wrinkles. Free retail quotes are often fifteen minutes stale, which is covered in why stock quotes are delayed 15 minutes, and during a locked market your bid can sit equal to somebody else's offer without either one executing, described in locked and crossed markets.

Was my order marketable at all?

A buy limit placed above the current offer is marketable: it can execute immediately against what is already there. A buy limit placed below the current bid is non-marketable: it joins the book and waits for the market to come down to it. Non-marketable is the normal state for a patient order, and the full distinction lives in marketable vs non-marketable limit orders.

An order parked a few cents away can spend the whole day untouched. The panel below counts, for five household names on the same date, how many one-minute bars came within a penny and within five cents of each name's own session low.

QueryMinutes a session spends near its own low, five household names
tickerminutes_within_a_pennyminutes_within_five_centsminutes_in_session
KO11390
MSFT13390
SPY11390
AAPL11390
NVDA12390
The exact SQL behind every number
WITH bars AS
(
    SELECT
        ticker,
        toFloat64(low) AS low_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO')
      AND window_start >= '2026-09-15 00:00:00'
      AND window_start <  '2026-09-16 00:00:00'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
),
lows AS
(
    SELECT
        ticker,
        min(low_px) AS session_low
    FROM bars
    GROUP BY ticker
)
SELECT
    b.ticker                                  AS ticker,
    countIf(b.low_px <= l.session_low + 0.01) AS minutes_within_a_penny,
    countIf(b.low_px <= l.session_low + 0.05) AS minutes_within_five_cents,
    count()                                   AS minutes_in_session
FROM bars AS b
INNER JOIN lows AS l ON l.ticker = b.ticker
GROUP BY b.ticker
ORDER BY minutes_within_a_penny
Run this yourself

Read the first row. KO printed 390 one-minute bars in that regular session, and only 1 of them came within a penny of the day's low. Widening the band to five cents brings the count to 1. A limit resting at or under the low has a window measured in minutes out of a six-and-a-half-hour day, and inside that window it still has to clear the queue from the section above.

Chasing the price with cancel and replace resets your place in line

The instinct, once an order has sat for an hour, is to move it a penny closer. Be aware of what that costs. On nearly every venue a change to the price of a resting order is processed as a cancel plus a brand new order, and the new order arrives at the back of the queue at the new price. You traded a good position in a line you had been standing in for an hour for a worse position in a different line. The same applies to increasing displayed size. Order modification and queue priority lists which amendments keep priority and which forfeit it.

Partial fills are the normal middle case

The third outcome, between "filled" and "open", is the one readers forget. A 1,000-share limit can come back as 200 shares done and 800 still working, often at several different time stamps. That is the queue reaching you and then stopping, exactly as the mechanics predict. The 800 shares keep their place and keep working until the time in force runs out.

What to check on your own order

Three things are visible to you, no market-structure background required.

  • Time in force. A day order expires at the close of the regular session and is gone, even if the market touched your price at 4:02 p.m. A good-till-cancelled order survives the night. An order marked regular-hours-only never saw the extended session at all, and why overnight orders must be limit orders explains how the rules change after hours.
  • The venue. Your execution report or trade confirmation names the exchange or market centre that handled the order. Compare it against the venue column in the first panel above and the "my price printed" mystery usually dissolves on the spot.
  • The fill detail. Brokers show the executed quantity, the price of each fill, and the time stamp. A string of small fills at one price is a queue that reached you late. A completely empty report alongside a tape full of your price points back to venue, queue depth, or odd lots.

One line is worth keeping in front of you through all of this. A limit order guarantees your price and never guarantees your execution. A market order inverts that trade: it guarantees execution and surrenders the price.

FAQ

Does a limit order guarantee a fill?

No. A limit order guarantees only that you will not trade worse than your limit price. Execution depends on another participant choosing to trade with your order at that price, on the venue where your order rests, after everyone who was already in the queue ahead of you.

Why didn't my limit order fill when the stock traded at my price?

The common answers, roughly in order: the print happened on a different venue, you were behind resting size at that price and the queue never reached you, the print was an odd lot that never set the national quote, or you were watching the composite national quote rather than the book your order actually sat on.

Can a limit order be skipped?

It can be passed over, which feels the same. Trading at your price is not a promise of a fill, since fills go in queue order on one book, and trade-through protection applies to the protected quote rather than to your individual order.

Why did I get a partial fill on a limit order?

The queue reached your order and then ran out of willing counterparties at your price. The filled portion settles normally, and the remainder stays open at the same price with its original time stamp until the time in force expires or you cancel it.

Does cancelling and re-entering a limit order help it fill?

Moving the price makes the order more aggressive, which raises the odds of trading, and it also sends you to the back of the queue at the new price. The two effects pull in opposite directions, and the trade-off is worth understanding before you reflexively chase.


Every panel on this page carries the exact SQL that produced it, one click underneath the table. To check the venue split or the price-level volume for your own symbol and date, ask the question in plain English on the Strasmore terminal.