Low quality leads: 6 signs you're paying for junk
Low quality leads hide behind a cheap CPL. We break down a hypothetical batch of 100 leads: six signs of junk, the math per campaign and what to fix first.
Low quality leads are requests that look like demand in the ad report and turn into nothing in sales: wrong numbers, bots, people from another region, people who don't remember filling in a form. They're dangerous because they make a campaign look cheap. CPL goes down, the dashboard is green, and the sales team quietly stops calling the new leads back.
My position: lead quality is a marketing problem, not a sales complaint. If a campaign brings junk, it's because we told the platform to bring cheap form submissions, and it did exactly that. The fix starts with counting what's in the batch.
A batch of 100 leads
Say Oliver runs a company that installs air conditioners in one city. Last month three campaigns brought 100 leads. The sales manager says “half of them are garbage,” marketing says “CPL is great.” Both are partly right. The numbers below are hypothetical.
Oliver asks the manager to do one thing: for each of the 100 leads, write one reason in a spreadsheet column. Here is the result.
| What the lead turned out to be | Count |
|---|---|
| Unreachable or wrong number | 14 |
| Spam or bot | 9 |
| Outside the service area | 8 |
| Wrong request (job seekers, other services) | 10 |
| Duplicate of an earlier lead | 5 |
| “I didn't leave any request” | 7 |
| Real, qualified request | 47 |
| Total | 100 |
Of the 47 qualified leads, 12 became paying customers. So the manager was close: 53 out of 100 leads were junk. Now the six signs, one by one.
Sign 1: contacts that don't work
Fourteen numbers didn't answer after three attempts or belonged to someone else. Some of this is normal: people make typos. But when a campaign has many more of these than others, the form is probably being filled in on autopilot. Check which campaign they cluster in.
Sign 2: spam and bot patterns
Names like “asdf,” the same text in the comment field, five submissions in two minutes at 3:40 a.m. Nine leads in Oliver's batch look like this. Simple bots tend to fill every field they find, including fields a human can't see, so a hidden “honeypot” field in the form is a cheap filter: if it's filled in, the submission is not from a person.
Sign 3: outside your area
Eight requests came from places Oliver doesn't serve. That's a targeting problem. Check location settings. In Google Ads, the default option is “Presence or interest”: it reaches people who are in your area and also people who have shown interest in it. For a local service, the “Presence” option, which shows ads to people located in your area, is often the better fit. Write the service area on the landing page too, next to the form.
Sign 4: the wrong request
Ten people wanted something else: a job as an installer, repair of a brand Oliver doesn't service, “just the price, I'm not buying now.” Usually this means the ad or the keywords are too broad. Review search terms and add negatives, and make the landing page clear about what you do and don't do.
Sign 5: duplicates
Five people submitted twice, once through the form and once through a call or messenger. Duplicates aren't junk in themselves, but they inflate the count and make CPL look better than it is. Merge them before you calculate anything.
Sign 6: “I didn't leave a request”
Seven people said they never filled in anything. This can happen with forms that the platform pre-fills from a profile: one tap and the request is sent. Meta's instant forms, for example, have a “Higher intent” type that, as Jon Loomer describes it, adds a review step so people confirm their details before submitting. Fewer leads, but people who know they left them.
Count it by campaign
The reasons are useful. The breakdown by campaign is where decisions come from. Oliver matches every lead to its campaign using UTM tags and adds spend.
| Campaign | Spend | Leads | CPL | Qualified | Per qualified | Customers | Per customer |
|---|---|---|---|---|---|---|---|
| Search: service + city | $1,400 | 35 | $40 | 26 | $54 | 8 | $175 |
| Search: broad match | $750 | 25 | $30 | 12 | $63 | 3 | $250 |
| Social: instant form | $600 | 40 | $15 | 9 | $67 | 1 | $600 |
| Total | $2,750 | 100 | $28 | 47 | $59 | 12 | $229 |
The formula is the same for every row:
cost per qualified lead = spend / qualified leads
cost per customer = spend / customersThe social campaign had the cheapest CPL, $15, and the most expensive customer, $600. Search with the service and the city in the query had the highest CPL and the cheapest customer. If Oliver had moved the budget by CPL, he would have moved it to the worst campaign.
Check on other numbers. Suppose the social campaign is twice as good as the table says: 2 customers instead of 1. That's still $300 per customer, worse than both search campaigns.
Common mistakes
- Judging campaigns by CPL alone. It counts every form equally, including bots and duplicates.
- Letting sales complain without data. “Half are garbage” doesn't help. A column with one reason per lead does.
- Optimizing the algorithm for any form submission. The platform will find the people most likely to submit a form, and that's not the same as people most likely to buy.
- Fixing everything at once. Change targeting, forms and bids in one week and you won't know what helped.
- Throwing out the whole channel. The social campaign may work with a different form type or audience. Test one change before you switch it off.
How this looks in Gauss
Gauss shows which campaign each conversion came from: goals by URL or event, the form_submit and contact_click goals that work automatically, and a breakdown by source and UTM campaign. That's the first half of the table above: leads and conversion rate per campaign. Form field values, numbers and addresses aren't collected, so the quality check itself happens in your CRM or spreadsheet.
Coming in the next version: gauss.attribution() will put the channel and UTM into hidden form fields, so each lead in the CRM carries its campaign. The offline events API will bring the deal outcome back into Gauss, and you'll see revenue and the cost of a customer per campaign, not only per lead.
What to do in the next hour
- Export the last 100 leads, or as many as you have for the past month.
- Add a column “reason” and fill it in with one of seven values: unreachable, spam, wrong area, wrong request, duplicate, didn't leave it, qualified.
- Add the campaign for each lead from UTM tags or your CRM.
- Count qualified leads and customers per campaign, then divide spend by each.
- Pick one fix for the worst campaign: location settings, negative keywords, a form type with a review step or a hidden honeypot field.
Related reading:
- CPC, CPM, CPA, CPL: an ad metrics glossary
- Speed to lead: why buyers leave while you call back
- How to fix a lead form that loses requests
The bottom line
A cheap lead is only cheap until you count what it turned into. The platform will give you exactly what you ask for, so ask for the thing you actually want: people who become customers, not people who tap a button.
One spreadsheet column with a reason per lead is enough to end the argument between sales and marketing. After that you're discussing numbers, not impressions.
Your task: take today's leads and write one reason next to each. Even ten leads will show you which campaign to look at first.
Want to see which channels actually bring you customers? Try Gauss →