In January 2025 I started tracking every job. Materials cost. Hours billed. Hours actually worked. Drive time. Materials runs. Callbacks. Everything.

I expected to find some surprises. I did not expect to find that almost half the job types I was doing were either barely breakeven or actively losing money.

Twelve months and 187 jobs later, here is what the data said.

The job that triggered the spreadsheet

It was a kitchen rewire in Newtown. A repeat customer who had used me twice before. Job total: $3,790. Materials I quoted: $720. Labor I billed: 16 hours at the rate I was running.

It felt like a great job. Customer was thrilled. Got paid in full inside a week. Drove home that Friday feeling like I had a good week.

Then I sat down on Sunday and actually did the math, because something was nagging at me.

Real hours, including drive time and three materials runs: 22, not 16. Actual materials, with the two replacement items I had to swap: $890, not $720. Callback the next week for a flickering switch: another 90 minutes round trip, parts and time.

By the time I allocated overhead at $32 per billed hour, the job had cleared $410 in actual profit. On a $3,790 job. That is a 10.8 percent net margin on something I had been telling myself was a winner.

That weekend I built the spreadsheet.

What I tracked, and why

The spreadsheet was simple. Every job got a row. Every row got these columns:

  • Job number and date
  • Customer name and zip code (for drive time bucketing)
  • Job type (panel swap, service call, troubleshoot, rewire, etc.)
  • Total billed
  • Materials cost (actual, not estimated)
  • Billed labor hours
  • Actual labor hours (including drive, materials runs, callbacks)
  • Overhead allocation (hours actual times my overhead per hour)
  • Net profit dollars
  • Net profit per actual hour

That last column was the one that mattered most. Profit dollars hide a lot of sins. Profit per actual hour shows you, brutally, which jobs are actually paying you what your time is worth.

The most profitable job type

Surprise winner: service calls.

I had always thought of service calls as the small change of the business, jobs you do to fill gaps between bigger work. Turns out service calls were paying me the most per actual hour of any category, by a wide margin.

Average service call: $385 billed, 1.5 actual hours including travel, $190 net profit, $127 per actual hour.

Why they win: small material cost, almost no project management overhead, no waiting on permits or other trades, fast in and out. The drive time hurts on individual jobs but bunching them in geographic clusters (the data showed me which zip codes paid for themselves) made the math better than I expected.

The least profitable job type

Surprise loser: small renovation work for general contractors.

I had three GCs feeding me steady electrical work on remodels. It felt like good business. Steady volume. Less marketing burden. I liked the GCs personally.

The data was bleak. Net profit per actual hour for those jobs averaged $48. My target was $115. I was working for less than half my real rate on close to 30 percent of my volume.

The reasons came out when I dug in: I was on the GC's schedule, not mine, which meant a lot of wasted trips when the job was not ready. Their materials lists were always incomplete, which meant 2 to 3 supply house runs per job that I was eating. Their customers were not my customers, so no referrals or repeat work came out of it. And the GCs had negotiated me down on rate at the start, so I was billing 15 to 20 percent below my normal pricing.

The hidden cost that destroyed three categories

Drive time. The killer.

I had been pricing as if a one-hour job was a one-hour job. The data showed me that a one-hour job 35 minutes away is actually a 2 hour 10 minute job once you count round-trip drive time. If I am billing $240 for the hour of work and burning 70 minutes of unpaid travel, my actual hourly rate on that job is closer to $111.

Three categories got hammered by this:

  1. Small jobs outside my home zip code cluster. Below about $300 in billed labor, drive time ate the entire profit.
  2. Estimates that did not close. Every unconverted estimate was 60 to 90 minutes of unpaid time. I had been ignoring this. The data showed I needed a close rate above 65 percent or my estimate process was a net loss.
  3. Multi-visit jobs. Anything requiring three or more visits had its actual labor hours quietly double from what I had quoted, because every visit included drive time and a materials check.

What I changed because of the data

Six concrete changes, all driven by what the spreadsheet showed me:

1. Minimum job size for jobs outside my home zip code cluster: $400 billed labor. Below that, I quote a minimum trip charge or decline the work.

2. Trip charge for first-time customers more than 20 minutes away: $95, applied to the bill if work proceeds. Killed the freebie windshield-time estimates.

3. Service call cluster days: Tuesdays and Thursdays are now booked tight in geographic clusters. Other days are reserved for larger projects. Average drive time per service call dropped 40 percent.

4. GC pricing reset: I went to two of the three GCs and raised my rate 18 percent. One agreed. One pushed back and I stopped working for them. My total revenue dropped 8 percent and my profit went up.

5. Materials markup audit: I had been marking materials at 25 percent. I moved to 40 percent on standard items and 60 percent on specialty items. Customers noticed exactly zero of those bills.

6. Callback tracking: Every callback got its own row. Within three months I saw a pattern, one specific brand of switch was responsible for 60 percent of my warranty returns. I stopped installing them.

The two customers I stopped working for

The hardest call was firing one of the GCs. He was a friend. He sent me consistent work. But the data was unambiguous: I was working for him at $44 per actual hour. He was the lowest-paying customer in my database.

I sent him a one-paragraph email. Said I was raising my rate effective in 60 days. Gave him the new number. He pushed back. I held firm. We stopped working together. He told two other GCs in the area about it.

Three months later I had replaced his volume with direct residential work paying twice the rate. I would not have made that call without 12 months of data sitting in front of me.

The other one was a residential customer who had become a project. Multiple small jobs over 18 months, always demanding immediate response, always negotiating on price after the work was done, four callbacks for stuff that was not warranty. The spreadsheet said she was costing me money. I stopped returning her calls.

What I would tell a new contractor

You cannot price intelligently without knowing what your jobs actually cost.

You cannot fire bad customers if you do not know who they are.

You cannot tell your spouse why you are working 60-hour weeks and still tight on cash without a spreadsheet that shows where the money is leaking.

The whole exercise takes 10 minutes a day. Open the spreadsheet at the end of each work day, fill in the row for whatever jobs you touched. Once a month, look at the totals by category. Once a quarter, decide what to change.

Twelve months of that data turned a business I thought was healthy into a business that actually was.

Frequently Asked Questions

How do I allocate overhead to a single job?
Divide your annual overhead by your annual billable hours. That gives you an overhead cost per hour. Multiply by the hours actually spent on the job. For a solo contractor with $35,000 annual overhead and 1,100 billable hours, that is about $32 per billed hour of overhead allocation.
Should I include my own labor at full rate or take-home rate?
For job costing, use your full loaded labor rate (what you bill out at), not your take-home pay. The point of job costing is to see if the job paid for everything: overhead, your time at market value, materials, and profit. If you only use take-home, you hide the real cost of your hours and every job looks more profitable than it is.
What's the minimum job size worth tracking?
Track everything for at least three months. The small jobs are exactly the ones most likely to be unprofitable, and you cannot find them without data. After three months of complete tracking, you can decide whether to stop tracking jobs under a certain size. My personal cutoff ended up being $300 because below that, drive time eats everything regardless.
How long until I have enough data to see patterns?
Six months gives you trends. Twelve months gives you confidence. Within 90 days you can usually spot your most and least profitable job categories. After a year you can make hiring and pricing decisions with real data instead of gut feel.
Do I need accounting software to do this?
No. A spreadsheet handles job costing better than QuickBooks for a solo or small operation. The accounting software is built for taxes and financial statements, not job-by-job analysis. The Job Profitability Tracker I built is an Excel file with built-in formulas for overhead allocation, labor at loaded rate, and material markup. Same engine, different output.