NFL Projection Model
How Fairline's NFL model works: opponent-adjusted EPA ratings produce a projected margin and total, and a key-number discretizer turns them into prices that respect the numbers NFL games actually land on.
Updated Sep 2026 · Part of the models series
Statistical estimates, not betting advice. Past results do not predict future results. 21+. Call or text 1-800-MY-RESET (1-800-697-3738).
Where does this model stand today?
This model projects every game and prices every market off those projections. It flags no value on NFL game markets.
Before launch, each market and side was scored once against an untouched 2023, 2024, 2025 holdout of 855 games, at the same 3% edge threshold the live system uses. All six market-and-side combinations failed. Five of six lost money when their bets were priced at the closing line. Five of six also failed to beat the naive strategy of blindly backing one side of every game. All six forecast worse than the de-vigged close. Totals overs made money and still forecast worse than the close.
So no NFL moneyline, spread or total carries a value flag. Projections and fair odds serve as context on those three markets. The switch stays off until a live record earns it. A weekly check through Week 6 is what would earn it.
Player props are a separate switch, and it is not off. The holdout above scored the three game markets only, so the gate never touches props: a passing, rushing or receiving yards play ships flagged. Read those flags as the less proven half of this model. No holdout scored them, which is the same bar the three game markets were held to and failed.
What did the holdout test find?
Every market and side lost. The table below gives each one: how many bets it placed, what it returned when those bets were priced at the closing line, and what blindly backing one side of every game would have returned instead. Read the verdict column as the reason the value flags are off.
| Market | Bets | Return at the close | Blind one-side return | Verdict |
|---|---|---|---|---|
| moneyline home | 227 | -13.9% | -5.2% | FAIL |
| moneyline away | 336 | -9.8% | -6.0% | FAIL |
| spread home | 214 | -4.7% | -2.8% | FAIL |
| spread away | 321 | -8.5% | -5.9% | FAIL |
| total over | 223 | 3.8% | -3.2% | PASS |
| total under | 263 | -1.5% | -5.7% | FAIL |
Moneyline Brier 0.2268, margin error 10.43 points, total error 10.32 points, over the same holdout.
Why does the model need a discretizer?
Because NFL margins pile up on a few numbers and a smooth curve cannot reproduce that. A bell curve fitted to the same games puts roughly a third of the real weight on a margin of exactly 3, so a spread priced off it is wrong at every line near a key number. The discretizer adds fitted weight back at each of those numbers.
About 14.9% of NFL games end on a margin of exactly 3 points. A smooth bell curve fitted to the same data puts 5.3% there. It understates the most common margin in the sport by nearly three times, and a spread priced off that curve is wrong at every line near a key number.
So projecting and pricing are separate steps. A regression produces two numbers, the projected margin and the projected total. A second layer turns each one into a probability distribution over whole-number outcomes, with fitted mass added at 3, 6, 7, 10, 14. Every market price is a partial sum of one of those two distributions. That is why the moneyline, the spread, the total and both team totals can never disagree with each other.
That key-number margin curve was calibrated once, offline, on historical closing margins from the public nflverse games file, and it ships frozen as a JSON artifact. No live book price reaches it.
The fit was checked against a preregistered tolerance at each key number before any candidate was scored. The smooth-normal baseline fails that check at four of the five numbers.
| Parameter | Value | |
|---|---|---|
| Discretizer | mixture | The shipped candidate. The empirical-matrix alternative stays fitted behind the same interface. |
| Margin sigma | 14.24 | Spread of the fitted margin distribution, in points. |
| Total sigma | 13.76 | Same, for the game total. |
| Mass added at 3 | 2.94x | How much the fit lifts the exact-3 margin above the smooth curve. |
| Mass added at 7 | 1.54x | The second-largest key number. |
| Games fitted | 7276 | Pooled seasons, with post-2015 games double-weighted for the extra-point rule change. |
How does the model rate a team?
In expected points added per play, taken from public play-by-play and split between passing and rushing. Every rating is then adjusted for the opponents it was earned against, shrunk toward the league average in proportion to how few plays the team has run, and anchored by last season until the new one stands on its own.
Each team's offense and defense are measured in expected points added per play, split internally between passing and rushing, taken from public play-by-play. Alternating passes over the schedule adjust every rating for the opponents it was earned against. Each rating is then shrunk toward the league average in proportion to how many plays the team has run. Last season's rating anchors it until the new one has enough data to stand alone.
The result maps linearly to a projected margin and a projected total. That pair, plus home field, is the entire public surface of the game model.
| Parameter | Value | |
|---|---|---|
| Opponent-adjustment passes | 4 | Alternating offense/defense passes; the fixed point is near after three or four. |
| Shrinkage scale | 400 plays | A team reaches half weight on its own season at this many plays. |
| Prior-season carryover | 60% | How much of last year's rating anchors the new season. |
| Home field | 1.8 points | Flat additive, zeroed at neutral sites. |
| League points per team | 22.5 | The anchor both projected scores deviate from. |
| Plays per team per game | 63 | Scales EPA-per-play deviations into points. |
How does the model price games in September?
It blends in an Elo rating built from nothing but final scores back to 2002, with one fitted weight. Four weeks of play-by-play is not enough to rate a team, and Elo needs only results. The same rating stands as the fallback margin model if the regression misses its checkpoint.
Four weeks of a new season is not enough play-by-play to rate a team. A results-only Elo rating, built from nothing but final scores back to 2002, blends into the September projection with one fitted weight of 0.86. The same rating also serves as the fallback margin model if the regression misses its checkpoint. Either way it prices through the same discretizer.
Elo alone replays at 10.59 points of margin error and 64.4% straight up across 2002 to 2025.
How does weather change the projection?
It changes the inputs, never the finished price. Sustained wind and cold shift passing efficiency by fitted amounts, and strong wind also cuts the points expected from field goals. Because the change happens upstream, player props inherit it the same way the game total does.
Wind and cold change the inputs rather than the finished price, so player props inherit them the same way the game total does. Sustained wind and temperature shift passing efficiency by fitted amounts. Wind at or above 15 mph also cuts the expected points from field goals, by 7% of the make rate. Gusts are recorded, not modeled.
Retractable roofs price as indoor unless the schedule says the roof was open. The handful of international games each season price weather-neutral on purpose, because the free forecast service covers no venue outside its zones.
Which NFL markets does the model price?
The moneyline, the spread, the game total and both team totals. Each one is a partial sum of the margin distribution or the total distribution, which is why no two of them can disagree. Player props are priced separately, below.
Moneyline
P(margin > 0)Read straight off the margin distribution.
Spread
-21 to +21A partial sum of the same distribution, quoted every half point so pushes are priced.
Total
30 to 62The same machinery on the total distribution, with weaker key-number structure.
Team totals
9.5 to 36Derived from both distributions, so a team total cannot contradict the game total.
How are player props projected?
Top down, as shares of the team. The model projects how many plays a team runs and how it splits them between passing and rushing, then gives each player a share of that, normalized so the players on a team add up to the team. A quarterback's passing yards are his share of what his own receivers are projected to gain.
A player's projection is a share of his own team's projected volume, never built bottom-up. One module projects how many plays the team runs and how it splits them between passing and rushing. Each player's targets, carries and attempts are shares of that, normalized so the players on a team add up to the team. A quarterback's passing yards are his share of what his receivers are projected to gain, which keeps an accounting identity that a bottom-up model breaks.
Each market's spread of outcomes was fitted separately and gated separately.
| Parameter | Value | |
|---|---|---|
| Passing yards | split normal | Fitted on 2266 player-games; passed its holdout gate. |
| Rushing yards | disabled | Failed its preregistered holdout gate, so no line in this market is priced. |
| Receiving yards | hurdle_gamma | Fitted on 15369 player-games; passed its holdout gate. |
| Receptions | disabled | Failed its preregistered holdout gate, so no line in this market is priced. |
When does the projection freeze?
When the inactives publish, about 90 minutes before kickoff. NFL has no lineup card, so that list is the lock. After it, exactly one thing can move the projection, and the rules below say when.
NFL has no lineup card, so the inactives list is the lock. Projections move freely through the week. When the inactives publish, about 90 minutes before kickoff, the projection freezes and the freeze is logged.
After that, one thing can move it. A player ruled out who was available at the freeze triggers a recompute, but only when his recent snap share clears 25%. The recompute then commits only if it moves the projected total or spread by at least 0.5 points. A check that moves less is recorded as a check that did not commit.
Every projection change belongs to exactly one logged event. A play that changed after the freeze is therefore attributable to the book or to a named recompute, never to mystery.
What data does the model use?
Three free public feeds and nothing else. None of them is a sportsbook, and no live book price enters a projection.
Every input is free public data.
- nflverse release artifacts: schedule, play-by-play, weekly player stats, snap counts
- ESPN's public injuries endpoint: game-week availability and the inactives lock
- National Weather Service gridpoint forecasts, by stadium
nflverse data is licensed CC BY 4.0. Source: nflverse-data.
What happens when the upstream data goes stale?
The run labels the projection and turns its flags off. Each nflverse release publishes a timestamp, every run compares those against the last completed game, and anything stale raises an ops alert. A dead upstream degrades to no flags rather than to wrong ones.
Each nflverse release publishes its own timestamp. Every run compares them against the last completed game. Anything stale raises an ops alert. Anything stale past the gate threshold labels the projection and gates its flags, so a dead upstream degrades to no flags rather than to wrong flags.
Where can I read about the key numbers in more detail?
The key numbers are what separates NFL pricing from every other sport here. Why the numbers 3 and 7 matter when pricing an NFL spread works one spread through the margin distribution, half point by half point.
Sources
The parameter values on this page are rendered from the running system and refresh periodically; when a weight or threshold changes, this page reflects it automatically.