Your log already shows the bad month that repeats every year.
Most lifters blame the program for a bad month. Three or four years of unbroken log data shows the dip lands in the same calendar weeks every year.
Three Februaries, three abandoned programs
February, year one. A lifter eight weeks into a 5/3/1 block starts missing reps on a squat top set that moved easily in November. Bar speed is gone, warm-ups read a full point higher on RPE than they should, and by the third bad week the block is dead. March brings a new program. Within a month, training feels good again.
February, year two. Different program, an upper/lower hypertrophy split this time. Same slide. Same verdict: the program stopped working. Another restart in March.
February, year three. You can guess.
Three different programs took the blame for three bad winters. Lay the three years of log side by side, though, and the slump lands in the same stretch of weeks every year, under three different sets of percentages. That's a calendar signature, and the lifter has been firing programs for it.
The 12-week blind spot
Most training gets planned and judged in blocks of 8 to 16 weeks. That's the right unit for programming. For diagnosis it's a bad one, because the things that drag performance down on an annual cycle run on a 52-week period, and any single block only ever sees a slice of it.
Call it the 12-week blind spot. Inside one block, a February slump looks exactly like a program that has run its course: loads stall, RPE creeps, the lifter feels flat. The block has no way to tell those two apart. Only the same weeks from earlier years can.
So the honest read on a bad month starts with a question most lifters skip. What did this exact stretch of the calendar look like last year, and the year before that?
A 12-week block can't see a 52-week pattern.
Why does my training performance vary so much?
The standard answers are all local. Sleep was bad, work was stressful, the volume is too high, you need a deload, you need a new program. Some of those are true some of the time. Every one of them gets diagnosed from the last three or four weeks of data.
The program hop is the expensive answer. Each March restart gets a fresh baseline, fresh training maxes, a fresh spreadsheet tab. The comparison that would expose the pattern, this February against last February, never happens, because last February lives in a different program's numbers and sometimes in a different app entirely.
And the restart usually seems to work, which teaches the wrong lesson. Performance comes back in March because the seasonal drag lifted. The new program collects the credit, and the cycle is set up to repeat.
What repeats on a 52-week clock
A lifter's year runs on cycles, and so do several of the inputs that move a top set. None of them is exotic. Most lifters could name all of them. What they rarely do is check which ones actually show up in their own numbers.
The map below is generic on purpose. Which rows matter for one lifter, and how hard they hit, is personal. A population study can't answer that. A few years of that lifter's own log can.
Annual input
When it tends to land
What it looks like in the log
Respiratory illness season
In the US, flu activity most often peaks December to February
Missed sessions, then a week or two of flat, high-RPE work on return
Holiday stretch
Late December into early January
Irregular sessions, disrupted sleep, a bodyweight swing
Short daylight
Around the winter solstice, harder at higher latitudes
Flat early-morning and late-evening sessions
Work and school calendars
Fiscal year-end, tax season, exams; depends on the lifter
Shorter sessions, skipped accessories, sleep debt
Heat
Midsummer, worst in garage and home gyms without air conditioning
Higher RPE at the same load, conditioning cut short
Competing seasons
Varies: summer travel, ski trips, a running season
Extra fatigue, fewer lower-body sessions
A qualitative map. Flu timing per CDC seasonal influenza guidance; every other row varies by lifter, which is what your log is for.
How to read your log for a seasonal dip
The method is boring, and it works just as well in a spreadsheet as in an app. It needs three or more years of mostly unbroken logs. With two years, a coincidence can pass for a pattern.
Pick two or three anchor lifts you've trained in some form every year: a squat, a press, a hinge. For each calendar month, take the average estimated 1RM from your top sets, or the average load at a fixed RPE if your RPE logging is consistent. Then normalize each month against that year's own average. Otherwise a stronger year three hides a dip that only shows up relative to its own year.
Now line the years up by month. A seasonal dip is a month that sits below the months on either side of it in most years, on most anchor lifts. One bad February is noise. Three Februaries in a row sitting below January and March is a signature.
Last step: read the notes. If the weak month also carries the comments about illness, travel or a brutal work quarter, you've found the cause along with the timing.
Strip out the planned dips first
Deload weeks, tapers, post-meet recovery and injury layoffs all show up as low months. Mark them before you compare, or the method finds your programming instead of your calendar. If a dip lines up with a planned deload every year, that's the plan doing its job.
Stop peaking inside your weak months
Once the weak months have names, the program stops absorbing the blame and the calendar becomes a planning input.
The prescription is narrow. Don't put a peaking block, a meet, a test day or a heavy-singles week inside a month your log says is historically soft. Put accumulation, technique work or a planned deload there, and aim the hardest intensity at the months that have held up year after year. A lifter whose Februaries sag can run volume through February and test in late April, and get a fair read on the program instead of a seasonal one.
The second change is harder. Stop killing programs in the weak month. A block that stalls in the same weeks where every previous block also stalled hasn't told you anything about itself yet. Judge it on the weeks outside the dip.
The pattern only exists if the years stay together
Every step above assumes something most lifters don't have: three or four years of training in one place, still queryable. The usual history is scattered. Year one in a spreadsheet, year two in one tracker, year three in another after a subscription lapsed and the export never happened. Each fragment is fine on its own terms. None of them can line up a February against a February.
Platepusher is built for keeping those years in one record. Drop in a CSV from Strong or Hevy and every lift, every set and every date imports as native data, on the same timeline as what you log next week. Full history and CSV export are in the free tier, so the record outlives any change of plan. The plateau flag marks the week a top set stops moving, and with the old years sitting in the same log, you can check whether that stall is new or one you've hit in this same month before.
The broader argument is in [Your training history is the experiment](/articles/your-history-is-the-experiment). The seasonal read is its most concrete case. The evidence for your worst month already exists. It has to be in one place before anyone can read it.
Put every year of your training in one log, and see which months keep coming back.
Platepusher imports a Strong or Hevy CSV with every lift, set and date as native data, so years of training sit on one timeline next to what you log today. Full history and CSV export are free at every tier, and the plateau flag marks the week a top set stops moving. Monthly, yearly or lifetime: same Pro feature set, you pick the shape.