Why Stock Quotes Are Delayed 15 Minutes
Why are stock quotes delayed 15 minutes? How exchange data licensing sets the rule, and what a quarter hour of staleness actually costs on real prices.
Stock quotes are delayed 15 minutes on most free websites for a licensing reason. The plumbing is not slow: a price leaves an exchange matching engine and reaches a screen in a fraction of a second. The 15 minutes is a contract term, written into the agreements that decide who may show live prices and what they pay for it.
Where a stock price comes from before it reaches you
A single US stock trades in more than a dozen public venues at once, alongside a long tail of off exchange trading that reports its prints separately. Each venue publishes its own quotes and trades. Industry plans consolidate all of it into one tape, one plan covering NYSE listed names and another covering Nasdaq listed names, and the processors running them are the SIPs, short for securities information processors. That consolidated tape produces the national best bid and offer, the best price pair available anywhere at that instant, explained in full in our guide to what the NBBO is.
Exchanges also sell their own direct feeds, faster and more detailed than the consolidated tape and licensed separately from it.
Why stock quotes are delayed 15 minutes: the licensing answer
Market data is an exchange revenue line. Every distributor of prices, a broker, a website, a terminal, a phone app, signs agreements with the exchanges and the tape plans, and those agreements split the same numbers into two products. Real time data is fee bearing and reported per user every month. Delayed data, once it is at least 15 minutes old, sits outside the real time schedule, and a distributor can give it away without counting heads.
The schedules stack several charges: an access fee for the pipe, a per user monthly fee for every person who can see a live price, and non display fees for machines that consume prices with no human watching. Rates are filed publicly and change most years, so the structure matters more than this year's numbers. Someone pays per person per month for live prices. Nobody pays for a price that is a quarter of an hour stale.
That is the whole answer to why the free version is free. Volume is the other half of the cost of carrying live prices: the tape runs a continuous stream of quote updates through the session, and options are the extreme case, as the size of the options quote feed shows.
What a 15 minute delay is actually worth
A delay matters to the extent the price moves inside it, which is measurable. The panel below takes every regular session minute bar in SPY, the S&P 500 tracking fund, through June 2026 and compares each one against the bar 15 minutes later, grouped by the hour the earlier bar fell in.
The exact SQL behind every number
WITH regular_bars AS
(
SELECT
toTimeZone(window_start, 'America/New_York') AS et,
toTimeZone(window_start, 'America/New_York') + INTERVAL 15 MINUTE AS et_later,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND close > 0
AND window_start >= '2026-06-01 00:00:00'
AND window_start < '2026-07-01 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
)
SELECT
formatDateTime(toStartOfHour(a.et), '%H:%i') AS et_time,
round(quantileDeterministic(0.5)(abs(b.px / a.px - 1) * 100, toUInt64(toUnixTimestamp(a.et))), 3) AS median_gap_pct,
round(quantileDeterministic(0.95)(abs(b.px / a.px - 1) * 100, toUInt64(toUnixTimestamp(a.et))), 3) AS p95_gap_pct,
count() AS sample_count
FROM regular_bars AS a
INNER JOIN regular_bars AS b ON b.et = a.et_later
GROUP BY et_time
ORDER BY et_timeBars stamped in the opening hour, which begins at 9:30 a.m. ET, moved a median of 0.125% over the following 15 minutes, with a 95th percentile of 0.556%. In the 15:00 hour the median was 0.065%. Each bucket pools 630 overlapping minute pairs, so these are typical figures rather than one day's accident. The curve is not flat, and a fixed delay hides more at some hours than others.
How much it hides depends on the name as well. Same measurement, six household tickers, same month.
The exact SQL behind every number
WITH regular_bars AS
(
SELECT
ticker,
toTimeZone(window_start, 'America/New_York') AS et,
toTimeZone(window_start, 'America/New_York') + INTERVAL 15 MINUTE AS et_later,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'AMD')
AND close > 0
AND window_start >= '2026-06-01 00:00:00'
AND window_start < '2026-07-01 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
)
SELECT
a.ticker AS ticker,
round(quantileDeterministic(0.5)(abs(b.px / a.px - 1) * 100, toUInt64(toUnixTimestamp(a.et))), 3) AS median_gap_pct,
round(quantileDeterministic(0.99)(abs(b.px / a.px - 1) * 100, toUInt64(toUnixTimestamp(a.et))), 3) AS p99_gap_pct
FROM regular_bars AS a
INNER JOIN regular_bars AS b ON b.ticker = a.ticker AND b.et = a.et_later
GROUP BY ticker
ORDER BY median_gap_pct DESCAMD carried the widest typical gap of the six at 0.361%, and SPY the narrowest at 0.071%. The 99th percentile column is the one to read twice: across its worst one percent of 15 minute windows that month, AMD travelled 2.532%.
Here is the same idea on one day. The panel finds the June 2026 session with the widest intraday range in SPY, then draws two lines: the live tape at each ten minute mark, and what a 15 minute delayed page was showing at that moment.
The exact SQL behind every number
WITH
widest_session AS
(
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND close > 0
AND window_start >= '2026-06-01 00:00:00'
AND window_start < '2026-07-01 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
GROUP BY d
ORDER BY (max(toFloat64(high)) - min(toFloat64(low))) / min(toFloat64(low)) DESC
LIMIT 1
),
session_bars AS
(
SELECT
toTimeZone(window_start, 'America/New_York') AS et,
toTimeZone(window_start, 'America/New_York') - INTERVAL 15 MINUTE AS et_earlier,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND close > 0
AND toDate(toTimeZone(window_start, 'America/New_York')) IN (SELECT d FROM widest_session)
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
)
SELECT
formatDateTime(a.et, '%H:%i') AS et_time,
round(a.px, 2) AS live_price,
round(b.px, 2) AS delayed_price,
round(abs(a.px - b.px), 2) AS gap_delta,
formatDateTime(a.et, '%b %e') AS session_label
FROM session_bars AS a
INNER JOIN session_bars AS b ON b.et = a.et_earlier
WHERE toMinute(a.et) % 10 = 0
ORDER BY a.etOn Jun 9, at 09:50 ET, live SPY was 746.13 while the delayed view read 744.22, $1.91 away from it. By 15:50 the pair read 735.29 and 734.49. The lines overlap whenever the tape is quiet and separate whenever it moves. A delay costs nothing on a still market and the most at the moments people are watching.
The display rule: what a website has to show you
Regulation NMS carries a consolidated display requirement, Rule 603(c). A vendor showing quotation data to the public has to present consolidated information, the national best bid and offer with the consolidated last sale, rather than one venue's quote dressed up as the price. Vendors must also identify delayed data as delayed, which is where the small print at the bottom of every finance page comes from. Two things follow for anyone reading a free quote.
- A free live quote from a single exchange is a real price and it is not the NBBO. It shows one venue's book, which can sit wider than the best available.
- A page with a live last trade and no bid or ask is ordinary. Last sale and quotes are separately licensed products, and last sale is the cheaper one.
For what happens when two venues meet at the top of the book, see locked and crossed markets.
Professional or non professional: the test that sets your bill
What live data costs an individual turns on a classification, and the classification turns on your job rather than your money. You count as a non professional subscriber, in the language the exchanges use, when all of the following hold.
- You are a natural person taking the data for personal use, not on behalf of a company or any other entity.
- You are not registered or qualified with the SEC, the CFTC, a state securities agency, a securities exchange or association, or a futures contract market.
- You are not engaged as an investment adviser or an asset manager, and you are not employed to do work that would require one of those registrations.
- You put the data to no business use, including at an employer who reimburses the subscription.
Fail one and the exchanges class you as professional, billed per exchange, per user, per month, at a multiple of the non professional rate. A junior analyst at a fund with a small personal account is professional; a retired investor with a large portfolio, trading only their own money, is not. Distributors are obliged to collect your answer and report it, which is why every live data signup asks about your employer and your registrations.
What is a snapshot quote?
A snapshot is one reading taken at the moment you ask: the last price, or the current bid and ask, returned once and never updated. A stream is a standing subscription, with every change pushed as it happens. Licensing prices the two differently, often per query against per user per month, which is why a free API will hand you a delayed snapshot endpoint and no live stream. Refresh a snapshot every second and you have rebuilt a stream, and the agreements are written to catch that.
How to tell whether the price in front of you is delayed
- The timestamp is the only reliable tell. A live quote is stamped within a second or two of the current ET clock.
- The day's high and the running volume go stale as well, so a delayed page can miss a high the tape set ten minutes ago.
- For the first 15 minutes after the 9:30 a.m. ET open, a delayed page has nothing from the current session, and shows the previous close or a premarket print.
- The freeze test, watching whether the number moves at all, only works on names that move.
That last one needs data behind it.
The exact SQL behind every number
WITH regular_bars AS
(
SELECT
ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
toTimeZone(window_start, 'America/New_York') AS et,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'AMD')
AND close > 0
AND window_start >= '2026-06-01 00:00:00'
AND window_start < '2026-07-01 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
),
stepped AS
(
SELECT
ticker,
et,
px,
lagInFrame(px) OVER (PARTITION BY ticker, session_date ORDER BY et
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_px
FROM regular_bars
)
SELECT
ticker,
round(100 * countIf(px != prev_px) / count(), 1) AS minutes_price_moved_pct,
round(quantileDeterministic(0.5)(abs(px / prev_px - 1) * 10000, toUInt64(toUnixTimestamp(et))), 1) AS median_move_bps
FROM stepped
WHERE prev_px > 0
GROUP BY ticker
HAVING count() > 0
ORDER BY minutes_price_moved_pct DESCThrough June 2026, AMD printed a price different from the previous minute in 99.8% of regular session minutes, with a median minute to minute move of 9.6 basis points, a basis point being one hundredth of one percent. KO repainted least often of the six, at 94.1%. On names this active, a last price that has not budged for several minutes in the middle of a session is a fair hint you are looking at a delayed or cached number. On a thinly traded stock the same stillness is ordinary, which is why the timestamp stays the test.
Which free stock quotes are genuinely real time
Two sources reliably carry live prices for a private individual, and one common label deserves a second look.
- A funded brokerage account. Brokers carry the non professional entitlement for their customers and pass live quotes through the app, which is why the account opening form asked about your employer.
- An exchange operator's own website, for the names that exchange lists. Real time and single venue, so it is one book rather than the consolidated NBBO.
- Anything advertising free real time quotes with no login and no self certification. Check the stamp on the quote before relying on it.
When the destination is a program rather than a screen, the classification shifts again: machine consumption is licensed under non display terms, a separate schedule from the per user one. Our writeups on free stock market data APIs and querying market data with SQL cover those tiers.
FAQ
Why are stock quotes delayed exactly 15 minutes?
Fifteen minutes is the age at which US equity prices stop being a fee bearing real time product under exchange data agreements. A distributor can publish anything at least that old without reporting a user count.
What makes someone a professional market data subscriber?
Registration with a securities or futures regulator, employment in an investment role, taking the data on behalf of an entity, or any business use of the prices. Net worth and account size play no part in it.
How can I tell if a stock quote is delayed?
Check the quote timestamp against the current ET clock, and look for the delayed label vendors are required to display. On an active name during regular hours, a price that sits still for minutes at a time is a further hint.
Are free real time quotes the same as the NBBO?
Often not. A single exchange's free quote shows that one venue's book. The NBBO is the best bid and offer across every venue, computed from the consolidated tape.
Does the 15 minute delay matter for end of day data?
No. Once a session closes, the delayed and the real time version of a closing price or a daily volume figure are identical. The delay only bites inside the session.
Every panel here ships with the SQL that produced it, so any number above can be recounted on another ticker or another month. To measure what 15 minutes is worth on a name you follow, ask for it in plain English on the Strasmore terminal.