Agency OS Skill Library

Profit By Client

Shows which clients and service lines actually make money once delivery cost and hours are counted, and which are quietly subsidizing the rest.

Finance profit-by-client
Back to all skills

What it does

A whole-business blended margin hides the one decision that moves a service business's numbers: which specific clients and services make money once you count what it costs, and how long it takes, to deliver them. This skill decomposes the blend. You supply a table of revenue, direct cost and hours per client or service line; it computes the contribution margin of each one, ranks the money-losers against the hidden stars, reads how concentrated your revenue and margin really are, and hands back an action list per problem account: reprice, systematize, upsell or exit. Every finding traces back to a row in your table, with the formula and a worked line shown, and the per-segment margins are written to your workspace metrics snapshot so the dashboard and downstream skills can read them. It is a repeatable method with a fixed input template, not a one-off spreadsheet interrogation.

Say this to start

This skill has no button. You start it by saying what you want. Any of these will do it:

> profit by client
> which clients actually make money?
> who is actually paying for this?
> margin by service line
> which account is losing money?

When to reach for it

When NOT to use it

If you actually wantUse this instead
bookkeeping: categorizing expenses, reconciling a ledger, tax-ready accountsyour accountant or bookkeeping software; this skill reads a table, it does not keep books
the exit or rescue conversation with a client the ranking says is unprofitableclient-retention
designing the new price once the ranking says a segment must be repricedoffer-architect
cutting the delivery hours that make an account expensive to serveclient-delivery-engine
a one-off question about a spreadsheet with no repeatable template behind itask it directly in chat; this skill exists for the recurring margin read, not ad-hoc queries

Before you start

The whole skill runs off one input: a table with a row per client or service line. Paste it, drop a CSV or spreadsheet, or answer conversationally and the skill will assemble it. Each row carries:

ColumnWhat it means
segmentthe client or service line the row describes
revenuewhat that segment paid you over the period
direct delivery costmoney spent specifically to serve that segment: contractors, software seats, ad spend passed through, media
hours to serveteam hours spent delivering for that segment over the same period
loaded hourly costwhat an hour of delivery actually costs you: salary plus overhead and tools, divided by working hours, not the raw wage

Missing hours mean exclusion, not estimation. If a segment's hours cell is blank, that segment is flagged in the provenance header and left out of the ranking. The skill will not guess the hours, and it will not silently drop the row either; you are told exactly what was excluded and why. If you track no hours at all, the skill runs on revenue and direct cost alone and says plainly that the labour view is unavailable.

What you needWhy
The revenue-and-cost table above, covering one consistent periodevery number in the output derives from this table; mixing months and quarters in one table corrupts the rankingRequired
A loaded hourly cost you believethe labour side of every margin is hours times this figure; a raw salary number understates it and flatters every accountRequired
A decision on which workspace you are in, _default for your agency or client--* when running it on a client's businessthe memo and the metrics snapshot land in the active workspaceRequired
Hours tracked per segment, even roughlywithout hours a segment drops out of the labour ranking; a calendar-based estimate you stand behind beats no number, but the skill will never invent one for youOptional

How it runs

  1. Provenance firstOpens with a provenance header before any finding: where the data came from, the period it covers, how many rows were read, and which rows were excluded and why. If that header cannot be written honestly, the analysis stops there.
  2. Contribution margin per segmentComputes revenue minus direct cost minus labour, where labour is hours to serve times loaded hourly cost. The formula is shown along with at least one fully worked line so you can check the arithmetic yourself.
  3. Margin percent, rounded honestlyDivides contribution margin by revenue for each segment and rounds to the precision the data actually supports, no false decimal places.
  4. Rank and flagRanks every segment by contribution margin in money, and separately flags the low and negative margin-percent segments: the accounts the rest of the book is quietly subsidizing.
  5. Concentration readReports what share of revenue and what share of margin your top few segments represent, side by side. This is where the busy-but-broke pattern becomes visible: a flagship account can dominate revenue while contributing little or negative margin.
  6. Action listFor each money-loser or thin-margin segment, a specific move grounded in that segment's own numbers: reprice toward a stated rough level, systematize to cut delivery hours, upsell into better-margin work, or exit. No generic advice.
  7. Write the snapshotWrites the per-segment margins to brand/reports/metrics-snapshot.md in the workspace, so the dashboard and downstream skills read the same numbers you just saw.

What you get

Honest limits

Read this before you rely on it

Where people go wrong

The mistakeDo this instead
Trusting the blended margin because it looks healthyDecompose it. A comfortable blend routinely hides a flagship account running at a loss, paid for by your smallest, quietest clients.
Ranking clients by revenue and calling the biggest one the bestRank by contribution margin. As an invented example: a client paying 6,000 for the period who takes 90 delivery hours at a loaded 60 per hour has already cost 5,400 in labour before a single direct cost, while a 4,000 client needing little delivery time may out-earn them.
Guessing hours for a client nobody tracked, just to complete the rankingLet the skill exclude and flag that client, then go get the real hours. A ranking with an honest gap beats a ranking with an invented number in it.
Using raw salary as the hourly costLoad it: salary plus overhead, tools and management time, divided by actual working hours. The unloaded figure makes every account look better than it is.
Mixing periods, one client's quarter against another's monthOne period per table, every row. Rerun the skill per period rather than blending them.
Firing a client off a single period's rankingRerun it on another period first. Onboarding-heavy months and one-off projects distort hours; act on a pattern, not a snapshot.
Worth knowing

The most common finding is not a small bad client. It is the flagship: the largest account, the one everyone serves first, showing negative contribution once hours are counted. That is why the ranking uses margin in money and margin percent side by side, and why the concentration read sits next to it. The account that fills your calendar and the account that funds your business are often not the same account.