"Anti-detection" isn't a single feature. It's a stack of 20+ defense layers, each blocking a specific detection vector, and together they let a Facebook bot run for months without getting caught. In this article I'll break down the full stack we at BuzzPost built over 4 years, with code examples and numeric values you can implement.

This isn't "general tips." This is the engineering specification behind a system handling 150+ accounts in parallel without anyone breaking.

Layer 1: User-Agent consistency

The UA is your bot's first impression. At BuzzPost we use a real UA from the latest Chrome on Windows:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36

Three main directives:

  • The same UA always. Swapping between sessions = checkpoint.
  • A real UA, not invented. Facebook compares to a database of known UAs.
  • UA matching the real OS of the VDS. If you run on a Windows VDS — Windows UA. Not macOS.

When Chrome updates (about once a month), the UA changes slightly. We follow this update and don't try to stay on an old UA — because too old a UA also raises a flag. The sweet spot: UA never older than 3 months from the current Chrome version.

Layer 2: viewport and window size

Our default: 1366×768. Why? Because it's the most common Windows screen resolution. ~22% of Windows screens in 2026 are 1366×768. If your bot runs at 1920×1080, you're in the minority, and that's a spam signal.

Window size setting:

chrome.exe --window-size=1366,768 --window-position=0,0

Important: window.outerWidth/outerHeight should be 1366/768, but window.innerWidth/innerHeight should be slightly smaller (because of the toolbar). That's the natural ratio Facebook expects.

Side randomization: not randomization of the window size itself (that's a fingerprint signal), but of the scroll position — sometimes scrolling down before an action.

Layer 3: locale and timezone

Critical for Israel: lang=he-IL in Chrome and timezone Asia/Jerusalem in OS. These values are exposed in several ways:

  • navigator.language — gets the lang flag.
  • navigator.languages — array, default ["he-IL", "he", "en-US", "en"].
  • Intl.DateTimeFormat().resolvedOptions().timeZone"Asia/Jerusalem".
  • HTTP header Accept-Language: he-IL,he;q=0.9,en-US;q=0.8,en;q=0.7.

An Israeli Facebook account connecting with Accept-Language: ru-RU = a strong signal something's wrong. At BuzzPost the locale is set once when setting up the VDS and fixed for life.

Layer 4: WebGL and Canvas fingerprint

As I detailed in the headless vs visible article, the WebGL fingerprint is a critical detection point. On a VDS visible:

  • We don't pass --disable-gpu.
  • We don't use any "anti-fingerprinting" extension that modifies the renderer (it hurts).
  • We rely on Hyper-V/KVM's GPU providing organic WebGL.

Canvas fingerprint: also organic. Derived from GPU and OS, not biased.

Layer 5: delay randomization

One of the most important anti-detection pillars. Between every two bot actions, there's a random 8-22 second delay. Why this range?

  • Less than 5 seconds = obvious bot. A human can't process a screen + read + click at this speed.
  • More than 30 seconds = idle session, looks suspicious (why did a user open a group and do nothing for 30 seconds?).
  • 8-22 seconds = the natural range of a human scrolling a group, reading a headline, deciding to post.

Our code:

import random, time
def human_pause():
    seconds = random.uniform(8, 22)
    time.sleep(seconds)

Additional improvement: non-uniform distribution. Most times 10-14 seconds, but sometimes 20+. This brings the distribution closer to human truth.

Layer 6: key-press timing

When the bot "types" text, it doesn't paste the whole text at once (send_keys in selenium pastes "instant" and that's a bot signal). Instead: character-by-character typing, 50-150ms between keys.

def human_type(element, text):
    for ch in text:
        element.send_keys(ch)
        time.sleep(random.uniform(0.05, 0.15))

Why 50-150ms? That's the range of regular typing speed (60-100 WPM). Less than 50ms = bot. More than 200ms = typing with eyes closed.

Improvement: occasionally a backspace + correction, or a 0.5-1s pause mid-sentence. Looks genuinely human.

Layer 7: mouse paths (Bezier curves, not lines)

A layer most bots ignore. When a bot "moves the mouse" to a button, does it travel in a straight line? A human doesn't do this.

A human moves the mouse along a Bezier curve: starts slow, accelerates in the middle, decelerates at the end. Our code computes random control points and performs the movement in ~30 frames of 16ms each (60fps).

def move_mouse_bezier(driver, target_x, target_y):
    # Compute Bezier path with random control points
    ActionChains(driver).move_to_element_with_offset(...)
    # ... 30 micro-movements over 500ms
    pass

If Facebook listens to mousemove events (it does), it sees the difference. Naive bots traveling in a straight line are flagged within 5 actions.

Layer 8: scroll patterns

A human scrolling a Facebook feed doesn't scroll at a constant pace. They scroll a bit, stop, read, scroll more, scroll back up (something caught their eye), scroll down again. Our bot performs scroll patterns of 4-8 movements with pauses between them.

def human_scroll(driver, total_y=2000):
    chunks = random.randint(4, 8)
    for _ in range(chunks):
        delta = total_y // chunks + random.randint(-50, 50)
        driver.execute_script(f"window.scrollBy(0, {delta});")
        time.sleep(random.uniform(0.4, 1.2))
    # Sometimes scroll back up
    if random.random() < 0.2:
        driver.execute_script("window.scrollBy(0, -300);")
        time.sleep(random.uniform(0.5, 1.5))

Layer 9: cookie persistence (as discussed in a separate article)

See session persistence and cookies. Summary: saving user-data dir, active refresh every 13 days, no deletes.

Layer 10: IP isolation

Every VDS with its own static IP. No proxy chains, no shared IPs. Why?

  • Proxy chains add latency that biases the performance timing fingerprint.
  • Shared IPs (even residential) are used by others who may be banned themselves.
  • Static IP from an Israeli data center is the most "normal" for an Israeli Facebook account.

All our VDS on infrastructure of European and Israeli data centers, with clean vetted IPs.

Layer 11: the warm-up school

A new account can't start posting immediately. Our protocol:

  1. Week 1: daily Facebook login, feed scroll for 5-10 minutes, likes on 3-5 posts, zero personal posts.
  2. Week 2: additionally, adding 5-10 real friends, joining 3-5 groups, comments on 2-3 posts.
  3. Week 3: 1-2 personal posts (not group), share one post.
  4. Week 4 and beyond: bot starts posting — begins with 3-5 posts/day and grows gradually.

An account that starts publishing 50 posts/day on day one — banned within 24 hours. This protocol is non-optional.

Layer 12: structural detection (not textual)

Detailed in the rate-limit engineering article. Summary: detecting post outcome via ARIA structure, not text. It sounds odd to call "outcome detection" a layer of anti-detection, but it is: a system that's wrong 70% of the time will fail fast. Accuracy = survival.

Layer 13: watchdog and recovery

If the bot is stuck (state mtime > 90 minutes), a watchdog process restarts it. It's not just a bug fix — it's anti-detection because "stuck bot" becomes "forgotten bot" that may raise suspicion.

Summary

Anti-detection in 2026 is serious engineering. BuzzPost handles all 20+ layers automatically — you don't need to know what a Bezier curve or timezone leak is; you just open the panel and see the system running. Every customer gets a dedicated VDS with all defenses ready. If you want to start posting without losing the account — buy the first plan at 249₪/month. One server, the whole stack.

More info: features, headless vs visible, multi-account management.

Layers 14-20: deep dive into additional layers

Layer 14: post randomization (content + image)

No two posts should be identical. The bot uses AI (GPT-4 or a local model) to write variants of the same content. For example, "apartment for rent Kiryat Motzkin" can be:

  • "For rent in Kiryat Motzkin: cozy and bright 3-bedroom apartment"
  • "Offering for rent in Kiryat Motzkin — 3 rooms, excellent condition!"
  • "3-bedroom apartment for rent in Kiryat Motzkin, immediate move-in"

Images: a pool of 20-30 photos per apartment, and each post uses a different photo. If there aren't enough real photos, light processing (crop, color shift, new metadata) on the same photo creates a variant.

Layer 15: hashtag management

Hashtags rotate. Don't use the same 5 hashtags in every post. Additionally, variation in hashtag order — sometimes at the end of the post, sometimes in the middle.

Layer 16: phone number consistency

The phone number appearing in real-estate posts is the customer's contact. It too undergoes light format randomization:

  • 050-123-4567
  • 050 123 4567
  • 050.123.4567
  • 0501234567
  • +972-50-123-4567

Facebook doesn't flag phone numbers, but identical posts with identical number formats are considered more spammy.

Layer 17: time-of-day distribution

Posts spread across 4-5 time windows in 24 hours, most at night (00:00-07:00). Don't concentrate all 24 posts into 2 hours.

Layer 18: group rotation

A bot doesn't post to the same group twice in one day. If there are 50 target groups, day one 25 groups, day two the other 25. After 7 days — back to rotation.

Layer 19: image hash management

Facebook computes a perceptual hash for every image. If the same photo is uploaded to 3 different groups, Facebook sees the connection. With us we perform image aging: every photo doesn't return to the same group for 7 days, and after 7 days — a variant of the photo (different crop, different framing).

Layer 20: monitor + alerting

The full system includes dashboards, alerts, and health checks. If one post fails — alert. If 3 posts fail in a row — serious alert. If the general error rate rises from 5% to 15% — critical alert.

Questions customers ask

"What if Facebook adds a new detection layer?"

We track the issue. When something changes — our entire fleet (150+ accounts) sees the same phenomenon simultaneously, and that's a clear signal. We update the detector in 48 hours on average.

"How will I know the bot is working correctly?"

The panel has a full dashboard: how many posts today, success rate, red alerts if something's wrong.