DEV Community

forlazin-debug
forlazin-debug

Posted on Edited on

97.3% of keyword matches are junk: lessons from 542,795 Telegram messages

We built a service that watches open Telegram chats and surfaces people who are actively looking
to buy something. After processing 542,795 keyword-matched messages in production, here is the
number that defines the whole problem:

97.3% of them were junk. Only 14,774 were real purchase requests.

That is roughly 36 useless messages per 1 real lead. Last 30 days alone: 7,945 real requests
against 363,508 rejected.

If you are thinking about building keyword monitoring for lead generation, this post is the thing
I wish someone had told me before we started.

Why keyword matching fails so badly

The naive approach is obvious: pick keywords, match messages, get leads. It works for about a week.

The noise is not random garbage. It is specifically the stuff that looks exactly like a lead:

  • Competitor ads. They use the same words a buyer would. "Ищу клининг" (looking for cleaning) and a cleaning company's ad both contain "клининг".
  • Job postings. "Требуется мастер" (master needed) matches every keyword a repair service has.
  • Reposts and cross-promotion. Same text, many chats, multiplied by the number of chats you watch.
  • Discussion without intent. People talk about renovation constantly. Almost none of them are hiring a contractor right now.

A keyword is a subject signal. It carries no intent signal at all. "ищу риелтора"
(looking for a realtor) and "ищу приключений" (looking for adventure) share a token and mean
nothing alike.

The architecture that actually works

Telegram open chats
        │
        ▼
 [1] keyword / stop-word prefilter   ← cheap, high recall, ~97% false positives
        │
        ▼
 [2] LLM intent classifier           ← "is this a real request to buy?"
        │
        ├─ rejected → log
        └─ passed   → lead (hot / warm / cold) + draft reply
Enter fullscreen mode Exit fullscreen mode

Stage 1 must stay broad. Every attempt we made to encode intent into the keyword list itself
made recall collapse: you start losing real requests because people phrase them in ways you did
not predict. Keep it dumb and permissive, let stage 2 do the thinking.

Stage 2 is where the product lives. Our classifier returns three classes:

  • hot — explicit, ready now: "ищу клининг после ремонта, когда можете подъехать?"
  • warm — asking for advice, no deadline or budget yet
  • cold — topic-adjacent, low intent

Noise rate varies wildly by niche

This surprised us. Real data from client accounts, 60-day window, anonymised to niche + region:

Niche Region Chats Leads Days Hot Noise
Price monitoring SaaS Russia 448 402 40 65 67.3%
White imports from China Russia 482 1,174 34 525 80.0%
Product certification Russia 165 751 57 262 87.3%
Apartment renovation Moscow reg. 49 161 11 44 88.5%
Debt relief lawyers Moscow reg. 811 174 24 56 92.0%
Marketplace fulfilment Russia 190 415 39 98 93.1%
Realtor Blagoveshchensk 189 166 46 33 95.4%
Cleaning company Moscow 272 201 19 159 97.3%

The pattern: the more common the vocabulary, the worse the noise. "Уборка" (cleaning) appears
in chats constantly and almost never means "I want to order cleaning". Meanwhile a narrow B2B term
like "репрайсер" (repricer) is almost self-filtering.

Practical consequence: niche determines your infrastructure cost. A cleaning client needs ~36x more
classifier calls per delivered lead than a narrow B2B client.

A measurement trap that will fool you

When a new account connects, the system scans chat history. That first day produces a huge
batch of leads at once.

In one account, 417 of 1,174 leads arrived on day one. If you compute "leads per day" naively,
you report 34.5/day when the real steady-state is much lower. Two of our accounts had all their
leads on a single day — pure backfill, zero ongoing flow.

Always exclude the first active day before computing rate, and drop accounts with a single
active day entirely. We nearly published inflated numbers because of this.

Stop-words carry more weight than keywords

Generic set that applies to nearly any niche (Russian, but the categories translate):

# hiring, not buying
вакансия, ищем сотрудника, требуется, резюме, зарплата, оклад, на работу

# someone selling, not buying
предлагаю услуги, оказываю услуги, наша компания, обращайтесь, прайс,
портфолио, скидка, акция, подписывайтесь, реклама, промокод

# channel noise
переслано, репост, кто знает чат, админ, правила группы
Enter fullscreen mode Exit fullscreen mode

Niche-specific additions matter more. For cleaning: уборщица, пылесос купить,
генеральная уборка сама.

Speed beats price

Lead temperature decays fast. In a 500-flat residential chat, a cleaning request collects several
competing replies within the hour. The first clear answer with a price and a time slot wins far
more often than the cheapest one sent next morning.

This changes the product requirement: it is not enough to find the lead, you have to deliver it
while it is still warm, and ideally hand over a draft reply.


Full dataset and per-niche breakdown:
mpleads.ru/kejsy-po-nisham

The service itself is Leadolovets — commercial, Russian market, 5-day free
trial. The documentation and stop-word recipes are public on
GitHub.

Happy to answer questions about the classifier setup in the comments.

Top comments (0)