Skip to content

Build1 publisher2 min readPublished

Mercado Libre's search page renders a 3.3 MB DOM that OOM-kills Camoufox in a 4 GB container

The same Camoufox code cleared Mercado Libre's proof-of-work challenge six times in twelve at 4096 MB and nine times in ten at 8192 MB, with the low-memory failures reporting an error that looks exactly like a target hanging up.

The Engineer · Build desk

Illustration accompanying Mercado Libre's search page renders a 3.3 MB DOM that OOM-kills Camoufox in a 4 GB container

What happened

  • Anonymous GETs to the sites/MLA/search endpoint return the same 67-byte 403 JSON from a home laptop, a bare Apify runner, Apify datacenter and Apify residential proxies pinned to MX/AR.
  • The HTML search page answers every weak instrument with a 200 whose roughly 25.6 KB body is Mercado Libre's own suspicious-traffic-frontend asset bundle, with zero real result markers in it.
  • Only the residential request drew a real challenge: a 10.9 KB page with snoopy-script.js, a trackPowResult call, a _bmc cookie written after the computation, and the line "This page requires JavaScript to work."
  • Twelve runs at 4096 MB cleared six; ten runs at 8192 MB cleared nine, and the single miss there was an account-verification page rather than a challenge failure.
  • Once a context had cleared the challenge, offsets 49 through 385 returned 200 with 54 to 59 grid ids each across four separate attempts, with no second challenge.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint Rotating exits cannot move a 403 that is identical on datacenter and residential tiers, so budget that used to buy proxy diversity has to buy page rendering instead.
  • decision A NO-GO verdict on a browser-rendered target now needs a memory setting attached to it, because a recon run only at 4 GB cannot separate a killed process from a refusal.
  • exposure Any pipeline that asserts on HTTP status will record success while ingesting an asset bundle, so a green dashboard and an empty dataset look the same until someone reads a body.
  • cost Because clearance is bought once per run and spread over up to nine pages, abandoning a session early lands the residential clearance cost on far fewer billed rows.

The error string is where this goes wrong. At 4096 MB the browser died mid-page and the client reported `TargetClosedError: Target page, context or browser has been closed` [7]. A client prints that when the browser process is gone. It prints the same thing whether the kernel killed the process or the remote end dropped the session, and the dev.to write-up attributes the 4 GB deaths to the container running out of RAM before rendering finished [20].

The page's DOM is 3.3 MB [6]. The container that could not finish it had 4096 MB, roughly 1,200 times the document [13]. The document's byte count is not what sets the ceiling; what sets it is what the browser does with the document while the proof-of-work script runs.

Sample size deserves a look before anyone budgets on 90 percent. The two rates come from 12 runs at 4096 MB and 10 runs at 8192 MB, 22 runs in total [8][9][14]. Had two of the nine successful 8 GB runs gone the other way, the rate reads 70 percent [15]. The account was published on dev.to by the author of the Actor that ships at 8192 MB [18], and the same author reports that the OOM kills and the genuine anti-bot refusals were interleaved across one batch of runs [10]. The single 8 GB miss was an account-verification page [9].

For the jump from 50 to 90 percent to transfer to your own target, a few things have to hold. Your page has to put a comparable working set into the renderer, not just ship a similar number of bytes. Your platform has to kill the container at its memory limit; if it swaps, you get a slow run instead of a crash. And your failure classifier has to read response bodies, because in this recon a 200 was a decoy bundle, a solvable challenge, or the real page, and the status line does not separate them [4][5].

The clearance also amortises. Nine pages per cleared session at 54 to 59 grid ids per page is about 486 to 531 rows [16], and at the Actor's published $5.20 per 1,000 results that session bills $2.53 to $2.76 [11][17]. The challenge is cleared once per run [11], and the eight deeper pages came back at 2.65 to 2.77 MB each [12].

The code was the same, the proxy tier was the same, and the runs fell in the same hour. The only variable that moved was the memory ceiling [19].

What to watch

  • Whether a run count larger than 22, with each failure classified by response body, holds the 8 GB clearance rate near 90 percent.
  • Where the memory floor actually sits: only 4096 MB and 8192 MB were tested, so 5, 6 and 7 GB are unmeasured.
  • Whether the 9-page ceiling per cleared session (offset 385) moves, since it sets how many rows one residential clearance pays for.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories