CRM Solid logo
GUIDE18 min read

Bulk messaging best practices: send at scale, stay safe

The rate-limit math we use in production, multi-account rotation patterns, the 14-day warm-up curve, spintax variation, and the exact flood-wait response policy that keeps high-volume campaigns alive for months.

14-day free trial · No credit card required · Cancel anytime

What you will learn

Four production-grade skills by the end of this guide

Rate-limit math

How to compute realistic daily ceilings and avoid the silent trust-score downgrade.

Multi-account rotation

Round-robin queues, per-account state, and how to scale linearly with N senders.

Spintax variation

Writing alternations that defeat content fingerprinting without sounding robotic.

Warm-up curve

The 14-day ramp every new sender goes through before it touches a real campaign.

What you will need

Bulk messaging at scale is a multi-account discipline. Solo sender, solo template, no warm-up: that is the path to a banned account.

  • A CRM Solid workspace (free trial works) with at least 2 connected Telegram sender accounts.
  • Sender accounts that are at least 30 days old and have completed the 14-day warm-up curve.
  • A clean recipient list (CSV or a saved CRM segment), with duplicates removed and opt-outs scrubbed.
  • A template library of at least 5 variants per intent: opener, qualifier, follow-up, exit.
  • A monitoring dashboard for outreach health (built into CRM Solid; equivalent works elsewhere).
  • Patience to launch a 50-message pilot before scaling to full daily ceiling.

Before you read on

Bulk messaging is gated by the recipient's consent or your documented lawful basis (GDPR, KVKK, CAN-SPAM, CASL). This guide teaches the operational mechanics of sending at scale safely. Compliance is your responsibility; never assume a purchased list is opt-in, and never send to anyone who has asked you to stop.

Bulk messaging is a probability game played against platform anti-abuse systems. The platforms (Telegram, X, WhatsApp) maintain a hidden per-account trust score updated in near-real-time based on send volume, send timing, message similarity, recipient reports, recipient blocks, and a dozen other signals. Drop below a hidden threshold and the account is restricted, suspended, or banned.

The job of this guide is to give you the operating ranges that keep trust scores stable. Stay inside the ranges, run for years. Cross them, and you lose the account.

Step 1: Calculate your realistic daily throughput

The formula:

daily_safe_volume = warm_accounts × per_account_daily_ceiling × (1 - opt_out_buffer)

# Worked example
warm_accounts            = 5
per_account_daily_ceiling = 50   # for accounts 30+ days old, post-warmup
opt_out_buffer            = 0.10 # reserve 10% capacity for replies, opt-outs

daily_safe_volume = 5 × 50 × (1 - 0.10) = 225 outbound DMs/day
weekly_volume     = 225 × 7  = 1,575
monthly_volume    = 225 × 30 = 6,750

That is the realistic envelope. If your campaign plan calls for 10,000 DMs in a week from a 5-account fleet, the math says no; you will either burn accounts or take three weeks. Resize the campaign or add accounts before launch.

The per-account daily ceiling table:

  • Account age 0-7 days: 5/day max.
  • Account age 8-14 days: 15/day max.
  • Account age 15-30 days: 30/day max.
  • Account age 30+ days, warmed up: 50/day standard.
  • Account age 90+ days, strong history: up to 100/day for short bursts.

These are not Telegram's published limits (Telegram does not publish any). They are the empirical safe envelopes we have observed across thousands of production accounts over multiple years. Stay below them and your trust score is stable. Push them and you start collecting flood-waits.

Step 2: Set up the rate limiter per account

CRM Solid's rate limiter is per-account, with three knobs and an optional schedule:

  • per_hour: maximum sends per rolling 60-minute window.
  • per_day: maximum sends per UTC calendar day.
  • min_interval_seconds: minimum gap between two consecutive sends from the same account.
  • business_hours_only: restrict sends to a configured local timezone's 9 AM - 7 PM window.

The recommended defaults by account age:

Account age    per_hour  per_day  min_interval  business_hours
0-7 days        2         5        60s           on
8-14 days       5         15       45s           on
15-30 days      10        30       20s           on
30+ days        20        50       10s           on  (recommended)
30+ days, busy  40        100      8s            off (advanced)

The "advanced" row is for established accounts running a high-volume support inbox in addition to outbound; they have organic traffic that justifies higher rates. Most accounts should stay on the 30+ days standard row.

Step 3: Build spintax variation into every template

Platforms run content fingerprinting across messages from the same account and across multiple accounts on the same network. If 200 DMs in 48 hours all start with the same eight words, the content fingerprint matches and your trust scores drop together.

Spintax defeats this signal by varying the message body deterministically per send. The syntax is {option1|option2|option3}. CRM Solid resolves it at send time so every recipient receives one randomly-picked variant.

# Weak spintax (do not do this)
{Hi|Hey|Hello} {there|friend|buddy}!

# Strong spintax (every variant reads naturally)
{Hi {first_name}|Hey {first_name}|Hello from London, quick one for {first_name}}
- {noticed your post|saw your comment|caught your latest tweet} about
{topic} {today|earlier|yesterday}.

We help {persona} solve that without
{spending six months in spreadsheets|paying enterprise prices|building it in-house}.

Quick check - are you {actively looking|just researching|on the side}
for that right now?

The four rules of strong spintax:

  1. Each variant is a complete natural sentence on its own. Read every variant out loud. If any sounds broken, rewrite.
  2. Vary structure, not just adjectives. {great|awesome|amazing} is shallow; varying the sentence shape ("Quick one, vs Hi {first_name}, vs Hey,") creates real lexical diversity.
  3. 4-8 variants per spintax block. Below 4, the alternation collapses to noticeable repetition under load. Above 8, you struggle to keep them all coherent.
  4. Combine spintax with merge variables. {first_name}, {company}, {custom_field_1}: these are the strongest variation source because they are unique per recipient.

Step 4: Distribute across multiple accounts with round-robin

One account at 50/day caps your campaign at 50/day. Two accounts at 50/day each give you 100/day. The math is linear up to the point where multi-account behavior itself becomes a signal.

In CRM Solid, Sequences > New > Audience > Distribution offers four modes:

  • Round-robin: recipients dealt one-by-one to accounts in rotation. Even load, simple to reason about.
  • Weighted: recipients dealt proportionally to each account's configured weight. Useful when one account is older/stronger than the others.
  • Geographic: recipients in EU go to EU-based senders, US recipients to US senders, etc. Higher relevance, fewer obvious-bot signals.
  • Owner-bound: recipients with an assigned owner go to that owner's sender account. Best for warm follow-ups, terrible for cold (creates a hot-spot account).

For cold outreach with 5 senders of equal age, use round-robin. For mixed-age fleet, use weighted with weights proportional to account age (e.g., 90-day account = weight 3, 30-day account = weight 1).

Step 5: Warm up every new account before adding it

A fresh account dropped into a campaign at 50/day from day one is a banned account by day 4. The Telegram (and X, and WhatsApp) anti-abuse systems specifically watch for "young account, high cold volume" as the strongest possible spam signal.

The 14-day warm-up curve:

Day    Daily target  Pattern                              Notes
1      5             Send to your own personal contacts   Pure warm
2      5             Reply to inbound, send 2 outbound    Bias to inbound
3      8             5 warm + 3 opted-in subscribers      First outbound to non-personal
4      10            7 opted-in, 3 warm                   Light-cold
5      12            10 opted-in, 2 cold                  Tiny cold test
6      14            12 opted-in, 2 cold                  Same, slightly more
7      16            12 opted-in, 4 cold                  Cold creeping up
8      20            15 opted-in, 5 cold                  Phase 2 starts
9      24            18 opted-in, 6 cold
10     28            20 opted-in, 8 cold
11     32            22 opted-in, 10 cold
12     36            22 opted-in, 14 cold
13     42            22 opted-in, 20 cold
14     50            22 opted-in, 28 cold                 Full ceiling reached

CRM Solid has a warm-up mode toggle on every account. When enabled, it caps sends to the day-N target on the curve, automatically incrementing daily. You set the start date, it manages the rest. Disable it after day 14, and the account graduates to standard rate limits.

Meanwhile, the account must look human:

  • Profile photo set (use a real photo, not a stock image).
  • One-line bio set in your operating language.
  • At least 10 contacts in the address book.
  • At least 5 organic 2-way conversations in the message history.
  • Visible activity status (not "Last seen long time ago").

Step 6: Configure your flood-wait response policy

A flood-wait is Telegram's soft rate-limit error. The response includes a duration in seconds:FLOOD_WAIT_42 means "wait 42 seconds before retrying." CRM Solid handles this automatically, but you should configure the response policy.

Recommended settings in Settings > Outreach health:

  • On first FLOOD_WAIT: pause account for X + 30% jitter, mark "recovering."
  • On second within 6 hours: pause for X × 2 + 30% jitter, reduce per-hour cap by 50% for 24 hours.
  • On third within 24 hours: stop the account for the day, send alert email to operator, suggest reviewing templates and segment.
  • On any account-level suspension (PEER_FLOOD): pause for at least 24 hours, alert operator, do not retry automatically.
# Sample worker log
[14:02:18] Account #3 (alice_main): SENT to @user_4521 (#1247 of 250)
[14:02:31] Account #3: FLOOD_WAIT_55 received
[14:02:31] Account #3: pausing 71s (55 + 30% jitter)
[14:02:31] Worker: queued message #1248 re-dispatched to Account #1
[14:03:42] Account #3: resumed, per-hour cap reduced 50% for 24h
[14:03:42] Account #3: SENT to @user_2199 (#1248 of 250)

Step 7: Launch a pilot batch and watch metrics

Never go from "draft" to "full campaign" in one click. Run a 50-message pilot first.

  1. Set the campaign daily cap to 50. Launch.
  2. Watch the outreach health dashboard for 60 minutes.
  3. Healthy targets:
    • Reply rate ≥ 8%
    • Bounce/error rate ≤ 2%
    • Zero flood-waits
    • Zero blocks (someone blocked your sender)
    • Opt-out rate ≤ 1%
  4. If any of these are off, pause. Do not raise the cap. Investigate.

Step 8: Scale safely

After a clean pilot, raise the cap to your calculated daily safe volume (Step 1). Then watch the same metrics daily for the first week, weekly thereafter.

The early-warning signals to act on:

  • Reply rate trending down 1%/week: template fatigue. Rotate in a fresh variant set.
  • Block rate rising: audience targeting is too broad. Tighten the segment.
  • Flood-wait spike on a single account: that account is hitting a per-window cap. Reduce its share of the rotation, give it a day off, then re-introduce at half load.
  • Multiple accounts hit flood-wait same day: campaign-level signal. Telegram is throttling your whole fleet. Pause everything for 24 hours, then resume at 50% throughput.

Bulk messaging done right looks boring from outside: the same campaign quietly sends 225 personalized DMs every weekday for months, producing 20-30 replies and 5-8 demos every day, with zero ban events. That is the goal.

CRM Solid vs DIY scripts vs free bots

The differences become operational fast; what is automatic in CRM Solid is hand-rolled tooling in everything else.

CapabilityCRM SolidRecommendedDIY Python scriptFree Telegram bot
Throughput safety
Per-account rate limiter
hand-rolled
Automatic flood-wait backoff
no jitter
Multi-account round-robin
Persistent job state
memory only
Content variation
Spintax engine
Merge variables
A/B test branches
Operational visibility
Live broadcast progress UI
Outreach health dashboard
Opt-out keyword automation

DIY scripts work for tiny campaigns; they break the first time a flood-wait fires at 3 AM and there is nobody watching the terminal.

“Before CRM Solid, we ran a Python script and lost three Telegram accounts in the first month. After moving in, we have run 4,800 DMs/week for nine months across five senders with zero bans. The flood-wait handler alone paid for the subscription.”
Marcus Heinrich
Head of Sales Ops · Polymath Studio

Bulk messaging FAQ

The eight questions every operator asks within their first month of high-volume outreach.

There is no published number. Telegram does not publish its rate-limit thresholds. Empirically, healthy 30-day-old accounts can sustain ~50 outbound DMs per day to non-contacts before trust-score deterioration. New accounts should not exceed 20. The hard upper bound where flood-waits become guaranteed is around 200 per day per account for cold outreach.
Twenty per hour aligns with the median sustainable rate across a 30-day window for a warm account. It also leaves a 60% safety buffer below the practical ceiling so an occasional burst (e.g., five quick replies to a hot lead) does not breach a per-window limit. You can tune it up or down per account in Settings > Rate limiter.
A FLOOD_WAIT_X response is Telegram's way of saying "you sent too much, slow down for X seconds." CRM Solid intercepts the error at the worker layer, pauses that account's queue for X seconds plus a small jitter, exponentially backs off if it keeps hitting, and surfaces the event in the outreach health dashboard. You never see a failed message; it gets re-queued automatically.
Platforms detect <em>obvious</em> spintax: random adjective shuffling, awkward punctuation, broken grammar. They do not detect well-written human alternations like "Hi vs Hey vs Hello." The rule of thumb: every spintax variant should read as a natural sentence on its own. If you would not say it out loud, neither should your sender.
Add a second account when one account at full throttle (50/day) is the bottleneck. Add a third when two senders consistently hit the daily ceiling and you still have queued contacts. Beyond five accounts, returns diminish; you are usually better off improving template quality or audience targeting.
Sending at 3 AM in the recipient's timezone is allowed by Telegram but trains your trust score to look like a bot (humans sleep). CRM Solid's default schedule respects business hours and adds randomized jitter. The exception is if you sell B2C in a different timezone and the audience is genuinely active at night; then send.
Job state lives in PostgreSQL, not in worker memory. The worker polls the DB every five seconds for due jobs; if the process restarts, it picks up exactly where it left off, including the per-account rate-limiter counter state. No duplicates, no skips.
Yes. In Sequences > New, add two parallel step branches with different templates and a 50/50 split. CRM Solid logs which variant each contact received and surfaces per-variant reply rate, opt-out rate, and downstream pipeline conversion. Statistical-significance markers appear once you have ≥ 200 sends per variant.
Ready to ship

Send 1,000 DMs this week with the safety nets on

A 14-day trial includes multi-account rotation, the flood-wait handler, spintax, and the warm-up mode. Run the guide end-to-end on a free workspace.

Trusted by 2,500+ teams · GDPR-ready · 99.95% uptime

We value your privacy

We use cookies to improve our site, analyze traffic, and personalize ads. You can accept all, reject non-essential, or customize your choices. Read our Cookie Policy.