How Fewer Leads Made a Roofing Client More Money
The setup
A roofing contractor running ~$50K/month in Google Ads — about $600K annually. They were sophisticated about seasonal flighting and demand pacing, but consistently missing their funnel projections. Repair work was fine. The high-revenue full-replacement jobs almost never came through.
What they expected from $50K:
200 calls or form fills. 40% schedule rate → 80 consultations. 50% close rate → 40 signed jobs. A blended mix of repair and full installs that justified the spend.
What they actually got:
180 calls (CPC had drifted up). 30% schedule rate → 54 consultations (relevancy was dropping). 33% close rate → 18 signed jobs. 16 of 18 were repair jobs. The full installs — the jobs that actually justified the $50K spend — almost never appeared.
They were missing their numbers at every stage. When they came to us, their first question was the obvious one: how do we lower the CPC?
The diagnosis
Lower CPC was the wrong question. The real problem was that every click looked the same to Google’s algorithm. Someone searching “roof leak repair” and someone searching “full roof replacement quote” were both being optimized as undifferentiated conversions. The bidding strategy was finding the cheapest path to a phone call, not the most valuable one.
The result: cheaper traffic, sure. But also lower-intent traffic. And lower-intent traffic skewed hard toward small repair jobs — the low end of their revenue range. The algorithm was optimizing them straight into a margin trap.
What we did
We didn’t lower the CPC. We changed what the algorithm was optimizing for.
Step one: Asked the client to start logging an estimated job size on every lead as it came in — based on signals they already knew how to read (roof age cues from the call, materials mentioned, square footage indicators, urgency level).
Step two: Built an offline conversion tracking goal called Roof Estimate — OCT that fed those job-size estimates back to Google Ads. Not just “a lead happened” — but what the lead was worth.
Step three: Once we had enough data, we shifted bid strategy from optimizing for call volume to optimizing for estimated value.
The platform now had the missing context: not all clicks are equal, here’s what “good” looks like, go find more of that.
The outcome
- Phone calls dropped from 180 → 120 (−33%)
- We reduced budget from $50K → $35K (the goal wasn’t to spend more, but to be more effective with the budget)
- CPC went up (the algorithm was now competing aggressively for high-intent searches)
- Cost per lead went up
- Schedule rate climbed from 30% → 40% (back to projected)
- Close rate tripled at the qualified end of the funnel
- Closed jobs jumped from 18 → 30 (+67%)
- Job mix shifted from ~10% full installs to the projected blend
- Cost per signed job: $2,778 → $1,167 — a 58% reduction
The dashboard told a worse story. The P&L told the real one.
The takeaway
CPC isn’t a cost to minimize. It’s a signal of how aggressively the algorithm is competing for the customers you actually want. Cheap clicks usually mean you’re winning races nobody good is running.
If your sales team is closing fewer deals despite stable lead volume, the answer is rarely “more leads.” It’s almost always “different leads.” Teaching the platform what “different” means requires giving it data it can’t see on its own.