Major version upgrades aren’t tickets. They’re projects.

Patch versions are tickets. Minor versions are usually tickets. Major versions (the ones with breaking changes, deprecation cycles, peer-dependency cascades, and “we recommend migrating to…” in the changelog) are projects, and planning poker isn’t the right tool for sizing them whole. The story that says “upgrade to React 19” or “Postgres 16” is not the work; it’s the wrapper around the work.

Treating the upgrade as a single estimate produces a single failure mode: the team votes 13, runs out of time in week three, and ships a half-migrated codebase that has the new framework’s bugs and the old framework’s idioms. The honest move is to break the upgrade into a sequence of smaller stories, each independently estimable, with the upgrade itself as the umbrella project.

What gets said in the room

Engineer: “The codemod handles most of it.”

Lead: “Most of what? What does it not handle?”

SRE: “Do all our deps support the new version yet?”

QA: “What’s our regression-testing strategy for the diff?”

PM: “Are we shipping anything else this sprint, or is this the sprint?”

Questions worth asking before voting

  • How many breaking changes apply to our codebase (read the changelog and count)?
  • Do peer dependencies support the target version, or do we cascade?
  • Codemod or manual? What’s the codemod’s coverage?
  • Test coverage on the changed surfaces: adequate, or do we add tests first?
  • Rollback strategy if it goes badly mid-sprint?
  • One PR or many? If many, what’s the dependency order?

The right output of this conversation is often “this isn’t a story, it’s a project, so let’s plan it that way,” then split it into slices the team can each estimate against a reference story.

Don’t put a single number on a major upgrade. Break it into stories, then size those.

See estimation techniques for fuzzier or larger work, and estimating a research spike for the investigation that should precede the estimate. Browse the other worked estimation examples.