How to Fix Sprint Velocity That's Not Improving
When sprint velocity not improving becomes a recurring retro complaint, teams need a systematic diagnosis instead of guesswork. This guide walks engineering managers through pinpointing the real causes—cycle time, scope creep, or morale—and fixing stalled velocity using real sprint data.
If your team's sprint velocity has plateaued or dipped despite good intentions, you need a systematic way to find the real cause instead of guessing. Sprint velocity not improving is one of the most common complaints engineering managers bring to retros, and it's also one of the most frequently misdiagnosed. Most advice jumps straight to "improve your estimation process," but in practice the real cause usually lives somewhere else: cycle time, scope creep, or team morale. This guide walks through diagnosing and fixing stalled velocity systematically. You'll need access to your sprint history in Linear or Jira and at least 3-4 sprints of data to spot real patterns rather than noise.
Step 1: Confirm the problem is real, not a measurement artifact
Before you change anything, make sure the "problem" isn't just statistical noise. Pull velocity for the last 6-8 sprints, not just the last two or three. A single slow sprint tells you almost nothing; a short window will exaggerate whatever happened to go wrong recently, whether that's a holiday week or one engineer being out sick. Plot the numbers and look for a genuine trend line, not a jagged one-off dip.
Next, check whether your estimation process itself changed during that window. New team members almost always throw off point calibration for a sprint or two, since they haven't internalized what a "3" or a "5" means for your codebase yet. Re-scoped tickets do the same thing: if a ticket ballooned from a 2 to an 8 mid-sprint because requirements changed, your historical average is no longer measuring the same thing it used to.
The most common mistake here is comparing velocity across sprints with different team sizes or PTO weeks without normalizing. If your team shipped 40 points with six engineers and then 30 points with four engineers the following sprint, that's not a slowdown, that's basic capacity math. A simple fix is to track velocity per engineer, or at least note headcount and available days next to each sprint's total so you're not comparing incompatible baselines.
It's also worth remembering that velocity isn't supposed to climb every sprint forever. A team's healthy target is a stable, predictable number, not a permanently upward slope. If your velocity has flattened after an initial ramp-up period, that's often a sign of a mature, well-calibrated team rather than a stalled one. Only proceed to the next steps once you've confirmed the drop is real, sustained across multiple sprints, and not explained by team composition changes.
Step 2: Audit how work actually moves through the sprint
Once you know the drop is real, the next question is where time is actually going. Velocity is a lagging output; cycle time tells you where the friction lives. Map cycle time by stage: backlog, in progress, in review, blocked, and done. For each ticket, note how long it sat in each column, not just the total time from creation to close. Averaging across a sprint or two will usually reveal one stage that's disproportionately long compared to the others.
Code review turnaround is one of the most common silent killers of velocity. A ticket can move quickly through development and then sit for a day and a half waiting for a reviewer to have time, then bounce back for changes, then wait again. None of that shows up as "the code was hard to write," but it eats real days out of the sprint. Merge queue delays behave the same way: work is functionally done but blocked from landing, and it doesn't count until it's merged.
Doing this audit manually in a spreadsheet is tedious and easy to get wrong, since you're pulling timestamps from GitHub and Linear separately and trying to reconcile them by hand. This is exactly the kind of stage-by-stage breakdown that a tool like Progress is built to surface automatically, since it ingests both GitHub and Linear data and continuously analyzes change-pressure and churn instead of requiring someone to reconstruct it after the fact. Rather than a one-time audit, you get a running view of where tickets are getting stuck, which matters because bottlenecks tend to move around as team composition and workload shift. Whether you do this by hand or with a platform, the goal is the same: find the one or two stages eating the most calendar time, because that's almost always more productive than re-litigating your story-point scale.
Step 3: Identify hidden scope creep and unplanned work
Scope creep rarely announces itself. It shows up as a slow accumulation of small additions that individually seem reasonable but collectively consume a sprint's worth of capacity. Start by tallying tickets added mid-sprint against tickets planned at sprint start, sprint over sprint. If that ratio is climbing, that is a direct signal that planning discipline is slipping, regardless of what the velocity number says.
It helps to separate two categories that often get lumped together: planned feature work and firefighting. Firefighting includes production incidents, urgent customer escalations, on-call interruptions, and the kind of "can you just quickly look at this" requests that never make it onto the board formally. These pull engineers off planned work without ever being logged as sprint scope, which makes the capacity drain invisible in your tracking tool even though everyone on the team feels it.
The mistake to avoid is counting unplanned urgent work toward velocity just because it eventually got a ticket and some story points attached to it after the fact. That practice makes the velocity chart look stable while masking the actual problem: your team doesn't have the planning slack it thinks it does. If a sprint's real output was 60% planned work and 40% unplanned firefighting, that's the number worth discussing in a retro, not the blended total.
A useful habit is tagging every ticket at creation as either "planned" or "unplanned/urgent," even retroactively for the past few sprints. Once you have that split, you can see whether velocity is flat because the team is genuinely slower, or because an increasing share of every sprint is being consumed by work nobody scheduled. Those two situations call for very different fixes.
Step 4: Check for stalled work and emerging risk signals
Aggregate metrics can hide a small number of problem tickets that are quietly draining a sprint's worth of points. Pull up your board and flag any ticket that has been sitting "in progress" far longer than your team's typical cycle time for that ticket size. A single 3-point ticket stuck for nine days is often the real explanation for a sprint that came in three points short, even though nothing else about the sprint looked unusual.
Pay particular attention to pull requests with unusually high churn or repeated rounds of review. A PR that's been through five review cycles with major diffs each time is rarely a coding problem; it's usually a sign that requirements were unclear at the start, or that the change is touching a part of the codebase carrying enough technical debt that every attempt to modify it breaks something else. Either way, that ticket is a leading indicator worth investigating on its own, separate from the sprint retro.
Manually spotting these patterns means someone has to scroll through the board, cross-reference PR history, and remember what "typical" cycle time looks like for tickets of that size, which is easy to skip when things are busy. This is one of the areas where Progress's pre-computed signals save real time: it flags stalled work and change-pressure automatically based on merge volume and code churn, so you see which tickets and which parts of the codebase are carrying elevated risk without running a manual board audit every sprint. That turns a reactive, occasional check into something closer to a standing early warning system.
Once you've identified the stalled tickets, don't just close them out and move on. Ask what made them stall: unclear acceptance criteria, a dependency on another team, or a part of the codebase everyone quietly avoids. That answer usually points directly at step six.
Step 5: Rule out team morale and burnout as a root cause
Velocity drops often show up well before anyone files a complaint or hands in notice. By the time turnover becomes visible, the underlying strain has usually been building for a while, and it tends to show up first in subtler signals: commit cadence slowing down, PRs getting smaller and more conservative, or a drop in the kind of after-hours or weekend engagement that, healthy or not, often correlates with engagement in a startup environment.
The most direct way to check this is to simply ask in a retro, but ask specifically rather than generally. Instead of "how's everyone feeling," ask whether workload has felt sustainable, whether priorities have been clear sprint to sprint, and how much context-switching people have had to do between planned work and interruptions. Context-switching in particular is a common hidden velocity tax: an engineer juggling three different tickets across two different priorities loses real time to task-switching overhead that never shows up as a line item anywhere.
The limitation of relying on a retro alone is timing. Retros happen every one or two weeks, and people don't always volunteer that they're stretched thin until it's already affecting delivery. This is where a morale and momentum read, a capability built into platforms like Progress, adds something a conversation can't: a continuous signal drawn from actual activity patterns, not self-reported sentiment on a single day. Catching a dip in team momentum a sprint or two before it shows up as a formal complaint gives you room to adjust workload before it turns into attrition. Treat morale as a genuine root cause candidate here, not an afterthought; a burned-out team will underperform regardless of how well you fix cycle time or scope discipline.
Step 6: Fix the process bottleneck you found
By this point you should have a specific, evidence-backed cause rather than a vague sense that "velocity is down." The fix depends entirely on what you found:
- Review delays: Set an explicit review SLA, for example a first pass within four business hours during working days, and rotate reviewers across the team so no single person becomes a bottleneck every sprint. If one senior engineer reviews 80% of PRs, their vacation or busy week will show up directly in your velocity chart.
- Scope creep: Introduce a mid-sprint intake process that forces an explicit trade-off decision. Anything added mid-sprint requires removing or deprioritizing something else of equivalent size, decided in the moment by whoever owns the sprint, rather than quietly stacking on top of existing commitments.
- Stalled tickets: Add a WIP limit per engineer, capping how many tickets someone can have "in progress" at once. This forces finishing over starting, which sounds simple but directly addresses the pattern of engineers picking up new work while old tickets sit half-done waiting on a decision or a review.
- Unclear requirements driving high-churn PRs: Require a brief written spec or acceptance criteria for any ticket above a certain size before it enters a sprint, so ambiguity gets resolved during planning instead of during review cycles.
- Morale and workload strain: Rebalance assignments so the same one or two people aren't consistently absorbing firefighting duty on top of planned work, and make on-call rotation genuinely rotating rather than default to whoever's fastest to respond.
Pick one fix, not all five at once. Changing every process lever simultaneously makes it impossible to tell which change actually moved the needle, and it risks overwhelming a team that may already be stretched thin. Apply the single most relevant fix for a full sprint cycle before layering in another.
Step 7: Set a realistic benchmark and monitor going forward
Don't expect an immediate jump in velocity the sprint right after you make a process change. Teams need at least one full sprint cycle to adjust to a new review SLA, intake process, or WIP limit, and the first sprint under a new process sometimes looks slightly worse before it improves, simply because people are still learning the new habit. Re-baseline your velocity expectations after that full cycle, not immediately after the change goes live.
Just as important, don't go back to watching velocity alone. Track the leading indicators you identified during diagnosis, cycle time by stage, review turnaround, and the ratio of planned to unplanned work, alongside the velocity number itself. These leading indicators will typically shift a sprint or two before velocity does, which gives you an early warning if a fix isn't holding or if a new bottleneck is emerging elsewhere.
Keeping this visible to stakeholders without manually rebuilding a report every sprint is where an on-demand executive summary earns its keep. Rather than an engineering manager compiling cycle-time charts and change-pressure notes by hand before every leadership check-in, a tool like Progress can generate that summary automatically from the same underlying data, so the update takes minutes instead of an afternoon. That matters especially at a startup, where the same person diagnosing the velocity problem is often also the one expected to explain it to the founders.
Set a calendar reminder to revisit this full audit in a quarter, even if velocity looks stable by then. Bottlenecks shift as teams grow, codebases age, and priorities change, and the diagnostic process you just ran is worth repeating rather than treating as a one-time fix.
Watching the signals that predict velocity, not just the number itself
Recheck velocity after two to three sprints with your fix in place, since a single sprint still isn't enough data to call it a trend. While you wait, keep watching the underlying cycle-time, scope, and morale signals rather than fixating on the velocity number alone; those are the indicators that will tell you whether the fix is holding or whether you're about to be back here in another month. Velocity is the symptom you noticed first, but it was never the actual disease.
If manually pulling this data from Linear and GitHub every sprint isn't sustainable for your team, that's precisely the gap an engineering intelligence platform is built to close. Learn more about our services to see how automated stalled-work detection, change-pressure signals, and morale reads can catch these problems before they show up as a flat velocity chart.