How to Track Gross Margin by Job Without a Bookkeeper
Most contractors know their total revenue and their total expenses. What they do not know is which jobs made money and which ones quietly bled cash. Without per-job margin tracking, you cannot identify your most profitable work type, your most reliable clients, or the subcontractors whose bids consistently underperform. You are running a business with company-wide averages instead of job-level intelligence.
Why Company-Wide Margins Are Not Enough
A contractor running $1.2M in annual revenue with a 28% gross margin sounds healthy. But that 28% average might be masking a flooring division running at 41% margin and a framing division running at 14%. If you knew that, you would bid more aggressively on flooring work and either fix the framing operation or stop taking those jobs. The company-wide average hides the information you need to make that decision.
The same principle applies at the job level. A $180,000 renovation that came in at 22% margin tells you something important — but only if you can compare it to the $95,000 renovation that came in at 39% margin and ask why. Was it the client? The location? The subcontractor you used for tile? The material supplier? Without per-job data, you cannot answer those questions and you cannot improve.
The Three Inputs You Need for Per-Job Margin Tracking
Revenue by job is usually the easiest to track. Your invoices or draw requests have job addresses on them. When the payment arrives in your bank account, it needs to be tagged to the job that generated it. The challenge is that bank deposit descriptions are often vague — "ACH CREDIT CONTRACTOR PLUS SETTLEMENT" tells you nothing about which job it came from without additional context.
Direct costs by job are harder. Every Home Depot run, every lumber delivery, every subcontractor payment needs to be attributed to a specific job. The problem is that most contractors make purchases that span multiple jobs — a single trip to the supply house might include materials for three different projects. Without a system for splitting or tagging those purchases, all direct costs get lumped together.
Labor by job is the hardest. If you have W-2 employees, their time needs to be allocated across jobs. If you use 1099 subcontractors paid per job, the allocation is cleaner — each check corresponds to a specific project. Most small contractors use the sub model precisely because it makes job costing easier.
The 80/20 rule for job costing: You do not need perfect allocation to get useful data. If you can correctly attribute 80% of your direct costs to specific jobs, the margin numbers will be accurate enough to make better decisions. Start with the large purchases — material deliveries, sub payments, equipment rentals — and let the small miscellaneous costs flow to overhead.
Setting Up Vendor Rules for Automatic Categorization
The most time-efficient approach to job costing is to create vendor rules that automatically categorize recurring transactions. Home Depot, Lowes, Menards, and Floor & Decor are always materials. Your regular subs — the framing crew, the plumber, the electrician — are always labor. Your insurance carrier is always overhead. Once these rules are in place, the categorization happens automatically on every future transaction from those vendors.
The job attribution step is separate from the category step. Categorization tells you what type of cost it is. Job attribution tells you which project it belongs to. For subcontractor payments, the check memo or bank description often contains the job address or the sub's name, which can be matched to a job record using fuzzy matching. For material purchases, the match is less reliable — a Home Depot receipt does not know which job the lumber was for.
The Job Alias System
One of the most practical solutions to the job matching problem is a job alias system. When you create a job record for "McArthur Renovation — 1210 17th Street," you also add aliases: "17th St," "McArthur," "1210." Any bank transaction description containing those strings gets flagged as a potential match for that job. An admin reviews the flagged transactions and confirms or reassigns the match. Once confirmed, the rule is remembered — the next transaction from the same vendor with the same description is automatically assigned to the same job.
This approach handles the real-world messiness of contractor financial data. A receipt might say "17th St." A sub's invoice might say "McArthur job." A material delivery might reference the address. The alias system catches all of them without requiring perfect data entry.
Frequently Asked Questions
What is a good gross margin percentage for a general contractor?+
Most general contractors target 20% to 35% gross margin per job. Residential remodeling typically runs 25% to 40%, while commercial work often runs 15% to 25% due to competitive bidding. If your gross margin is below 15%, your overhead and labor costs are likely consuming your profit.
What is the difference between gross margin and net profit for a contractor?+
Gross margin is revenue minus direct job costs (materials, labor, subcontractors). Net profit is gross margin minus overhead (insurance, office, equipment, owner salary). A job can have a healthy 30% gross margin but still produce low net profit if overhead is high.
How do I allocate overhead costs to individual jobs?+
The most common method is to allocate overhead as a percentage of direct labor hours or direct job cost. If your annual overhead is $120,000 and you bill 4,000 labor hours per year, your overhead rate is $30 per labor hour. Add this to your job cost estimate before calculating your margin.
See your margin by job this week
CashFlowSmart tracks gross margin per job using real bank transactions, vendor rules, and the job alias system. No bookkeeper required. Founding cohort: $97/month.
Claim your founding member spot →