Margin
MSP gross margin, and what to do when it is thin
MSP gross margin is revenue minus the fully loaded cost of delivering the service, divided by revenue. Cost of goods sold for an MSP means delivery labour, per seat tooling, subcontracted delivery such as an outsourced NOC, and any licences you carry. It does not include sales, marketing, admin or premises. Calculate it separately for recurring services, projects and hardware, and per client. A blended figure is the number that hides which of the three is losing money.
Kyslan finds the unbilled work in your own PSA, then writes the change order that bills it. First report free, read-only. Claim it back →
The formula, and what goes in it
Gross margin % = (revenue − cost of goods sold) ÷ revenue
At $92,000 of managed services revenue and $38,000 of delivery cost: (92,000 − 38,000) ÷ 92,000 = 58.7%.
The formula is trivial. Every real disagreement about MSP margin is a disagreement about what belongs in cost of goods sold, and it is worth settling once and writing down, because a margin figure calculated two different ways in two different months is worse than no figure at all.
What belongs in an MSP cost of goods sold
| Cost | In COGS? | Why |
|---|---|---|
| Service desk and field engineers | Yes | Their time is consumed delivering the service |
| Employer taxes, benefits, insurance on those people | Yes | Fully loaded or the number is fiction |
| RMM, PSA, security, backup, documentation tooling | Yes | You cannot deliver without them |
| Outsourced NOC, SOC, overnight cover | Yes | Substituted delivery labour |
| Licences you buy and resell | Yes | Direct cost of a revenue line |
| Hardware you resell | Yes | Direct cost of a revenue line |
| Service delivery manager | Usually | If the role exists to deliver rather than to sell |
| Sales and marketing | No | Operating expense, recovered from margin |
| Finance, HR, owner's admin time | No | Operating expense |
| Premises, insurance, professional fees | No | Operating expense |
The two lines people argue about are the service delivery manager and the owner. The test that settles both: if the client base doubled, would you need more of this? If yes, it is cost of delivery. If the role would stay the same size, it is overhead.
Split it by service line
Three lines, three very different shapes:
| Line | Cost shape | Expect |
|---|---|---|
| Recurring managed services | Mostly fixed tooling, leveraged labour | Your highest margin, and the one that should improve with scale |
| Projects | Labour heavy, estimated, variable | Lower than recurring. Overruns land entirely on this line |
| Hardware and licence resale | Almost entirely direct cost | Thin by nature. Volume, not margin |
Report them separately every month. A single blended figure moves when your mix moves, so a quarter with heavy hardware resale looks like a margin collapse when nothing about your delivery changed, and a quarter with no hardware looks like an improvement you did not earn.
Then split it by client
Per-client gross margin is the report that changes decisions, and it needs one input most MSPs have and do not use: hours worked per client.
- Take total hours logged against the client over 12 months, billable and non-billable.
- Multiply by your fully loaded cost per delivery hour.
- Add tooling cost for their seats and devices, and any licences you carry for them.
- Compare against everything you invoiced them in the same 12 months.
Sort the result ascending. In most MSPs the bottom three clients are consuming a disproportionate share of delivery capacity while contributing a small share of margin, and nobody has ever seen it stated in one line because the reporting has always been blended.
Hours logged is only as good as your time entry discipline. If tickets close with no time entry, the client looks cheaper to serve than they are and their apparent margin is overstated. Before you act on a per-client margin report, check what proportion of closed tickets carried zero time. If it is more than a few percent, fix that first or you will make a pricing decision on a number that is wrong in the client's favour.
The five causes of thin margin
1. Unbilled work
Delivery cost incurred against revenue never raised. It hits margin twice: the cost is in the numerator's subtraction and the revenue is missing from the denominator. Published billing research puts this at 5 to 15% of revenue for a typical provider, which on its own can be the entire gap between an acceptable margin and a poor one. See the eleven leaks.
2. Price never moved
Wages, tooling and security requirements all rise annually. A contract signed three years ago at a price that has not changed has lost several points of margin without a single thing going wrong operationally. This is the most common cause in long-established MSPs and the easiest to miss, because nothing breaks.
3. Tooling stack grown by accretion
Each individual tool was justified. Nobody ever removed one. Add up per seat tooling cost and compare it against per seat price: when tooling is consuming a large share of the seat price, no amount of operational efficiency recovers the margin.
4. Scope delivered beyond scope sold
The contract says one thing, the service desk does another, usually for good reasons and always for free. Compare ticket categories against the agreement's inclusion list for your five largest clients, and the gap will be concrete rather than theoretical.
5. Rework and repeat tickets
The same underlying fault generating tickets that are each closed individually. This is pure cost with no revenue attached under a recurring contract. Reopen rate and repeat tickets per client per month find it.
The fixes, ranked by speed
| Fix | Effect | Time to impact | Client risk |
|---|---|---|---|
| Bill the work already delivered | Direct, both sides of the ratio | One billing cycle | Low with evidence attached |
| Correct seat and device counts | Recurring, compounding | One billing cycle | Low, it is an administrative fix |
| Apply overdue annual uplifts | Permanent, compounding | Next renewal | Low if the clause exists |
| Enforce the scope boundary | Stops the bleeding | 1 to 2 months | Medium. Needs explaining first |
| Consolidate the tooling stack | Cuts fixed cost per seat | 3 to 6 months | Low, invisible to clients |
| Fix repeat-ticket root causes | Cuts hours per endpoint | 3 to 6 months | None, clients prefer it |
| Reprice the bottom clients | Largest single effect | Next renewal | High. Do it last, with data |
The order matters. Repricing is the biggest lever and the riskiest, and doing it first means asking a client for more money while you are still absorbing work you never billed them for. Recovering what you are already owed costs no goodwill and frequently closes most of the gap, which makes the repricing conversation smaller when it comes.
The blended margin trap
One MSP, one month, two ways of reporting:
| View | Revenue | COGS | Margin |
|---|---|---|---|
| Blended | $140,000 | $71,400 | 49% |
| Recurring only | $92,000 | $34,500 | 62.5% |
| Projects only | $26,000 | $14,900 | 42.7% |
| Hardware only | $22,000 | $20,000 | 9.1% |
The blended 49% invites no action. The split shows a healthy recurring book, projects that are being estimated too tightly, and hardware being resold at close to cost. Those are three different problems with three different owners, and blending them produces one number that describes none of them.
Report the split, per client, monthly. And check that the hours behind it are real, because a margin report built on incomplete time entry is a confident answer to the wrong sum. That check is what Kyslan automates, read-only, against your PSA.
Common questions
What counts as cost of goods sold for an MSP?
Delivery labour fully loaded with employer taxes and benefits, per seat tooling such as RMM, PSA, endpoint security and backup, subcontracted delivery such as an outsourced NOC or SOC, and any licences or hardware you buy and resell. Sales, marketing, finance, HR and premises are operating expenses and sit below gross margin. The test for a borderline role is whether you would need more of it if the client base doubled.
Why is my MSP gross margin falling?
The five usual causes are unbilled work, prices that never moved while wages and tooling rose, a tooling stack that grew by accretion, scope delivered beyond scope sold, and repeat tickets from unfixed root causes. Unbilled work hurts twice, because the delivery cost is counted and the matching revenue is absent, so it is the one worth ruling out first.
Should MSPs report blended gross margin?
No, or at least not on its own. Blending recurring services, projects and hardware resale produces a figure that moves with revenue mix rather than with performance, so a hardware-heavy quarter looks like a margin collapse when nothing about delivery changed. Report the three lines separately, and report per client margin alongside them.
How do I calculate gross margin per client?
Take twelve months of hours logged against that client, billable and non-billable, multiply by your fully loaded cost per delivery hour, add tooling cost for their seats and devices plus any licences you carry, and compare that total against everything you invoiced them in the same period. The result is only as reliable as your time entry, so check how many closed tickets carried no time before acting on it.
What is the fastest way to improve MSP gross margin?
Invoice the work you have already delivered and never billed. It is the only lever that improves both sides of the ratio at once, it lands within a single billing cycle, and it carries low relationship risk when the evidence is attached. Correcting seat and device counts on agreements is the next fastest, and unlike a price rise it is an administrative fix rather than a negotiation.
Keep reading
See your own number, then send the invoice for it
Kyslan reads 90 days of your tickets, time entries and contracts, finds the work you delivered and never billed, then writes the change order that puts it back on the invoice. Read only, nothing installed, first report free.
Claim it backFree · read-only key · no card · HaloPSA, ConnectWise Manage, Autotask PSA or a CSV export