Jira8 min read

Why Your Jira Projects Don't Map to Your P&L (and How to Fix It)

Jira projects are organised for delivery — one key per client, per team, per product. Your P&L is organised by contract. The two almost never line up, which is why agencies with perfect worklogs still can't answer what a specific engagement earned. Here is the mapping layer that fixes it.

In short

Almost every agency I talk to has the same quiet structural problem: Jira is organised for delivery and the P&L is organised for money, and the two use different units. Jira thinks in projects, boards and epics. Finance thinks in contracts, SOWs and invoices. A single Jira project routinely carries three different commercial engagements, and a single contract routinely spans two Jira projects.

The result is that even an agency with disciplined worklogs cannot answer the question "what did this engagement earn us" without an analyst spending an afternoon untangling tickets. The margin number exists in theory; in practice nobody can compute it without archaeology.

The fix is not restructuring Jira around your contracts — that punishes the delivery team for finance's reporting needs, and it doesn't survive the next re-organisation anyway. The fix is a mapping layer: sub-projects assembled from Jira's own structure (epics, components, labels), each mapped to one commercial engagement with its own type, its own rates, and its own margin line.

This piece is why the mismatch exists, why the two obvious fixes fail, and what the mapping layer looks like in practice.

Ask a CFO at a 50-person agency to name the margin on a specific support retainer and watch what happens. The revenue side takes thirty seconds — it's an invoice line. The cost side takes the rest of the week, because the retainer's hours live inside a Jira project called ACME that also contains a fixed-price build, a discovery sprint that was sold separately, and two years of internal account-management tickets that were never billed to anything.

The worklogs are fine. The people logged their time honestly, against real tickets, in the right project. The problem is that "the right project" is a delivery concept, and the question being asked is a commercial one.

I ran into this at the agency where I was CTO, and it took me longer than I'd like to admit to see it as a structural problem rather than a discipline problem. We kept asking the team to log time "more carefully", as if the missing information were carelessness. It wasn't. The information the P&L needed — which contract does this hour belong to — had nowhere to live in the structure we'd given Jira.

Two systems, two different units of account

Jira's unit of account is the project: a container for a board, a backlog, a workflow, a set of permissions. Agencies key their Jira projects to whatever makes delivery sane — usually one per client account, sometimes one per team or per product. That's the correct choice. A delivery team should not have its board carved up to match the finance department's filing system.

The P&L's unit of account is the engagement: a signed SOW, a retainer agreement, a change order with its own price. This is also the correct choice. Revenue arrives per contract, and margin is only meaningful per contract, because that's the level at which price was set.

The mismatch shows up the moment one client has more than one engagement — which, for any client worth keeping, happens within the first year:

What the client boughtCommercial shapeWhere it lives in Jira
Platform rebuildFixed price, senior-heavy teamEpics inside ACME
Monthly support retainerFixed monthly fee, capped hoursTickets inside ACME
Discovery for phase 2Time & materials, discounted rateMore epics inside ACME
Account managementNot billed at allAlso inside ACME

Four different economics — three of the project types every agency runs, plus unbilled internal work — one Jira key. Each engagement has a different pricing model, often different people, and frequently different rates: the rebuild was priced on senior role rates, the discovery was discounted to win phase 2, the retainer was priced two years ago and never reviewed. Roll them up into one "ACME margin" number and you learn nothing: the healthy build subsidises the decayed retainer, and the blended number looks acceptable right up until the build ends and the retainer is all that's left.

The two obvious fixes, and why they fail

Fix one: restructure Jira around contracts. One Jira project per SOW. It sounds clean and it fails within a quarter. The delivery team now has its work scattered across ACME-BUILD, ACME-SUPPORT and ACME-DISCO, with three backlogs, three boards and three permission schemes for what is, operationally, one client relationship. Cross-engagement work — the support ticket that turns into a change request — needs migrating between projects, and every migration loses history. And when the next contract is signed, someone has to create and configure a new Jira project before the team can log a single hour. Delivery pays a permanent tax so that finance's reports come out pre-sorted. The team quietly reverts within months, and I don't blame them.

Fix two: make finance do it by hand. Export the worklogs monthly, sort tickets into engagements in a spreadsheet, apply rates, reconcile. This is where most agencies actually live. It works, in the sense that a number eventually appears — but it appears three weeks after month-end, it depends entirely on one analyst's memory of which epic belonged to which SOW, and it is archaeology: by the time the number says a retainer is underwater, it has been underwater for a quarter. I've written before about why project losses surface too late; this manual mapping step is one of the main reasons.

Both fixes fail for the same underlying reason: they try to make one system hold both units of account. Jira can't be the P&L and the delivery tool at once, and a spreadsheet can't be a continuous mapping layer.

The mapping layer: sub-projects assembled from Jira's own structure

The fix that actually holds is to leave Jira alone and build the mapping one level up. The delivery team keeps one Jira project per client, organised however delivery wants. The financial layer then assembles sub-projects — one per commercial engagement — by pulling tickets from Jira along the structure that already exists:

  • The platform rebuild's epics → sub-project "Rebuild", type: development, fixed price.
  • Tickets tagged with the Support component → sub-project "Support retainer", type: support, monthly fee.
  • The discovery epics → sub-project "Phase 2 discovery", type: T&M at the discounted rate.
  • Everything else → internal, costed to overhead, visible rather than vanished.

Each sub-project carries its own commercial context: its own engagement type, its own revenue line, and — this matters more than it sounds — its own rates and its own expected team. The rebuild was estimated on senior role rates; the retainer assumed mid-level staffing; the discovery was priced at a discount. When the same hour of the same person costs into different engagements at different expectations, the variance between what was priced and what the person actually costs finally becomes visible per engagement, instead of averaging out into a blended number that flatters everyone.

One client, one Jira project, four margin lines. The P&L question — "what did this engagement earn" — now has a first-class answer, because the engagement finally exists as an object somewhere.

This is how Saldo models it, for what it's worth: sub-projects assembled from epics, components or JQL, each with its own type and rate card, computed continuously from the same worklogs the team was already writing. But the pattern is tool-independent — you can build the same mapping in a warehouse job or, painfully, in the spreadsheet you already have. What matters is that the mapping is declared once and computed continuously, not re-derived by hand every month-end.

What Jira needs to provide (very little, but not nothing)

The mapping layer can only pull along structure that exists, so Jira needs to offer a seam for each engagement boundary. In practice that means the conventions I described in the Jira configuration piece: epics that correspond to sold work rather than loose feature groupings, and a component (or label) that separates ongoing support from build work. That's the whole ask. Nobody logs time differently; nobody's board changes.

The one habit worth enforcing at the commercial boundary: when a new SOW is signed, the mapping is updated the same week. A new engagement gets its epics (or its component) and its sub-project before meaningful hours land against it. The failure mode of every mapping layer is drift — work sold in March that finance discovers in June, sitting unmapped in the "everything else" bucket. Make the mapping update part of the deal-closed checklist, next to raising the first invoice.

What changes when the mapping exists

Three things, in my experience, and they arrive quickly.

Retainer decay becomes visible while it's still cheap to fix. A support retainer priced two years ago, drifting from mid-level to senior staffing, shows a margin line falling month over month — on its own line, not blended into a healthy build. The repricing conversation happens a quarter earlier, with numbers instead of feelings.

Discounts stop being invisible. The discovery sold at a discount to win phase 2 shows exactly what the discount cost. Sometimes it was worth it. Now "sometimes" is a number, and the next discount conversation starts from evidence.

The blended client number stops lying. "ACME is at 38%" becomes "the build is at 52%, the retainer is at 9%, the discovery broke even". Same client, same worklogs — but only the second sentence tells you what to do next.

The mismatch between Jira and your P&L is not a discipline failure and it will not be fixed by asking the team to log time more carefully. It's a missing layer, and the layer is buildable. If you'd rather see it running than build it — the 15-minute demo runs on your real Jira data, sub-projects and all, and we don't ask for card details up front.

Going deeper: Saldo vs Tempo and Productive — where it lives, why it doesn’t replace Jira

Continue inside Saldo

More on this topic

Jira7 min read

Giving Your CFO Jira Access Without the Admin Keys

Finance needs to read Jira — worklogs, estimates, project structure — but a CFO with a Jira admin account is the wrong answer to the right question. How agencies give finance a real view of delivery data: scoped accounts, dashboards, and a financial layer where every role reads the same numbers in the unit that fits their job.

Jira7 min read

Jira Cloud vs Data Center for Agencies: What Changes for Profitability Reporting

The delivery experience of Jira Cloud and Jira Data Center is nearly identical. The finance experience isn't. Authentication, worklog APIs, data residency and plugin economics all differ — and they decide which financial tooling your agency can actually run. A practical comparison for agency CTOs and finance leads.

Jira8 min read

How to Get Honest Worklogs in Jira Without Policing Your Team

Every margin number is downstream of the worklogs, and worklogs go wrong for predictable reasons — most of them incentives, not laziness. Six steps to time data you can trust: what to ask for, what to stop rewarding, and why surveillance produces worse numbers, not better ones.

Popular reads