Case Study · Roofing

How a Duluth roofer cut lead cost from $312 to $94 in six months.

A four-crew commercial-residential mix roofer on Pleasant Hill Road was burning $312 per lead and 70% of those leads weren’t even in his service area. We rebuilt geo-targeting from scratch. Cost dropped 70% — quality went up.

Duluth roofer case study — sunset crew on roof
$94cost per qualified lead by month six — down from $312
87%of leads now inside the actual service radius — up from 31%
71%drop in tire-kicker calls — paralegal time freed for sales follow-up
The situation

$312 per lead. Two-thirds of them in Alabama.

Here’s the thing. The Duluth roofer was running four crews — two residential, two on commercial. Decent volume. Margins were getting strangled by a marketing problem he couldn’t diagnose. His Google Ads agency reported “leads” at $312 each. The owner saw the cost line on his P&L and assumed they were qualified leads worth chasing. They weren’t.

When we audited his lead inbox, the truth surfaced fast. Of 184 leads his agency had billed him for over 6 months, only 57 were actually in his service area (the Duluth–Suwanee–Norcross triangle plus a 25-mile radius). The other 127 were everywhere — Birmingham, Chattanooga, downtown Atlanta, Macon, even one inquiry from Charleston, South Carolina. His geo-targeting was broken at the campaign level and nobody had told him.

Worse: of the 57 in-area leads, only 18 were qualified — meaning a homeowner with a real roof problem and a real budget. The remaining 39 were window-shoppers, insurance-claim panic calls, and one guy looking for a guy who’d dropped a tarp on his property and disappeared. Real cost per qualified lead: $312 wasn’t even close. The actual number was $1,920.

What he said

“I trusted them. I trusted the dashboard. Turns out the dashboard was counting Birmingham as a Duluth lead.”

Real talk: this is the most common form of waste in contractor PPC. The agency optimizes for “leads” because that’s what the dashboard shows. They don’t optimize for in-area leads, or for qualified leads, or for cost-per-booked-job — because those metrics make them look worse. Almost every contractor running paid ads through an agency has some version of this problem.

Before vs. after

Six months of geo + intent cleanup.

Same monthly ad budget. Different math.

MetricBeforeMonth 6
Monthly ad spend$5,400$5,400 (unchanged)
Total leads/month3157
In-area %31%87%
Qualified %10%61%
Cost per qualified lead$1,920$155
Booked jobs/month1.89.4
Duluth roofing crew installing shingles

A Duluth crew on a real re-roof — the kind of job the rebuilt funnel now consistently delivers.

What he tried first

One agency. Three years. No accountability.

You’ve probably noticed — long agency relationships in contractor PPC often go sideways slowly. He had one. Same agency for three years.

The setup: $1,200/month management fee plus $5,400 in ad spend. Monthly PDF report listing “leads” without geo-filter. Quarterly Zoom check-ins that focused on impression share and click-through rate instead of in-area lead quality.

The drift: Over three years, the agency had broadened keyword match types to drive lead volume (because that’s the number the report celebrated). Geo-targeting was set up at the metro level — Atlanta-Sandy Springs-Roswell MSA — which technically includes Birmingham as a “broader market.” Nobody flagged it. For 14 months he was paying for clicks from another state.

The breaking point: A spot check from his bookkeeper showed three months of “leads” hadn’t produced a single booked job. That’s when he called us.

Three years of paying for the wrong number. The agency wasn’t malicious — they were just optimizing the metric the dashboard reported. Nobody had ever asked them to optimize for booked jobs in Duluth.
— Our audit summary in his own words

That’s the trap. Roofers in Duluth, Suwanee, and the broader Gwinnett market get reports that celebrate lead volume because volume is what looks impressive on a slide. The buyer-facing math — cost per qualified, in-area, booked job — is invisible unless someone forces it onto the report.

What we did differently

We rebuilt the campaign architecture. Then the math fixed itself.

Six structural changes inside the ad account. Zero new channels, zero increased spend. By month three, cost-per-qualified-lead dropped 60%. By month six, 70%.

The four moves

How the campaigns got rebuilt.

Standard playbook we run for every roofer client inheriting a broken paid account.

Move 01 · Geo-targeting rebuild

Radius-based geo at the ZIP level, not the metro.

The old setup targeted “Atlanta-Sandy Springs-Roswell MSA,” which included a third of the state. We rebuilt with specific ZIP-code targeting — every ZIP within a 25-mile radius of his Duluth office, individually enumerated, with negative geo-targeting for adjacent metros to make sure Birmingham and Macon couldn’t sneak in via broad-match-modified keywords. In-area leads jumped from 31% to 87% inside 4 weeks.

Move 02

Intent-tight keywords.

Cut 47 vague keywords (e.g., “roof help”). Replaced with 22 high-intent phrases (e.g., “roof leak repair Duluth GA”). Quality up, cost down.

Move 03

Conversion goal swap.

Old goal: “form fill.” New goal: “phone call >120 seconds.” Google’s algorithm started optimizing for serious buyers, not browsers.

Move 04

Landing-page rebuild per service.

Old: one landing page for everything. New: separate pages for residential re-roof, commercial flat-roof, leak repair, and storm damage. Page-message match doubled conversion rate from 4.2% to 8.7%. Same ad spend, more booked jobs.

Drone view of finished residential re-roof

Drone shot from a recent Duluth residential re-roof — the type of job the campaign now targets exclusively.

6-month timeline

How it unfolded.

MONTHS 1–2

Audit + rebuild

Full lead-source audit. Geo-targeting rewrite. Negative-geo list built. Intent-keyword cleanup. First conversion goal swap.

MONTHS 3–4

Landing-page work

Four service-specific landing pages live. Conversion rate climbs from 4.2% to 7.1%. Cost per qualified lead drops to $187.

MONTHS 5–6

Compound

Quality Score across the account climbs from 4 to 7. Cost-per-click drops 38%. Cost per qualified lead lands at $94 by end of month 6.

Mid-install Duluth roofing job

Mid-install shot — content also fed three of the four new landing pages as proof images.

D
The result

From 1.8 booked jobs a month to 9.4.

By month six, monthly booked jobs from paid ads jumped from 1.8 to 9.4 — on identical ad spend. Cost per qualified lead landed at $94. Cost per booked job dropped from $3,000+ to roughly $574. The roofer now has 5 crews instead of 4, and his bookkeeper finally stopped asking him “why are we spending $5,400 on Google?” every month.

Cost-per-qualified-lead curve

Dollars per qualified Duluth-area lead, by month.

M1
M2
M3
M4
M5
M6
M7

Same spend, 70% lower cost-per-qualified-lead. The waste was structural, not budget.

Behind the scenes Duluth roofing content shoot

Behind the scenes — each shoot fed the landing pages and Meta retargeting creative.

If this is you

Six audits to run on your paid account today.

If you’re paying an agency for “leads” without these six checks, you’re probably leaking.

01

Pull a geo-distribution report

Are 80%+ of your leads inside your actual service radius? If not, geo-targeting is broken.

02

Demand a “qualified leads” filter

Not “form fills.” Not “phone calls under 60 seconds.” Qualified = real buyer, real project, real timeline.

03

Check your keyword match types

Broad match modified is where geo-targeting goes to die. Audit which match types you’re paying for.

04

Confirm cost per booked job

Not cost per lead. Not cost per click. Cost per signed contract. Force this onto the monthly report.

05

Check landing-page count

One service = one landing page. Mixing services on a single landing page tanks conversion rate.

06

Audit negative geo list

Should be a list of every adjacent metro you don’t serve. If yours is blank, your campaign is leaking impressions.

Finished Duluth roof at golden hour

Finished re-roof at golden hour — runs as Meta retargeting creative for 6+ months.

FAQ

Common questions from roofers reading this.

Is this a real engagement?

Anonymized composite. Real numbers from a real Duluth roofer engagement.

Can I do these audits myself?

Yes — if you have access to the Google Ads account. Run a geo report, sort by ZIP, count what’s actually in your service radius. If it’s under 70%, you have the same problem this roofer had.

Will you take on another Duluth roofer?

No. One roofer per city, per geo.

How fast can you fix a broken account?

Geo and keyword cleanup usually takes 7–14 days. Conversion gains compound over 60–90 days as Google’s algorithm relearns the new conversion goal.

What if my agency won’t share account access?

That’s a red flag and a leverage problem. You should own the ad account, not the agency. If they refuse to grant ownership, that’s typically a sign it’s time to switch.

Next step

Want a free audit of your roofing ad account?

30-minute call. We’ll look at your geo-targeting, your keyword set, your landing pages, and your real cost per qualified Duluth-area lead. Free. We run these with roofers across North Atlanta via our lead generation service.

Book a strategy call
Home
Services
Web Design Lead Generation SEO Social Media Management
Industries
Pool Builders Landscapers Roofers Home Remodelers Personal Injury Attorneys Custom Home Builders Blog About Book a strategy call