Margin12 min read

The Cost of Senior Developers Doing Junior Work, in Pounds

How role-rate variance silently erodes agency margin when senior staff absorb work below their cost line. Worked tables of role rate × employee cost across four common scenarios, with the conditional logic that should drive who works on what.

In short

The most expensive recurring leak we see at agencies is not scope creep. It is senior staff quietly doing work that was scoped, priced and budgeted at junior rates. It rarely shows up on a closing pack because role-rate accounting hides it: the project was budgeted at the lead developer's rate, and the lead developer did the work, so on paper the numbers match.

In real-cost terms they don't match. A lead at £190 per hour role rate costs the agency around £85 per hour to deliver. A mid at £130 per hour role rate costs the agency around £45 per hour to deliver. When the lead does the mid's work, the agency invoices at lead rate (correct) but pays £85 for an hour that should have cost £45. That's £40 of margin per hour, on every hour of senior-covering-junior work.

For a 200-hour project where 60% of the work that should have been mid-level was quietly absorbed by the lead, the leak runs to roughly £4,800. Across forty projects a year, that's a low-six-figure number that nobody on the team is doing anything wrong to produce.

This piece explains the math, gives the four-scenario table we use internally, and lays out the staffing rule that makes the leak stop.

In the post-mortem on our own first heavily-bleeding project, we discovered something that wasn't obvious to anyone on the team and only became obvious after we built a tool to make the numbers visible: the lead developer had quietly been doing roughly half of the work that the estimate had budgeted for two mid-level developers.

He hadn't escalated. He hadn't re-quoted. He'd just done the work, because shipping mattered and the mids couldn't crack the trickier tickets fast enough. The project's labour margin, computed at role rate, looked fine. The project's real margin, once we costed each worklog at the named individual's actual hourly cost, was about £6,400 worse than the labour-margin report claimed.

That £6,400 is the topic of this article. Not the leak we caught — the leak we'd been bleeding silently for six months on every project we celebrated.

Why the labour-margin report hides this

A standard labour-margin calculation works like this:

  • Take the invoiced revenue for the project.
  • Multiply hours logged by role rate (the rate the client was billed for).
  • Subtract the second number from the first.

The arithmetic is internally consistent. But it answers a different question than the one you actually want to answer. It tells you whether the project priced its labour at a sustainable rate. It does not tell you whether the labour the project consumed was at the cost the price assumed.

For that, you need to compute against named people × their real hourly cost × their actual hours. The variance between what the project sold a role for and what the agency actually paid the named person delivering it is the place margin moves the most quietly.

A four-scenario table

We use a table like this internally on any pricing review that involves a lead-plus-mids role mix. The numbers are illustrative; the structure is the one to copy.

Assume a 100-hour sprint. The estimate budgets it at 25 hours of lead time at £190/hour role rate (£4,750 of revenue) and 75 hours of mid-level time at £130/hour role rate (£9,750 of revenue). Total invoice: £14,500.

Assume real hourly cost of the lead is £85, and real hourly cost of each mid is £45.

ScenarioLead hoursMid hoursLead costMid costTotal costReal margin £Real margin %
A: To plan. Lead does 25h, mids do 75h2575£2,125£3,375£5,500£9,00062.1%
B: Lead absorbs 30 mid hours. Lead does 55h, mids do 45h5545£4,675£2,025£6,700£7,80053.8%
C: Lead absorbs 50 mid hours. Lead does 75h, mids do 25h7525£6,375£1,125£7,500£7,00048.3%
D: Lead does the whole thing. Lead does 100h, mids do 0h1000£8,500£0£8,500£6,00041.4%

Same invoice. Same hours. Same role-rate report. Real margin moves from 62% to 41% — a 21-percentage-point swing — entirely on staffing variance below the role line.

Scenario B is the realistic one for most projects. The lead picks up the harder mid-level tickets that nobody else can crack quickly, the mids do the rest, the project ships. The labour-margin report says nothing has gone wrong because nothing has gone wrong. The project just earned 8 percentage points less than it had to.

This is what Scenario B looks like on the role-variance screen of the layer that became Saldo. The estimate is held against actual cost per named individual, not against role rate. The lead's overrun and the mids' under-run cancel out in the labour-margin frame, but the real-cost frame surfaces the £1,200 of cost the project absorbed without anyone billing for it.

saldo.team / projects / client / role-variance
Role-rate variance · scenario B
Lead covering mid work — what Saldo surfaces
100-hour sprint · £14,500 invoice · same hours, same role-rate report
Hours by role · plan vs actual
Lead — plan
25h
Lead — actual
55h · +30h
Mid — plan
75h
Mid — actual
45h · −30h
Real cost · plan vs actual
Plan cost
£5,500
Actual cost
£6,700
Variance
+£1,200
Labour-margin report
62%
says nothing went wrong
Real saldo
53.8%
−8.3 pts vs plan
Cause
Wrong people
not scope, not rate

Now multiply that across the forty active projects an 80-person agency runs in a quarter. At an average project value of £35,000, an 8-percentage-point margin compression on each is £2,800 per project, or £112,000 a quarter. A quarter of a million pounds a year. Nobody on the team is doing anything wrong to produce it.

The "of course they did" defence

When we first surfaced this number internally, the immediate pushback from the engineering side was: of course the lead absorbed the work. The mids couldn't do it. The project had a deadline. We're an agency, not a textbook.

That's correct. It's also not a defence. It's a description of the leak.

The defence that is available — the one we eventually adopted — has three parts:

  • The lead's involvement was always going to be necessary. The estimate underestimated it. The remedy is a better estimate next time, not a heroic recovery this time.
  • The mids couldn't do the work because they hadn't been senior'd by the lead through earlier sprints. The remedy is a deliberate skill-transfer plan with hours costed at lead rate and explicitly priced into the engagement.
  • The lead enjoyed doing the work because the work was interesting. The remedy is to scope the engagement so the interesting work is at lead rate, not absorbed for free.

Each remedy converts what looks like an ad-hoc heroism into something the agency can price. None of them require the team to be more disciplined or to log time better.

The conditional logic that should drive who works on what

The single most useful change we made on the back of this analysis was to put a soft conditional rule in the staffing process. It's a sentence, not a process:

When a worklog from a more expensive person lands on a ticket that was estimated at a lower role, the project lead is expected to either escalate it (if the cost is necessary and the client should know) or defend it (if it's a one-off coverage moment that won't repeat).

In practice this is a Slack message that goes to the project lead automatically when an unexpected role shows up against a ticket. It is not a policing mechanism — it is an interruption that says "this might cost something to absorb; check it's intentional".

About 30% of the messages produce no change: the project lead defends the cost (transfer of skills to a junior, a one-off complexity, a relationship hour). About 50% produce a small re-staffing — the lead steps off the ticket and a mid picks it up, sometimes with a brief synchronous handoff. About 20% produce a real action: a mid-flight conversation with the client about an extra line item, a follow-up estimate for support work that was off-spec, or a heading-off of a pattern before it compounds.

The 30% / 50% / 20% split is roughly stable across the agencies we've seen install this rule. Two-thirds of the leak gets fixed without anyone changing how they work; the rest gets surfaced for a real conversation.

Why it never gets fixed in role-rate reporting

A labour-margin report can't surface this leak because the report works at the role-rate granularity. It does not know that the named person is more expensive than the role they're working at. It cannot know, because the cost number is not in the system at the granularity that would let it know.

To surface this you need three things in your reporting layer:

  1. A real, fully-loaded hourly cost per named individual. Not derived; entered. Updated when salaries change, with a snapshot kept of the previous number for historical reports.
  2. Worklogs costed at the named individual's number. Not at the role rate, not at the project's blended rate. At the cost of the person who logged the time.
  3. A surface that compares the real-cost line against the role-rate line, mid-flight. A chart, an alert, anything — but it has to update during the project, not after it.

Without all three, you cannot see this leak. With all three, you see it within the first week of a project going off-plan.

How to surface this with the engineering team without losing them

The conversation with the engineering side, the first time you put this analysis on a table, has to be handled carefully. The risk: engineers hear "we're tracking when seniors do junior work and treating it as a problem" and reasonably interpret that as a discipline mechanism — a way to keep them on the tickets they were assigned, regardless of whether the project's success benefits.

That interpretation will kill the analysis within a week. Engineers will either log time defensively, find ways to make worklogs less specific, or stop volunteering for the harder cross-role tickets that genuinely need senior judgement. Any of those outcomes is worse than the leak.

Three communication moves we use, in order of importance:

  • Frame it as cost visibility, not cost discipline. The point of seeing role drift is not to prevent seniors from helping — it's to surface when senior help is happening, so the agency can either price for it (when it's a recurring pattern) or absorb it consciously (when it's a one-off). Seniors are not in trouble for absorbing junior work. The agency is in trouble when it absorbs it without knowing.

  • Defend the senior's discretion. When the role-drift query fires on a ticket, the project lead's question is "why" — not "stop". The right "why" answer can be: "the mid couldn't crack it before the deadline and the alternative was a partial ship". That answer ends the conversation. Sometimes the answer is "I enjoyed doing it" — also valid, but now it's a pricing conversation rather than a delivery conversation.

  • Show the variance to engineering, not just to finance. Once a quarter, share the role-drift summary with the engineering leadership. The pattern is almost always interesting to engineers (which roles are reliably absorbing higher-cost work, and on which kinds of project). It usually changes how seniors offer themselves on the next quarter's projects.

The first three months of running this analysis will produce some defensive reactions. By month six, in our experience, the engineering side has internalised that the variance is being measured for cost, not being policed for behaviour. The conversation about who should be on which ticket becomes more honest, in both directions — engineers ask for senior help when they need it, seniors decline absorbing low-leverage tickets, project leads re-staff before the leak compounds.

How we built it for ourselves

I built the layer that does this for the agency I was CTO of, because the off-the-shelf options either treat labour as a single role-rate line (the Jira plugin pattern) or replace Jira altogether (the platform pattern). Neither was workable for us — the first hides the variance, the second forces a re-platform of every active project. So I wrote a thin layer that reads from Jira's API, costs every worklog at the named individual's real hourly cost, and presents the role-rate vs employee-cost variance per project.

The layer is now Saldo. The founding-agency case study is two years of internal use at the agency where I built it. The pricing page is what it costs other agencies who want to skip the build year that went into it.

The shorter version: if your project margin is computed against role rate, the cost of senior developers doing junior work is invisible to you. If you cost worklogs against real employee cost, it stops being invisible the next day. The leak doesn't disappear immediately — but it stops being a leak you can't see, and that turns out to be most of the fix.

Going deeper: How Saldo calculates margin — estimate by role rate, actual by employee cost

Continue inside Saldo

More on this topic

Margin11 min read

What Project Margin Actually Is, for a Digital Agency

A definitional piece for finance directors and agency owners. Project margin is not invoice value minus labour cost. It is the share of project revenue left after labour at real cost, allocated overhead, and any unbilled scope. Worked example, common mistakes, and the formula that survives audit.

Popular reads