Do teams struggle after an international break?
Players come back tired, scattered and out of rhythm, so the first game after an international break is supposed to be a lottery. Over 82 breaks and 485 Scottish Premiership matches, results after a break look just like the rest, and no club is cursed.
Beginner
Contents
The claim
"We always lose after an international break." The players who were away come back tired, from long trips and different systems; the ones who stayed behind have had two weeks without a game. Either way, the argument goes, the first match back is a lottery, and some clubs are cursed by it.
Why people believe it
International breaks are memorable. Fans are without their club for two weeks, so the first game back gets extra attention, and a bad result has an easy explanation waiting for it. A club that loses a few times after breaks soon has a "rule", and every new defeat after a break confirms it. Wins after a break don't get the same credit.
The data
Every Scottish Premiership match from 2000/01 to 2025/26: 5,879 matches, with dates and final scores from football-data.co.uk, and Bet365's pre-match odds from 2002/03.
The method
The files don't say which weekends were international breaks, so the breaks are found from the fixture list: the league stopped for 12 to 21 days and restarted just after an international window (September, mid-October, mid-to-late November, or late March to early April). Gaps for other reasons are left out: the winter break, April cup semi-finals, the snow postponements of 2010 and the matches postponed after the Queen's death in September 2022. That leaves 82 breaks. The snippet prints every restart date, so you can check them.
Each team's first match back is what matters, so the comparison uses the 485 matches that were both teams' first game since the restart, within a week of it, against the other 5,394. Three checks:
- Results and goals, after a break against the rest.
- Results against the bookmakers' odds. Raw results could mislead if the first game back often happened to be a mismatch. The odds already allow for how good each team is, so comparing points with what the odds expected removes that, as in the midweek myth.
- Club by club. The belief is usually about one club, so each club's results after a break are compared with its own usual record, against the odds.
The evidence
The results are close to the usual. Home sides won 41.2% of matches straight after a break, against 43.9% otherwise. That's the biggest difference in the data, and it's inside the range luck produces: with 485 matches, the after-a-break figure could easily be 4 points either way. Goals are the same: 2.70 a game after a break, 2.68 otherwise.
Against the odds
| Favourites | Points v the odds |
|---|---|
| After a break | −0.05 a game (±0.11) |
| Other matches | +0.02 a game (±0.03) |
Favourites earned almost exactly the points the bookmakers expected, after a break and otherwise. Without Celtic and Rangers, it's −0.07 after a break against 0.00 otherwise, again inside the luck margin (±0.14).
Celtic and Rangers
It's often said that the Old Firm suffer most, because so many of their players are away. Celtic took 2.41 points a game after a break and 2.39 otherwise. Rangers took 2.07 after a break and 2.21 otherwise, a gap well inside the luck margin of ±0.29.
Club by club
No club is cursed. Of the 18 clubs with at least 15 matches after a break, one is outside its luck margin: St Mirren, who did better after breaks, by +0.36 points a game against a margin of ±0.35. By luck alone, about one club in 20 would cross its margin, so one in 18 is just what you'd expect. The furthest below zero, Dunfermline at −0.43, has one of the widest margins, from only 22 matches.
How a curse appears
Livingston went 12 Premiership games straight after a break without a win, from November 2021 to April 2026, with a season out of the top flight in between. That looks like a curse. But ten of the twelve were away from home, mostly as underdogs, and the bookmakers' own odds gave them about a 1 in 20 chance of going all twelve without a win: unlucky, not cursed. Over all their seasons, their record after breaks is within luck of their usual.
Then the bigger question: if breaks made no difference at all, would anyone have a run like that? Drawing every post-break result from the bookmakers' odds and repeating the whole record 2,000 times, some club has a winless run of 12 or more in 92% of the simulated histories. A "curse" somewhere in the league is almost certain, even when there's nothing there. That's the trap described in overfitting: a rule built from a handful of memorable games.
Verdict
Not supported. Results straight after an international break look like any other weekend's: the same goals, favourites earning the points the bookmakers expect, the Old Firm unchanged, and no club doing worse than luck can explain. The one club outside its margin did better, by a whisker, as luck predicts. Long bad runs after breaks happen, but in a league this size they'd happen anyway.
Caveats
- No squad information. The data can't show which players were away, so this tests the break, not tired internationals. A club with an unusual number of call-ups in one season could suffer without it showing here.
- Both teams had the break. If a break hurts everyone equally, comparing results can't see it; goals would be the clue, and they're unchanged.
- Breaks are found from the fixture list. A break where the Premiership played on isn't counted, and a gap that matched a window for another reason could slip in. Check the dates the snippet prints.
- Odds from 2002/03 only. The comparisons against the odds use 454 of the 485 matches after a break.
- League matches only. Cup ties straight after a break aren't in these files.
Reproduce the analysis
The results and odds files are published by football-data.co.uk. Download the Premiership (SC0) file for each season from 2000/01 to 2025/26 and save each under its own name, such as SC0_2425.csv; they aren't rehosted on this site. Then:
Show the Python119 lines, ready to copy and run.
# From Football Data Science by Bryan McGuire. Free to use with credit.
# https://www.footballdatascience.co.uk/myth-or-maths/international-break
import csv
from collections import Counter, defaultdict
from datetime import date, datetime
from math import sqrt
def when(d):
return datetime.strptime(d, "%d/%m/%Y" if len(d) == 10 else "%d/%m/%y").date()
def points(goals_for, goals_against):
return 3 if goals_for > goals_against else 1 if goals_for == goals_against else 0
matches = []
for y in range(2000, 2026):
with open(f"SC0_{y % 100:02d}{(y + 1) % 100:02d}.csv", encoding="latin-1") as f: # Premiership
for r in csv.DictReader(f):
if r.get("FTR") not in ("H", "D", "A"):
continue
try: # Bet365 odds turned into probabilities that add up to 1 (from 2002/03)
p = [1 / float(r["B365" + k]) for k in "HDA"]
p = [v / sum(p) for v in p]
except (KeyError, ValueError, ZeroDivisionError):
p = None
matches.append((when(r["Date"]), r["HomeTeam"].strip(), r["AwayTeam"].strip(), int(r["FTHG"]), int(r["FTAG"]), p))
# International breaks: the league stopped for 12 to 21 days and restarted just after an international window.
# Left out: the winter break, April cup semi-finals, snow in 2010 and the postponements of September 2022.
def after_window(d):
return ((d.month == 9 and d.day <= 20) or (d.month == 10 and (d.day <= 2 or 10 <= d.day <= 25))
or (d.month == 11 and 15 <= d.day <= 28) or (d.month == 3 and d.day >= 25) or (d.month == 4 and d.day <= 12))
days = sorted({m[0] for m in matches})
restarts = [b for a, b in zip(days, days[1:]) if 12 <= (b - a).days <= 21 and after_window(b) and b != date(2022, 9, 17)]
print(f"{len(restarts)} international breaks; the league restarted on:", ", ".join(d.strftime("%d %b %Y") for d in restarts))
def first_back(m): # both teams' first match since the restart, within a week of it
d = max((r for r in restarts if r <= m[0]), default=None)
return (d is not None and (m[0] - d).days <= 6
and not any(d <= x[0] < m[0] and {x[1], x[2]} & {m[1], m[2]} for x in matches))
after = [m for m in matches if first_back(m)]
other = [m for m in matches if m not in after]
print(f"{len(after)} matches straight after a break, {len(other)} others")
def share(rows, test):
p = sum(map(test, rows)) / len(rows)
return f"{p:.1%} (±{1.96 * sqrt(p * (1 - p) / len(rows)):.1%})"
def average(values):
mean = sum(values) / len(values)
return mean, 1.96 * sqrt(sum((v - mean) ** 2 for v in values) / (len(values) - 1) / len(values))
for name, rows in (("after a break", after), ("other matches", other)):
goals, margin = average([m[3] + m[4] for m in rows])
print(f"{name}: home {share(rows, lambda m: m[3] > m[4])}, draw {share(rows, lambda m: m[3] == m[4])}, "
f"away {share(rows, lambda m: m[3] < m[4])}, goals {goals:.2f} (±{margin:.2f})")
def against_odds(m, team):
"""Points the team earned minus the points the bookmakers expected it to earn."""
_, home, away, hg, ag, p = m
if team == home:
return points(hg, ag) - (3 * p[0] + p[1])
return points(ag, hg) - (3 * p[2] + p[1])
def favourite(m):
return m[1] if m[5][0] >= m[5][2] else m[2]
old_firm = {"Celtic", "Rangers"}
for label, keep in (("all clubs", lambda m: True), ("without Celtic and Rangers", lambda m: not old_firm & {m[1], m[2]})):
for name, rows in (("after a break", after), ("other matches", other)):
gaps = [against_odds(m, favourite(m)) for m in rows if m[5] and keep(m)]
mean, margin = average(gaps)
print(f"favourites v the odds, {label}, {name}: {mean:+.2f} points a game (±{margin:.2f}, {len(gaps)} matches)")
for club in sorted(old_firm):
for name, rows in (("after a break", after), ("other matches", other)):
mine = [m for m in rows if club in m[1:3]]
ppg, margin = average([points(m[3], m[4]) if club == m[1] else points(m[4], m[3]) for m in mine])
print(f"{club}, {name}: {ppg:.2f} points a game (±{margin:.2f}, {len(mine)} matches)")
# Club by club: each club's results against the odds after a break, minus its results against the odds otherwise
print("\nclub by club, after a break minus usual, points a game against the odds (clubs with 15+ matches after a break):")
clubs = Counter(t for m in after for t in m[1:3])
rows, outside = [], 0
for club, n in clubs.items():
if n < 15:
continue
a, ea = average([against_odds(m, club) for m in after if club in m[1:3] and m[5]])
b, eb = average([against_odds(m, club) for m in other if club in m[1:3] and m[5]])
margin = sqrt(ea ** 2 + eb ** 2)
rows.append((a - b, margin, club, n))
outside += abs(a - b) > margin
for gap, margin, club, n in sorted(rows):
print(f" {club:<14} {gap:+.2f} (±{margin:.2f}, {n} matches)")
print(f"{outside} of {len(rows)} clubs outside the luck margin; about {0.05 * len(rows):.1f} expected by luck alone")
# Why fans believe it: the longest run of post-break games without a win, for any club
def longest_runs(results):
"""results: (date, home, away, outcome) in date order -> each club's longest run without a win, and when it ended."""
run, best = Counter(), {}
for d, home, away, outcome in results:
for club, won in ((home, outcome == "H"), (away, outcome == "A")):
run[club] = 0 if won else run[club] + 1
if run[club] > best.get(club, (0,))[0]:
best[club] = (run[club], d)
return best
real = longest_runs([(m[0], m[1], m[2], "H" if m[3] > m[4] else "D" if m[3] == m[4] else "A") for m in sorted(after)])
n, club = max((v[0], c) for c, v in real.items())
print(f"\nlongest run of games without a win straight after a break: {club}, {n}, ending {real[club][1]:%B %Y}")
# If breaks made no difference, how often would some club have a run that long? Draw every post-break result
# from the bookmakers' odds and look for the longest run in the league, 2,000 times (matches with odds only).
import random
random.seed(1)
priced = [m for m in sorted(after) if m[5]]
def draw(p):
u = random.random()
return "H" if u < p[0] else "D" if u < p[0] + p[1] else "A"
hits = sum(max(v[0] for v in longest_runs([(m[0], m[1], m[2], draw(m[5])) for m in priced]).values()) >= n
for _ in range(2000))
print(f"with no break effect at all, some club has a run of {n} or more in {hits / 2000:.0%} of simulated histories")
Spotted a flaw in the method, or have a football claim you'd like tested? Suggest it on LinkedIn, where discussion of these articles happens.