The only measure that really counts is whether your software delivery is winning you customers, making the team more efficient, or hitting the goals the business set.
No chart can tell you that.
But when the honest answer is "no", or "I'm not sure", the shape of your pull requests starts to paint a picture. How many are open. How old they are. How fast they get merged. Whether they're getting bigger.
That data is already sitting in your repository. So I built a tool to chart it: pr.lampbristol.com. It's free, there's no sign-up, and it never sees your code.
This article covers what it shows, how to read it, and the patterns worth looking out for.
What it does
Point it at a GitHub repository, or upload a CSV with one row per pull request. It gives you back a dashboard with a permalink you can share.
The charts are grouped into four areas:
Backlog health. How many pull requests were open on the first of each month, split by how stale they were (over 7, 30 and 90 days). Plus the average age of the open backlog, and a breakdown of what's open right now by size and age.
Flow and throughput. Pull requests opened, merged and closed without merging, per month. Net open change, which tells you whether the backlog grew or shrank. And the merge deficit: are pull requests arriving faster than they're merged?
Size and speed. Merged pull requests by size, from S (under 50 lines changed) to XXL (1,000 lines or more). Time to merge, including the median, mean and 90th percentile. And a scatter chart of size against time to merge.
Monthly summary. A table of the last 12 complete months, so you can see the trend without squinting at charts.
There's a demo dashboard built from a real project if you want to have a look before trying your own.
No single number tells you much
It's tempting to pick one metric and watch it. Median time to merge is the usual favourite.
The trouble is that any one number on its own can mislead you.
A median time to merge of a few hours looks great. But if half the open pull requests are more than 90 days old, the project has a problem that the median is hiding.
A team opening lots of pull requests looks busy. But if the backlog is growing faster than the team can review, all that activity is turning into work in progress, and it isn't being delivered.
Combinations matter more than individual metrics. A growing backlog, plus an ageing backlog, plus a rising time to merge, is a far stronger warning than any one of them on its own.
The same goes for the good signs. One of the strongest is activity going up while the size and age of the backlog stay flat. That usually means the team's process is scaling.
Patterns to look for
Over time, most projects settle into one of a handful of shapes.
Balanced flow. Work arrives and leaves at about the same rate. The backlog is stable and young. Review times are steady. This is what you're aiming for.
Scaling successfully. Throughput is rising, but the backlog and its age are staying under control. The team is doing more without getting clogged up.
Fast lane with a stale long tail. Most pull requests are reviewed and merged very quickly, while another group sits open for months. You'll see a very low median time to merge alongside a high average backlog age. It's common in open source, where maintainers deliberately leave low-priority contributions open. In a commercial team it's worth asking what those old pull requests are and why nobody has closed them.
Growing congestion. New work consistently arrives faster than it's resolved. The backlog grows month after month, it gets older, and merges slow down. This one deserves a proper look.
Backlog recovery. The project built up a lot of work in progress and is now clearing it. Stale pull requests are being closed and the backlog is getting younger. Things are improving.
The demo project is a good example of how the numbers combine. In May 2026, 56% of its merged pull requests were merged within a day. That sounds healthy. But 16 of its 40 open pull requests were over 90 days old, the median age of the open backlog was 73 days, and the number open on the first of the month had gone from 9 in August 2025 to 33 in May 2026.
That looks like a fast lane with a stale long tail, drifting towards congestion. Nothing on those charts tells you why, but it does tell you which questions to ask.
Mean versus median
The dashboard shows both, and the gap between them is useful information in itself.
Means get pulled around by a few extreme pull requests. One that has been open for two years will drag the average backlog age up on its own. The median tells you what's typical.
So if the mean is much higher than the median, you've probably got a small number of very old or very large pull requests skewing things. Find them. Often they can simply be closed.
What it doesn't do
It doesn't tell you why.
The data might show that review capacity stopped keeping up with development around March. It can't tell you that someone left, or that the team took on a big new client, or that everyone was busy on a release. You still need to talk to the people involved.
It also doesn't judge the code. Small, fast pull requests can still contain poor code, and a big, slow one might be exactly the right change. It's about how work flows through the team.
Your code stays with you
The tool never sees your code or your pull request titles. It only uses numbers, states, dates and line counts.
With GitHub, you give it a read-only fine-grained token. The link on the page opens GitHub with the options already filled in: read-only access to pull requests, expiring in a day. The token is used once for that fetch and then thrown away. It works for private repositories too, although organisation repositories need fine-grained tokens to be allowed in the organisation's settings. It fetches the newest 5,000 pull requests.
If you'd rather not hand over a token at all, export a CSV yourself. The GitHub CLI can do it in one command:
gh pr list --state all --limit 5000 --json number,state,createdAt,closedAt,additions,deletions | jq -r '["number","state","createdAt","closedAt","additions","deletions"], (.[] | [.number,.state,.createdAt,.closedAt,.additions,.deletions]) | @csv' > prs.csv
Titles never leave your machine.
Getting a second opinion from AI
Each dashboard has a machine-readable version at the same address with .json on the end, and there's a published methodology describing how to assess it.
The "Analyse with AI" buttons open ChatGPT or Claude with a prompt that points at both. You get a written health report: a score out of 10, the flow pattern, what looks good, what's concerning, and what to investigate next.
It's not a replacement for knowing the team. But it's a quick way to get a structured first read, and it's pretty good at spotting combinations of signals that are easy to miss when you're looking at one chart at a time.
Try it on your own project
Run it on a repository you know well first. See whether the charts match how the project felt. If they don't, that's worth knowing too.
Then try it on the one you're not sure about.
If the picture it paints isn't the one you want, that's the kind of thing we help with through Steer.
What would you expect your own pull requests to say about your project?
/// More articles
PHP Has Had Generics for Years. You're Probably Just Not Using Them.
Read the article →Rector Isn't Just for Upgrades. Most Teams Are Using a Tenth of It.
Read the article →Stop Writing Coding Standards Documents. Write PHPStan Rules Instead.
Read the article →Start a conversation
We help teams put these ideas into practice, through training, code review and working alongside you. Tell us where you are and what you're aiming for.