Skip to content
stack-review/eleven-tool-agency-couldnt-tell-its-margin.mdx← all teardowns
[stack] the_stack_review

Stack Review 01: the 11-tool agency that couldn't tell you its margin

14 people, eleven tools, and a number nobody could produce in under a day: this month's gross margin. The 30-day fix.

· 5 min · EN/ES

A 14-person agency I looked at ran eleven tools and could not tell me its gross margin for the month we were sitting in. Not wouldn't. Couldn't. The number existed, but in pieces across four systems, and assembling it took an analyst the better part of a day. So in practice it got produced once a quarter, and by the time anyone read it the number was sixty days stale.

That is not a tooling shortage. It is the opposite.

Here is what the eleven tools were actually doing. Revenue lived in the invoicing system. Delivery labor lived in a time tracker that maybe 60% of the team logged into. Contractor costs sat in a separate bill-pay tool. Who worked on what lived in the project manager. And "the real numbers" lived in a spreadsheet one person rebuilt by hand every quarter, which everyone quietly trusted more than the eleven tools combined.

Eleven systems, and not one of them could answer "what did we keep on Client X this month," for one boring reason: no two of them agreed on what Client X was called. "Acme Co" in invoicing, "Acme Inc." in the PM tool, "ACME" in the time tracker. The data was all there. It just could not be joined.

So the analyst did it by hand, four exports at a time, which is why it happened four times a year instead of twelve.

Here's the method I use to fix this. I call it the Margin Spine, and it fits in 30 days because you are wiring up one number, not building a platform.

  1. Define the one number in one sentence. Gross margin = revenue recognized this month, minus direct delivery cost (delivery payroll allocated to client work, plus contractors, plus billable software), by client. Write it down. Most of the six-hour ritual was people silently disagreeing on what counted.

  2. Force a single join key. Pick a canonical client ID and make every system carry it. This is the unglamorous 70%, and it is the whole game. Until "Acme" is the same Acme in all four tools, nothing downstream works.

  3. Name one system of record per input. Revenue: invoicing. Labor: the time tracker. Contractors: bill-pay. One source each, no duplicates, no spreadsheet shadow copy. If two tools claim the same number, one of them loses on purpose.

  4. Build a thin pipe, not a platform. A scheduled nightly pull from those four sources into one table, joined on the canonical ID. No new app. No migration. You are connecting the stack you already have, not buying a twelfth tool.

  5. Give it one owner and an error path. Rows that don't match the key get flagged, not dropped. One person owns clearing the flag queue. Silent failure is how these things rot back to a spreadsheet within a quarter.

The math, before and after. Before: about 6 hours of one analyst stitching exports, run four times a year, always reading the past instead of the present. After: margin by client lands in one table by 7am daily, with unmatched rows flagged for review. The assembly cost goes to roughly zero.

But the assembly time was never the real win. The real win was the first clean read. With margin finally visible by client, the picture was not the comfortable 45% blended number everyone quoted. The top five clients were running above 50%. Three accounts were at 9%, 6%, and one at negative 4%: roughly $14k in revenue against $14.6k in delivery cost, a client the agency was paying to keep. [composite figures, confirm with your actuals] Nobody had hidden that. It was just spread across four tools that didn't speak, so no one could see it until the join existed.

This is the 70% nobody talks about. The automation, the nightly pull, the join logic, was the easy 30%. The durable work was deciding what "client" means, picking which tool wins when two disagree, and naming who clears the unmatched queue on a Tuesday. The model was almost an afterthought. The structure was the answer.

If your stack has grown past ten tools and your most-trusted number still lives in a spreadsheet someone rebuilds by hand, you don't have a reporting problem. You have a join problem, and it's fixable in a month. The diagnostic version of this is exactly what I built OpScan to surface (it's mine, full disclosure).

The 70%.

If that was the 70% you have been missing, that is exactly what the newsletter is for.

~bi-weekly · no spam · unsubscribe anytime