← back to blog

Running 200 profiles per machine: hardware, RAM, and CPU realities

Running 200 profiles per machine: hardware, RAM, and CPU realities

most operators hit a wall somewhere between 30 and 80 profiles. the browser starts stuttering, the machine’s swap file explodes, tasks time out, and you end up restarting everything twice a day. i’ve been there. the instinct is to buy more RAM, which sometimes helps, but more often the bottleneck is somewhere you didn’t expect: disk I/O, kernel context switches, or the proxy connection pool.

200 profiles per machine is not a fantasy number, but hitting it reliably requires thinking about resources differently than you do for a desktop workstation or even a small VPS. the goal isn’t to have 200 browser windows open simultaneously. it’s to have 200 isolated session contexts that can be activated, used, and suspended in rotation without the machine melting down. the distinction matters enormously for how you spec hardware and configure your stack.

this guide is for people who already run antidetect browsers commercially, know what a fingerprint canvas hash is, and want to push utilization higher without buying a rack of servers. i’ll cover how chromium actually consumes resources, what a realistic per-profile budget looks like, concrete machine specs that have worked in production, and the failure modes that will bite you if you ignore them.

background and prior art

the standard advice you’ll find on most forums is “1-2 GB RAM per profile,” which is not wrong exactly, but it’s a ceiling estimate rather than a floor. it comes from measuring a single Chrome window with a few tabs open and extrapolating linearly. the problem is that linear extrapolation breaks down at scale because of shared memory, OS-level caching, and the overhead of the antidetect browser’s own process management layer.

Google’s own Chromium team publishes memory architecture documentation at chromium.googlesource.com, and if you read it carefully you’ll notice that Chrome’s multi-process model means each renderer, GPU process, and browser process has separate resident set sizes. what top or Task Manager shows you is not the whole story because shared memory pages (especially for V8’s built-in snapshot and shared libraries) get counted multiple times. on a machine running 50 profiles from the same antidetect binary, those shared pages might represent 200-300 MB of savings that your naive RAM estimate misses.

the Linux kernel’s cgroups v2 interface, documented at kernel.org, has been the underlying mechanism that makes container-based profile isolation viable at scale since roughly 2019. antidetect browsers like AdsPower and Multilogin use process-level isolation rather than full containers, but the same resource accounting principles apply. understanding cgroups is useful even if you never write a cgroup rule yourself, because it explains why adding more profiles doesn’t degrade performance linearly until you hit a hard limit, and then it degrades catastrophically.

the core mechanism

a browser profile in any serious antidetect tool is fundamentally a combination of three things: a persistent storage directory on disk, a set of process-level memory allocations, and a network identity (proxy credentials plus fingerprint parameters). when you “run” a profile, you’re launching a chromium-based subprocess with a custom user data directory, injected fingerprint overrides, and a proxied network stack.

RAM breakdown per active profile

the actual memory consumption of an active profile depends heavily on what the tab is doing. here’s a realistic breakdown for a profile doing light automation work (loading a page, performing a form fill, idling):

  • browser process (the shell, UI chrome): 30-60 MB
  • renderer process per tab: 80-200 MB depending on page complexity
  • GPU process (shared across profiles from the same binary, but accounted separately): 50-150 MB
  • V8 heap for JavaScript execution: 20-100 MB per active tab
  • disk cache in RAM (chromium’s in-memory cache): 20-80 MB

a single profile doing one task on one tab realistically sits at 250-450 MB RSS (resident set size). a profile that’s open but idle, with the tab in the background, can drop to 80-150 MB if you have memory pressure configured correctly, because chromium will discard renderer memory for backgrounded tabs. this is the feature that makes 200 profiles possible without 200 × 400 MB = 80 GB of RAM.

the key insight: you don’t need all 200 profiles active simultaneously. you need a scheduler that runs profiles in waves. if your tasks take 3-5 minutes each and you’re running 200 profiles through them in a session, you might only have 20-30 active at any given second. that’s a very different hardware requirement.

CPU realities

chromium is single-threaded per renderer process, but the antidetect layer adds overhead. fingerprint spoofing for canvas, WebGL, audio, and fonts happens via JavaScript hooks injected at page load. each hook adds a small but real per-call cost. on a page with heavy canvas usage (think social media feeds with image processing), these hooks can add 5-15% to renderer CPU time.

for scheduling 200 profiles in rotation on one machine, you want high core count over high clock speed. a 32-core Epyc or Threadripper will outperform a 12-core i9 at high profile counts even if the i9 has a faster single-core benchmark. each active profile wants its own core or at least its own logical thread. when you over-subscribe CPU heavily (20 active profiles on 8 cores), you start seeing context switch overhead that manifests as fingerprint timing anomalies. canvas readback timestamps that should be consistent become jittery. this is detectable.

disk I/O and the storage wall

this is the bottleneck most people don’t anticipate. each profile has its own user data directory containing the leveldb databases for cookies, localStorage, IndexedDB, and history. chromium writes to these constantly. on a spinning disk or a slow SATA SSD, having 20+ profiles simultaneously performing writes causes I/O queue saturation.

the symptom is subtle at first: pages load but post-render interactions feel sticky. form fills that should take 2 seconds take 8 seconds. if you run iostat -x 1 during a workload and see %util at 90%+ on your disk, you’ve hit this wall. the fix is NVMe. specifically, a PCIe 4.0 NVMe drive like the Samsung 980 Pro or WD Black SN850X provides sequential write speeds of 5-7 GB/s and random 4K write IOPS in the 700k-1M range, which is what you actually need for concurrent small-write workloads. SATA SSDs top out at ~100k IOPS. the difference is real and measurable.

a second option that works well is using a RAM disk (tmpfs on Linux) for active profile directories and syncing to persistent storage when profiles are deactivated. i’ve run this setup on a 128 GB machine with 40 GB allocated to tmpfs. it eliminates disk I/O as a bottleneck entirely for active profiles and reduces fingerprint timing variance. the downside is that a crash means you lose session data for active profiles.

network and proxy considerations

200 profiles means 200 proxy connections. even if you’re rotating residential proxies via a pool, you’ll have bursts of 20-50 simultaneous TCP connections through the same proxy gateway. most proxy providers rate-limit concurrent connections per account or per IP. check your provider’s docs. for large-scale work, you want either per-profile dedicated proxies or a proxy rotation service that explicitly supports high concurrency. the machine’s network stack itself is rarely the bottleneck unless you’re on a 100 Mbps connection, but proxy-side limits will throttle you before your NIC does.

worked examples

example 1: AdsPower on a dedicated server, e-commerce automation, 150 profiles

hardware: AMD Epyc 7302P (16 cores, 32 threads), 128 GB DDR4 ECC, 2 TB Samsung 980 Pro NVMe, Ubuntu 22.04.

workload: 150 profiles visiting product pages, adding to cart, checking order history. tasks run in batches of 25, cycling continuously. average task duration 4 minutes.

at any given moment, 25 profiles are active (roughly 16% of total). peak RAM consumption observed via free -m: 42 GB used, 12 GB in buffers/cache, 74 GB free. disk %util stays under 30% during heavy phases. CPU load average hovers around 14-18 on the 32-thread machine. no swap is used.

this config has headroom. you could push to 200 profiles with this hardware. the limiting factor isn’t RAM or CPU, it’s the proxy provider’s concurrent connection cap (50 simultaneous connections in this case), which required splitting into two provider accounts.

example 2: Multilogin on a Windows Server 2022 VM, social media, 80 profiles

hardware: VM with 16 vCPUs, 64 GB RAM, 500 GB NVMe-backed virtual disk. host machine is a Hetzner AX101 (AMD Ryzen 9 5950X, 128 GB DDR4).

workload: 80 profiles running content engagement tasks on a social platform. tasks are shorter (90 seconds), but profiles are more active concurrently (40 at a time) because of the task structure.

Windows overhead is real. the base OS + Multilogin agent idles at about 6 GB RAM before any profiles are launched. each active Chromium profile on Windows uses slightly more RAM than Linux equivalents, roughly 10-15% more, because Windows doesn’t benefit from the same copy-on-write memory sharing optimizations for shared libraries. peak observed RAM: 54 GB of 64 GB. this is uncomfortably close to the limit. the recommendation here would be to move to Linux or increase to 96 GB RAM before adding more profiles.

disk I/O was the first bottleneck hit on this setup. virtual disk performance on shared Hetzner infrastructure was inconsistent. tasks ran fine for 20 minutes, then slowed down as disk queue backed up. solution: moved active profile directories to a 16 GB tmpfs partition. issue resolved.

example 3: GoLogin on a bare-metal Intel box, affiliate work, 60 profiles

hardware: Intel Core i9-13900K (24 cores, 32 threads), 64 GB DDR5, 1 TB WD Black SN850X, Fedora 39.

workload: 60 profiles, all running simultaneously (not in batches) for a short burst task that needs to finish within a 10-minute window. this is the “everything at once” scenario.

this is the hard mode configuration. 60 × 350 MB = 21 GB minimum RAM for profiles, plus OS overhead, plus GoLogin’s Orbita browser engine, plus proxy client software. observed peak: 49 GB RAM used, 8 GB swap activated. the swap activation caused performance degradation and timing jitter. the fix required reducing to 48 simultaneous profiles, which stayed under 40 GB active RAM and kept swap at zero.

the lesson: for simultaneous-launch workloads, the math is simple and unforgiving. budget 400-500 MB per profile for the simultaneous scenario, not the rotating scenario. 64 GB RAM supports roughly 100-110 simultaneous profiles on Linux with careful configuration, or about 50-60 on Windows.

edge cases and failure modes

1. tmpfs and crash recovery

running profile directories in RAM is fast but fragile. if the machine kernel panics, loses power, or the OOM killer terminates the antidetect browser’s parent process, every active profile loses its session state. cookies, localStorage, and pending writes are gone. for accounts where session continuity is critical, you need a checkpoint strategy: flush profile state to disk before suspending a profile, not just when closing the application. AdsPower has a sync-on-suspend option. GoLogin’s cloud profiles handle this at the platform level. if you’re building custom tooling, implement explicit sync calls before deactivating a profile.

2. OOM killer and profile prioritization

Linux’s OOM (out-of-memory) killer will start terminating processes when RAM is exhausted. by default it uses a heuristic that often kills large processes first, which will be your browser profiles. you can influence this with /proc/[pid]/oom_score_adj. setting your antidetect browser manager to a low OOM score (-500 to -1000) protects it from being killed first. setting individual profile processes to higher scores (+200 to +500) makes them sacrifice themselves before critical infrastructure. this is a 10-minute configuration task that can prevent losing an entire session because one profile misbehaved.

3. fingerprint timing jitter under CPU load

canvas fingerprints and WebGL renders have timing components. platforms measure how long certain operations take as part of behavioral fingerprinting. under heavy CPU load (load average > number of cores), renderer processes get starved. a canvas readback that normally takes 2ms takes 15ms. this timing signature is unusual and some platforms flag it. the mitigation is to not over-subscribe CPU. if you have 16 cores, don’t run more than 14-15 simultaneous profiles doing canvas-heavy work. the remaining headroom goes to OS tasks and fingerprint hook overhead.

4. proxy connection exhaustion

each active chromium profile maintains several TCP connections: one or more to the proxy, connections within the proxy tunnel to the target site, and background connections for browser telemetry. a profile doing nothing still has 3-8 open connections. 50 active profiles can mean 150-400 open file descriptors just for network. Linux’s default ulimit -n is often 1024 per process. if your antidetect browser’s main process manages all proxy connections, you can hit this limit. check with ulimit -n and increase to 65536 in your systemd service file or /etc/security/limits.conf. this is a silent failure, profiles just stop loading pages with no obvious error.

5. leveldb lock contention

chromium’s user data directory uses leveldb for persistent storage. leveldb holds an exclusive file lock on the database. if you try to launch two processes pointing at the same user data directory, the second one fails silently or corrupts the database. this matters because antidetect browsers sometimes create backup processes or watcher services that inadvertently re-use profile paths. audit your process table if you see unexplained profile corruption. lsof | grep LOCK on the profile directory will show you what’s holding the lock.

what we learned in production

the biggest shift in how i think about this work came from treating profile capacity as a scheduling problem rather than a hardware problem. buying more RAM delayed the wall but didn’t move it. building a proper rotation scheduler that respected per-machine resource budgets moved it significantly. the practical approach: instrument your machine (i use netdata for real-time RAM and I/O graphs) and set hard limits in your scheduler. if free RAM drops below 15 GB, pause new profile launches until it recovers. if disk I/O utilization stays above 70% for more than 30 seconds, suspend the lowest-priority profiles. these are simple rules that cost one afternoon to implement and eliminated 90% of the failure cases.

the other thing worth saying: different antidetect browsers have meaningfully different resource footprints. Multilogin’s Mimic browser (chromium-based) and Stealthfox (firefox-based) have different per-profile costs. AdsPower’s SunBrowser is lighter than GoLogin’s Orbita on RAM in my testing, but heavier on disk. if you’re building a scaled operation, run your own benchmarks on actual hardware before committing to a stack. spin up 10 profiles, run smem -t or ps_mem for accurate shared-memory-aware accounting, and extrapolate from there. the antidetect browser comparison notes at /blog/ are a starting point, but your workload profile is what determines the real number.

if you’re also thinking about this from an airdrop farming or multi-account DeFi angle, the hardware constraints are identical, the scheduling problem is the same, and the proxy management problem is arguably harder because gas estimation adds extra network calls per profile. the airdrop farming resource guides at airdropfarming.org/blog/ cover some of the task-scheduling angles that apply directly here.

for operators running Windows specifically: consider whether you need Windows at all. Linux gives you better memory efficiency, proper cgroup controls, and a much richer toolchain for process monitoring. the only legitimate reasons to run Windows for antidetect work are if your specific browser version requires it or if your automation scripts rely on Windows APIs. otherwise, Ubuntu 22.04 LTS or Fedora 39 on bare metal will consistently give you 15-25% more effective profile capacity on the same hardware.

references and further reading


see also on this site:

for multi-account operations workflow context beyond browser fingerprinting, multiaccountops.com/blog/ covers task orchestration patterns that scale alongside the hardware setup described here.


Written by Xavier Fok

disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-05-19.

need infra for this today?