Strasmore Research
Learn Matt ConnorBy Matt Connor

Price Return vs Total Return: The Real Gap

Price return vs total return: the S&P 500 headline index leaves out dividends. See the compounding gap measured over 20 years and where each version is used.

Price return vs total return is the difference between what a market chart shows and what someone holding the same position actually earned. Price return counts the change in price alone. Total return adds every dividend back in, reinvested at the price on the day it goes ex, which lets each payment compound alongside the shares that produced it.

The headline S&P 500 level quoted in the news is a price index. Its total-return twin holds the same companies and puts the dividends back to work. Over a single year the two look nearly identical. Over twenty years they describe very different outcomes, and the distance between them is larger than the annual yield would suggest.

What is the difference between price return and total return?

Price return is the ending price divided by the starting price, minus one. Every index level quoted on television and every price chart you have ever scrolled through is this number.

Total return runs the same calculation with each cash dividend used to buy more shares at the price on its ex-dividend date. Fund performance tables and the benchmark indexes those funds are measured against use this version.

A hypothetical makes the mechanics concrete. Buy a share at $100 that pays $2 a year, then sell it a year later at $105. Price return is 5%. Total return is roughly 7%. That first year is unremarkable. The compounding is what earns the distinction a page of its own: the reinvested $2 buys a fraction of another share, that fraction collects its own dividend the following year, and the two series pull apart at an accelerating rate.

One disambiguation before the data. A total return swap is a derivative contract in which one party passes along the full economics of an asset in exchange for a financing rate. It shares a name and nothing else with the index convention below. The rest of this page stays with indexes and funds.

How big is the gap on the S&P 500?

$10,000 into the largest S&P 500 tracker at the end of 2005, held to July 31, 2026. The first line spends every dividend the day it lands. The second reinvests each one at that day's closing price.

Query$10,000 in the S&P 500 tracker: price only vs dividends reinvested, year-end 2006 to July 2026
The exact SQL behind every number
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2005-12-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
base AS (
    SELECT argMax(close, d) AS start_px
    FROM daily
    WHERE d <= toDate('2005-12-31')
),
year_end AS (
    SELECT toYear(d) AS year,
           argMax(close, d) AS close,
           max(d) AS last_day
    FROM daily
    WHERE d >= toDate('2006-01-01')
    GROUP BY year
),
reinvest AS (
    SELECT dv.ex_dividend_date AS d,
           log(1 + toFloat64(dv.cash_amount) / dl.close) AS log_growth
    FROM global_markets.stocks_dividends AS dv
    INNER JOIN daily AS dl ON dl.d = dv.ex_dividend_date
    WHERE dv.ticker = 'SPY'
      AND dv.cash_amount > 0
      AND dv.ex_dividend_date >= toDate('2006-01-01')
      AND dv.ex_dividend_date <= toDate('2026-07-31')
)
SELECT ye.year AS year,
       round(10000 * ye.close / any(b.start_px)) AS price_only_usd,
       round(10000 * ye.close / any(b.start_px) * exp(sum(ri.log_growth))) AS reinvested_usd,
       round(100 * (1 - exp(-sum(ri.log_growth))), 1) AS dividend_share_pct
FROM year_end AS ye, reinvest AS ri, base AS b
WHERE ri.d <= ye.last_day
GROUP BY ye.year, ye.close
ORDER BY year
Run this yourself

The price-only line finishes at $59956. The reinvested line finishes at $85775. Dividends account for 30.1% of that ending balance, and none of it appears on a price chart.

The left edge of the chart is where this catches people out. At the end of 2007 the two lines sat at $11755 and $11971, with dividends worth 1.8% of the balance. A first-year gap that small files easily as a rounding detail. Twenty years of the same rounding detail, each one compounding on the last, produces the spread at the right edge.

Does the gap keep widening with time?

Same fund, same end date, five different start dates.

QueryPrice return vs total return by holding period: S&P 500 tracker, windows ending July 31, 2026
The exact SQL behind every number
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2006-07-31')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
spans AS (
    SELECT y AS years,
           concat(toString(y), '-year') AS horizon,
           subtractYears(toDate('2026-07-31'), y) AS start_date
    FROM (SELECT arrayJoin([1, 3, 5, 10, 20]) AS y)
),
divs AS (
    SELECT dv.ex_dividend_date AS d,
           log(1 + toFloat64(dv.cash_amount) / dl.close) AS log_growth
    FROM global_markets.stocks_dividends AS dv
    INNER JOIN daily AS dl ON dl.d = dv.ex_dividend_date
    WHERE dv.ticker = 'SPY'
      AND dv.cash_amount > 0
      AND dv.ex_dividend_date <= toDate('2026-07-31')
),
endpoints AS (
    SELECT s.horizon AS horizon,
           s.years AS years,
           argMin(dl.close, dl.d) AS start_px,
           argMax(dl.close, dl.d) AS end_px
    FROM spans AS s, daily AS dl
    WHERE dl.d >= s.start_date
    GROUP BY s.horizon, s.years
),
reinvest AS (
    SELECT s.years AS years,
           exp(sum(dvs.log_growth)) AS factor
    FROM spans AS s, divs AS dvs
    WHERE dvs.d > s.start_date
    GROUP BY s.years
)
SELECT e.horizon AS horizon,
       round(100 * (e.end_px / e.start_px - 1), 1) AS price_return_pct,
       round(100 * (e.end_px / e.start_px * r.factor - 1), 1) AS total_return_pct,
       round(100 * (e.end_px / e.start_px) * (r.factor - 1), 1) AS dividend_points_pct
FROM endpoints AS e
INNER JOIN reinvest AS r ON e.years = r.years
ORDER BY e.years
Run this yourself

Over the 1-year window, price return was 18.2% against a total return of 19.5%, a difference of 1.3 percentage points. The 10-year window separates 244.3% from 304.5%, worth 60.2 points. Over the 20-year window the two readings are 485% and 736.9%: a difference of 251.9 percentage points.

The curve does not rise in a straight line. It rises the way the balance does, since each reinvested dividend joins the base that the next one compounds on.

Why one year of dividends looks trivial

Here is every calendar year of the same window, split into the price move and the dividend contribution.

QueryS&P 500 tracker by calendar year: price return vs the points added by reinvested dividends
The exact SQL behind every number
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2006-01-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
yearly AS (
    SELECT toYear(d) AS year,
           argMin(close, d) AS first_px,
           argMax(close, d) AS last_px
    FROM daily
    GROUP BY year
),
divs AS (
    SELECT toYear(dv.ex_dividend_date) AS year,
           exp(sum(log(1 + toFloat64(dv.cash_amount) / dl.close))) AS factor
    FROM global_markets.stocks_dividends AS dv
    INNER JOIN daily AS dl ON dl.d = dv.ex_dividend_date
    WHERE dv.ticker = 'SPY'
      AND dv.cash_amount > 0
    GROUP BY year
)
SELECT y.year AS year,
       round(100 * (y.last_px / y.first_px - 1), 1) AS price_return_pct,
       round(100 * (y.last_px / y.first_px) * (d.factor - 1), 2) AS dividend_points_pct
FROM yearly AS y
INNER JOIN divs AS d ON y.year = d.year
ORDER BY year
Run this yourself

Read the two series together. The price line is the loud one, swinging hard in both directions. The dividend line is the quiet one: 1.9 points in 2007, 0.58 points in the partial year to July 2026, and never the headline in between. No single row of that panel would change anyone's mind about anything. Stacked and compounded across 20 rows, those same small numbers are the entire distance between the two lines in the first chart. Reinvesting a dividend is also automatic buying at whatever price prevails that day, a close cousin of dollar cost averaging. It is the same reason the S&P 500 dividend yield reads as a modest number while mattering far more over long windows than its size suggests.

Which stocks show the widest gap?

The gap tracks the yield: a company handing back more per dollar of price gives the holder more to reinvest. Seven familiar names over the ten years to July 31, 2026, annualized so the horizons are comparable.

QueryAnnualized price return vs total return over ten years: seven household names, to July 31, 2026
The exact SQL behind every number
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           argMax(toFloat64(close), window_start) AS close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'KO', 'JNJ', 'XOM', 'PG', 'VZ', 'MSFT')
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2016-08-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, d
),
px AS (
    SELECT ticker,
           argMin(close, d) AS start_px,
           argMax(close, d) AS end_px
    FROM daily
    GROUP BY ticker
),
divs AS (
    SELECT dv.ticker AS ticker,
           exp(sum(log(1 + toFloat64(dv.cash_amount) / dl.close))) AS factor
    FROM global_markets.stocks_dividends AS dv
    INNER JOIN daily AS dl ON dl.ticker = dv.ticker AND dl.d = dv.ex_dividend_date
    WHERE dv.ticker IN ('SPY', 'KO', 'JNJ', 'XOM', 'PG', 'VZ', 'MSFT')
      AND dv.cash_amount > 0
      AND dv.ex_dividend_date >= toDate('2016-08-01')
      AND dv.ex_dividend_date <= toDate('2026-07-31')
    GROUP BY dv.ticker
)
SELECT px.ticker AS ticker,
       round(100 * (pow(px.end_px / px.start_px, 0.1) - 1), 2) AS price_cagr_pct,
       round(100 * (pow(px.end_px / px.start_px * divs.factor, 0.1) - 1), 2) AS total_cagr_pct,
       round(100 * (pow(px.end_px / px.start_px * divs.factor, 0.1)
                    - pow(px.end_px / px.start_px, 0.1)), 2) AS dividend_points_pct
FROM px
INNER JOIN divs ON px.ticker = divs.ticker
ORDER BY dividend_points_pct DESC
Run this yourself

VZ carries the widest annual gap of the 7 at 5.46 percentage points a year: -1.51% annualized on price alone, against 3.96% with dividends reinvested. MSFT sits at the narrow end at 1.53 points. Two things follow for anyone comparing charts. A price chart understates a high payer far more than a low one, and any screen that ranks names on price performance quietly marks the payers down. The dividend yield behind each of these names is what sets the size of its gap.

Where each version gets used

  • Benchmarks and fund fact sheets quote total return. A "Total Return Index", a "TR" suffix, or a "net dividends reinvested" note in the fine print all mean the dividends are counted.
  • Financial media and quote screens use price return. "The S&P 500 closed up 0.4%" is a price move.
  • Brokerage performance tabs usually land on total return for the account, since the cash actually arrived there. A single position's gain column often shows price change against cost basis, which is not the same figure.
  • Backtests and strategy write-ups use whichever version the author's data feed supplied, which is the origin of many quietly inflated track records.

The mismatch that matters is setting a fund's total return beside a price index. The fund gets credit for its own dividends while the benchmark gets none of its own, which hands the fund a head start equal to the index's entire dividend stream. On the 20-year window above, that scoring error is worth 251.9 percentage points, and not one of them came from the manager. The like-for-like comparison puts total return next to total return. How monthly returns are measured walks the same arithmetic at the monthly level, and missing the best days shows what happens to the price line when a handful of sessions come out of it.

How these numbers are built
  • Prices are daily regular-session closes. Dividends are filed cash distributions, each reinvested at the closing price on its ex-dividend date, which is the standard convention for building a total return series.
  • The window runs from December 2005 to July 31, 2026, the span covered by the intraday price history behind these panels. A longer window widens the gap further.
  • A fund tracking the index stands in for the index itself, so fees and cash drag sit inside these figures. Calendar-year price return is measured from the first close of the year to the last, which trims the first session's move.

Price return vs total return FAQ

Is the S&P 500 a price index or a total return index?

The headline number is a price index: it tracks the market value of the constituents and ignores their dividends. A total return version of the same index exists and reinvests them. Fund benchmarks generally use the total return version, while news coverage generally quotes the price version.

How much do dividends add to S&P 500 returns?

Over the 10-year window ending July 31, 2026, the tracker used here returned 244.3% on price against 304.5% with dividends reinvested. Inside a single calendar year the contribution is far smaller, around 1.9 points in 2007.

Does my brokerage account show price return or total return?

Cash dividends land in the account, so the balance itself already includes them. A position's gain column often compares the current price with your cost basis only, which is a price return. The two disagree by exactly the dividends received, unless a reinvestment plan was buying more shares along the way.

Is a total return swap the same thing as total return?

No. A total return swap is a bilateral derivative contract that exchanges an asset's full economics for a financing rate. Total return in the index sense is a performance convention. The shared wording points at the same underlying idea of price plus income, and the two are unrelated as instruments.

Why does a fund look better when compared with a price index?

The fund's published figure includes its dividends while a price index excludes its own. The comparison hands the fund a head start the size of the benchmark's dividend stream, 251.9 percentage points over the 20-year window above.


Every figure here is a stored, versioned query over daily closes and filed dividend records. Open any panel to read the SQL, or run the same price-versus-total-return comparison on a ticker you follow on the Strasmore terminal.

#total return#dividends#s&p 500#index funds#performance