Answers

How do I track profit per job across two repair shop locations?

Define the number once, fix the three places the data lies, then compare the locations on identical job categories. The definition: parts sold minus actual invoice cost, plus labor sold minus the cost of the hours actually clocked, minus sublet and discounts. The three lies: parts cost captured at the estimate rather than at the vendor invoice, labor billed in book hours with no clocked hours beside it, and comebacks that open a fresh ticket so the original job keeps its margin. All three get fixed in the system you already pay for, where a monthly export and one pivot table answer most of the question for nothing. Buy a reporting layer when two databases and a faster cadence make that export the bottleneck.

§What "profit per job" has to mean before you can measure it

A repair order is a visit. A job is a line on it: front brakes, a diagnostic, an oil service. Gross profit per repair order is easy to produce and close to useless: one ticket can hold a strong brake job and a diagnostic that lost money, and the average hides both. Measure at the line instead — what it sold, minus the parts it consumed at invoice cost, minus the hours it consumed at loaded cost, minus sublet and discount. Loaded cost is the technician's pay for those hours plus payroll tax and benefits, not shop overhead, which belongs in a different report. Two shops using two definitions cannot be compared, so write the formula down once and make both use it.

§Parts cost gets captured at the estimate, not at the invoice

Capturing parts cost at the estimate rather than at the vendor invoice is where per-job margin usually goes wrong first. The estimate carries a catalog or last-known cost. The vendor invoice carries what you actually paid: billed price, freight, a core charge, a price change since the last order, a return nobody credited. Margin computed from estimate cost is a forecast wearing a report's clothing, and it flatters you. The fix is process rather than purchase — no repair order closes until its parts lines are reconciled against the vendor invoice. A parts matrix is a pricing rule, never a cost. A core you never returned belongs to the job that consumed it. Reconciling a month of invoices at month end is how shops end up guessing; make it daily and give it an owner.

§Labor sold and labor spent are two different numbers

Book hours are what you sold. Clocked hours are what it cost. A per-job profit figure built only from hours sold is a price report, not a profit report. The cost side needs two things many shops lack: technicians clocking on and off individual job lines rather than onto the shop day, and a loaded hourly cost per technician. Once both exist, effective labor rate per job, per technician and per location falls out of the same data, along with the categories where the labor guide and your bay disagree. A job that sells two hours and takes three and a half is not automatically a technician problem — it can be the guide, the estimate or the tooling — and one instance proves nothing. You need a run of them.

§Comebacks eat margin without appearing in any report

A comeback normally opens as a new repair order at no charge. The original job keeps the profit it recorded, the redo lands in a bucket nobody attributes, and both tickets look fine on their own. The fix is a link: a field on the redo pointing at the original repair order number, and a rule that the redo's parts cost and clocked hours come out of the original job's profit. If your shop system has no comeback flag, a naming convention in the ticket title — CB 12345 — is enough to reconstruct the link in an export. This matters most across two locations, because comeback rate is the truest quality difference between them and it is invisible in any report built from what was invoiced.

§What makes two locations hard is vocabulary, not arithmetic

Two shops running the same software drift apart as soon as two different people are entering tickets. One calls a job "Front brakes", the other "BRK-FR-PAD-ROT". Labor rates differ, parts matrices differ, vendors and net costs differ, and technician numbers collide because each database assigned them independently. Some shop systems keep each location in its own instance, so there is no shared key to join on. The work before any comparison is normalization: one canonical category list with both locations' names mapped onto it, labor rate recorded on each line rather than assumed, discounts treated as a line-level cost, and repair order and technician identifiers prefixed by location. Do that and a gap between the two means something. Skip it and you are comparing spelling.

§What the reports you already own will do for free

Exhaust the shop system you already pay for before you buy a reporting product. Tekmetric, Shopmonkey, AutoLeap and Mitchell 1 all record parts cost and labor at the line, and each has some form of closed repair order export — check what yours does, since it can depend on tier and version. Once a month, export both locations, stack them in one sheet with a location column, and pivot job profit by category, by technician and by advisor. That afternoon tells you which categories carry the shop, which are sold below what they cost to perform, and where the two locations differ. Ask your vendor what multi-shop reporting it already sells, too — some include it in a higher tier, and included beats bought. If a monthly answer is fast enough to act on, stop here and keep your money. You need parts reconciliation discipline and an hour with a spreadsheet; a reporting product bought before that discipline exists produces the same wrong number, faster and with more confidence.

§The data that has to exist for the number to be trustworthy

Per job line, in both locations: repair order and location identifiers; a job line identifier and a canonical category; parts lines with vendor, invoice number, actual invoice cost and a core flag; labor lines with hours sold, hours clocked, technician identifier and that technician's loaded hourly cost; sublet cost; discounts recorded at the line, not the ticket; a comeback link; and both close and posting dates, since a parts credit landing next month moves margin between periods. The failure modes map one to one. No invoice cost and margin is a forecast. No clocked hours and labor cost is an assumption. No line-level discount and the advisor who gives away the most looks the most profitable. No comeback link and the work you keep redoing looks like your best work.

§When a reporting layer is worth paying for

When the export is the bottleneck rather than the data underneath it: two databases that will not join, a cadence too slow to correct anything, or a question — profit per mechanic, per advisor, per category, this week — that somebody rebuilds by hand each time. Then a layer that reads closed repair orders from both locations, maps categories onto one list and computes one definition earns its cost. That is part of what Otto does for independent shops, on top of the shop system rather than replacing it. Pricing is quoted per engagement, so get in touch if that is your stage. The sequence matters more than the tool: reconcile parts to invoices, clock labor to job lines, link comebacks, agree one category list. A reporting layer inherits the quality of whatever sits beneath it.

Last updated 25 July 2026.