Velocity is a lie detector not a speedometer

Multiple screens showing dashboards and metrics

Every quarter we watch another engineering team roll a velocity chart into a review deck, gesture at the bars trending up and to the right, and declare progress. We used to do it too. Then we ran a small experiment on our own Velo delivery team: we hid the velocity number from three squads for a full quarter and gave them cycle time instead. Two of the three squads shipped more features. All three reported that planning felt less theatrical.

This is not an argument against measurement. It is an argument against a specific metric that has quietly stopped telling us what we think it tells us.

Velocity measures the ruler, not the road

Story points are a ruler the team invented. When we grade a team on how many units of their own ruler they produce per sprint, we should not be surprised when the ruler starts stretching. We have watched this happen on our own boards. A ticket that would have been a 3 in April becomes a 5 by July. Nobody lies. Everyone remembers “that thing that turned out harder than expected,” and the estimate drifts up. The chart climbs. The output does not.

Goodhart’s law shows up in the standup:

When a measure becomes a target, it ceases to be a good measure. Velocity is the most polite example of this rule we have found in software.

The other failure mode is subtler. Velocity averages hide the shape of the work. A team can hit 42 points every sprint for six sprints and be quietly falling apart, because 40 of those points come from a single engineer who is one Slack DM away from resigning. The bar chart cannot see that. Cycle time can.

Cycle time is boring, which is the point

Cycle time is the elapsed clock between “in progress” and “done.” It is boring because it measures reality rather than an estimate. We cannot inflate it by talking about it in a Wednesday grooming session. It refuses to care about our narrative.

Here is the comparison we now put in front of every engineering lead we hire:

  • Unit. Velocity uses story points, a team invented currency. Cycle time uses hours or days, a currency everyone shares.
  • Gameable by. Velocity is inflated by re estimation, ticket splitting, and status theatre. Cycle time is inflated only by shipping faster, which is what we wanted.
  • Sensitive to. Velocity is sensitive to who is in the room during planning poker. Cycle time is sensitive to review queues, environment flakiness, and handoffs, the things that slow us down.
  • What it hides. Velocity hides bottlenecks behind an average. Cycle time exposes them by widening the tail of the distribution.
  • Actionable signal. A dropping velocity prompts a debate about commitment. A widening cycle time prompts a debate about the pull request that has been open since Tuesday.

What we changed on our own board

We run Linear for tickets and pipe every state transition into a Datadog dashboard. Once a week, on Thursday afternoon, we look at three numbers together:

  1. Median cycle time for tickets closed that week.
  2. The 90th percentile of the same distribution.
  3. The count of pull requests older than 48 hours.

We deliberately do not look at velocity anymore. When a stakeholder in Notion asks “how much did we ship this quarter,” we answer with a count of shipped tickets and a link to the changelog. If they push, we show the cycle time trend. Nobody has pushed twice.

The 90th percentile is the metric that changed our behaviour the most. Medians are polite. They hide the ticket that sat in code review for eleven days because the reviewer was on parental leave and nobody rerouted it. The 90th percentile has forced us to build a bot in Slack that pings the review channel every morning at 9:15 with any pull request older than a day. Our median moved a little. Our tail moved a lot.

The objections we still hear

Two objections show up in every conversation about this, and both deserve a real answer.

The first is that cycle time punishes big work. A refactor that takes two weeks will show up as a fat cycle time number and drag the median. Our response: split the refactor. Not into fake tickets that ship in isolation, but into shippable, reversible steps. If a piece of work cannot be split, that is itself a finding, and the fat number is telling us something true.

The second objection is that cycle time can also be gamed. Engineers can open tickets late, close them early, or keep everything in draft. Fair. We have seen all three. The difference is that these games are visible in the version control log and in the Linear activity feed. Velocity inflation is invisible, because the ruler itself is invisible. A gamed cycle time becomes a conversation. A gamed velocity becomes a slide.

The metric we would keep if we could only keep one

If a new engineering leader joined tomorrow and asked which single number to track, we would not hesitate. Track the 90th percentile of cycle time, week over week, and set a target for the tail rather than the average. That number is close enough to reality that people can argue about it usefully, and far enough from planning theatre that it does not warp under pressure. Velocity charts belong in a museum next to lines of code per day. We stopped drawing them and started drawing something harder to fake.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *