When a game is decided by the third quarter, the snaps that follow — backups in, prevent defense, clock running — aren't really competitive football. Left in your data, this "garbage time" quietly distorts efficiency stats. Cleaning it out is a small, important habit. Here's how to define and filter it from play-by-play. Full code: scripts/clean-garbage-time-pbp-python.py.
Define garbage time
There's no single official definition; a clean, common one is: the 4th quarter with a margin of 22 or more points (a three-possession-plus lead late). You can also use win probability (say, above 97%). We'll use the score-and-period rule because it needs nothing but the play data:
def is_garbage(play):
period = play["period"]["number"]
margin = abs(play["homeScore"] - play["awayScore"])
return period >= 4 and margin >= 22
Tune the threshold (16, 22, 28) to taste; the idea is "the outcome is no longer in doubt."
Filter and re-measure
Pull a blowout, score every scrimmage play's success (the 50/70/100 rule), and compute success rate twice — all plays, then competitive plays only:
for p in plays:
if not scrimmage(p): continue
good = successful(p)
all_total += 1; all_ok += good
if not is_garbage(p):
comp_total += 1; comp_ok += good
The result
On the most lopsided 2024 CFP first-round game — Penn State's rout of SMU:
Game: SMU Mustangs at Penn State Nittany Lions
All scrimmage plays: 138 | success rate 42.8%
Garbage-time plays removed: 29
Competitive plays only: 109 | success rate 45.0%
Difference: -2.2 pts of success rate
Actual output, ESPN play-by-play, retrieved June 2026. (Game-wide success rate, both teams.)
Nearly one in five plays (29 of 138) happened after the game was effectively over. Removing them moved the game's success rate by 2.2 points — here it went up, because garbage-time football (clock-killing runs, vanilla calls, backups) tends to be less efficient than competitive football. The direction varies by game; the point is that those plays are measuring something different from the contest you actually want to analyze. Over a season, garbage time can meaningfully flatter or punish a team's numbers depending on how many blowouts it played.
Important caveats
- Not all feeds carry running scores per play. If
homeScore/awayScorearen't on each play, fall back to a period-only rule or align with the win-probability series. Our script notes when no plays met the test. - Don't over-filter. Too aggressive a threshold throws away real competitive snaps. 22 points in the 4th is conservative.
- Be consistent. Whatever rule you pick, apply it everywhere so teams are compared on the same basis.
- Filter per analysis, not per dataset. Keep the raw data; filter in code so you can change the definition later.
This is the unglamorous data-cleaning step that separates a number you can trust from one you can't. The best analysts spend more time here than on the modeling.
Sources & further reading
- ESPN public API (play-by-play)
- Companion code:
scripts/clean-garbage-time-pbp-python.py - Related: Season-long success rate · Success rate & EPA