Delivery metrics
What the pull request and complexity widgets measure, how to read them honestly, and what they deliberately refuse to tell you.
Hours tell you what a period cost. Delivery metrics tell you how the work moved — what is stuck, what is slow to review, and which pieces were genuinely hard.
They sit on the dashboard and are built from what you already send: commits, pull requests, and the time already tracked against them.
Who sees them depends on whose work they describe. The dashboard has two tabs, and the board follows whichever one you are on.
On My work it covers the pull requests you opened, across every project you can reach — personal projects included. Everyone gets this, because reading how your own work moved is not a management act.
On Team it covers everybody's, across the projects of the organisations you own or administer. Only owners and admins have that tab at all: a board that lets every member rank every other member is a different thing entirely. It never reaches a personal project, so nobody's own side work lands in a team figure.
The team board lists everyone who can reach the projects in scope, including people with nothing recorded for the period — their row simply reads zero. An absent row and a quiet one are indistinguishable, so leaving people out would make it impossible to tell "everyone shipped" from "half the team is missing from this list". Expect non-engineers in the list for the same reason; they sort to the bottom.
Who counts as workforce follows the project's own access rules, so the list shrinks with the project filter: narrow the board to a restricted project and you get its owners, admins and granted members rather than the whole organisation. Anyone who actually opened a pull request in the period stays on the list whatever their access is today — otherwise a revoked grant would leave a merged pull request in the chart with no row accounting for it.
[!NOTE] These are not a ranking, and they are not built to be one. Read the How to read these section before showing them to anyone whose work they describe.
What you need for them to work
Three things, and the widgets stay quiet until all three are true:
Your webhook sends pull request events. Push events alone are enough for time tracking, but a pull request opening pushes nothing at all — without the events there is simply no record that it happened.
There are two subscriptions, and they are separate checkboxes on both providers. Pull requests gives you states, cycle time, merge rate and complexity. Pull request reviews is what makes the review rate, time to first review and review cycles possible — nothing else produces them, and it is the one people most often miss. See Connect a repository.
The repository is linked to a project. Same rule as commits: unattached repositories have nowhere to file anything.
Time is tracked against the work. Effort is the backbone of the complexity metric, and it is the one thing a git host cannot know.
Data accumulates from the moment you subscribe, not before. A pull request merged last month sends nothing today, so the first weeks look sparse. That is expected, and not something to debug.
Pull request states
A single chart: every pull request opened in the selected period, showing where each one stands now.
| State | Meaning |
|---|---|
| Open | Still in flight, and something has happened to it recently |
| Stale | Open, not a draft, and untouched for long enough to be worth asking about |
| Draft | Deliberately not ready — counted separately so it never reads as stuck |
| Merged | Landed |
| Closed | Abandoned without merging |
One pull request, one slice, one denominator. The stale slice is the one that carries an action; the rest are context for it.
Where drafts count
A draft is work in progress, so it is kept out of anything that judges finished work:
- It is never stale — a draft nobody has touched is not a problem.
- It is not classified for complexity. Calling work in progress a quick win is premature, and an abandoned experiment would drag the team's typical effort down with it.
- Closing one does not count against the merge rate. Opening a draft to try something and closing it is not abandoned work, and counting it that way makes a healthy exploratory habit look like churn.
It still appears in its own slice, in the pull requests you opened, and in size figures — because all of those are simply true.
Flow
Every figure on this card describes the same set of pull requests: the ones opened in the selected period, by where they stand today. A pull request opened last week and merged this one belongs to last week's numbers — so this card answers "how is the work we started here going", not "what shipped here". Two consequences worth knowing: cycle time covers only the ones that have landed, so it rises as the rest do, and a pull request that has been stuck since before the period is not counted here at all.
- Merged — how many of them have merged since.
- Cycle time — opened to merged. How long finished work waits.
- Reviewed — the share of pull requests somebody other than the author looked at. Needs the pull request reviews subscription to be complete; without it this counts only merges by a colleague and will read low. That counts a submitted review or a merge by a colleague: merging someone's work is itself an act of review, and it is the only trace left when a reviewer approves without comment. Read this one first: it is the difference between "our reviews are efficient" and "we mostly do not review". A pull request the author merged themselves is the one case with no independent evidence either way.
- Review cycles — how many times a reviewed pull request went back and forth. One means it was reviewed and merged in a single pass. Counted while it is still open, not once it merges, so a pull request on its third round is visible now rather than afterwards.
- Time to first review — opened until somebody first looked. This is a team number, not the author's: it measures how quickly reviewers respond, so reading it as a statement about whoever opened the pull request blames the wrong person.
- Merge rate — merged against abandoned. Persistently low means work is being started that should not have been.
A round of review feedback is the system working, not waste — teams in the top quartile still average slightly more than one cycle per pull request. It is sustained back-and-forth that is worth asking about.
Work complexity
Every measurable pull request is placed in one of five categories.
| Category | What it means | Worth doing |
|---|---|---|
| Quick win | Small and fast | Nothing — this is healthy throughput |
| Deep work | Sustained effort, little code | Protect it. This is the work that gets undercounted everywhere else |
| Heavy lift | Sustained effort and a lot of output | Check it was reviewable — big and slow usually travel together |
| Bulk change | A lot of output for very little time | Usually generated, vendored or a rename. Fine, but not throughput |
| Contested | Reviewed repeatedly, round after round | The requirements, not the developer. Ask what was unclear |
What it is measured on
Effort against output. Effort is the time tracked against the work; output is how much came out of it. Both come from sources that both GitHub and Bitbucket provide, so the same work is classified the same way whichever host it came from.
Where a provider also reports the size of a change, that sharpens the output side. Where it does not — Bitbucket sends no size data at all — the pull request is placed on the other signals rather than being skipped or guessed at.
What it is deliberately not measured on
Lines of code, as the primary signal. A one-line fix found after two days of debugging is the hardest work on the board; a generated migration is thousands of lines of nothing. Ranking by diff size gets both backwards, and it is the easiest number on the board to inflate on purpose.
Size still contributes where it is available — it is genuinely useful for spotting a bulk change — but it can only ever add to the picture, never decide it alone.
Boundaries adjust to your team
Four hours means something different in embedded firmware than in a web app, so the boundaries between categories start from published industry research and then move toward your own team's typical pull request as enough of them accumulate. They cannot drift far enough to call twenty minutes deep work, or a full week light.
The card always says which is in force — the starting defaults, or your team's own — so a category is never a verdict you cannot interrogate.
How to read these
The metrics are built so that gaming any one of them degrades another, and they should be read the same way.
- Volume is context, never a score. Commit counts and pull request counts appear beside flow and rework figures on purpose. On their own they reward the wrong behaviour within a sprint.
- A dash is not a zero. Where there is not enough to say something honest, the figure is withheld rather than estimated. A median drawn from one pull request is not a measurement.
- Compare to the team median, not to each other. It sits beneath every column for exactly this reason.
- Ask, do not conclude. A stale pull request or a contested one is a prompt for a question. None of these numbers know about the outage, the customer call or the afternoon spent unblocking somebody else.
Known limits
Worth knowing before the numbers surprise you:
- Nothing backfills. Coverage starts when you subscribe to the events.
- Bitbucket reports no change size, so those pull requests are placed without it. This is by design, not a gap in the data you can fix.
- Pull requests from forks carry no commits we can see — the pushes go to the fork, not to your repository — so their effort cannot be measured.
- Bot authors are excluded so a dependency bot cannot dominate the board.
- Only reviews that reach us are visible. A pull request reviewed in person, over chat, or on a provider we are not subscribed to looks identical to one nobody read. Where no review has come through at all, coverage reports as unknown rather than 0% — absence of a record is not evidence of absence.
- Review cycles count only pull requests we saw a review on. One merged without a recorded review had no cycles, which is not the same as having had a clean single pass, so it is left out rather than counted as 1.
- Time tracked against the work is what makes it measurable. A pull request with no tracked time is shown as unmeasured rather than counted as zero effort.
Start measuring what your team ships
Output, cost and what your agents burn. Read from the commits, pull requests and agent runs you already have.
Start freeFree for single developers.