# perf-memory — VALIDATION RESULTS

## Signal hypothesis

Real Chrome on desktop reports `jsHeapSizeLimit` of 2-8 GB depending on system
RAM. Headless without `--max-old-space-size` tuning reports default values
(2 GB on most installs).

## 3-condition results

| Condition | jsHeapSizeLimit | jsHeapSizeLimitMB | deviceMemory | inconsistent? | verdict |
|---|---|---|---|---|---|
| Vanilla headless | 2,190,000,000 | 2089 | 4 | True | 🟡 Mid-range |
| CDP-attached | 2,121,007,104 | 2023 | 4 | True | 🟡 Mid-range |
| Headful (Xvfb) | 2,121,007,104 | 2023 | (not shown) | True | 🟡 Mid-range |

**All 3 conditions show heap limit ~2 GB.** Server has 4GB reported as
deviceMemory (Linux server RAM is probably 8GB but Chrome caps at 4).

## Verdict: ❌ REJECTED — no discriminator on this server

The heap limit is identical across all 3 conditions (~2GB). On a real
desktop with 16GB+ RAM, the heap limit would be 4-8GB and the signal would
be informative. But:
- Server-class hardware: 2GB limit (false positive on real users on shared hosts)
- Headless: also 2GB (matches server profile)
- No way to discriminate headless from server-class real users

**False positive risk:** HIGH on server-class deployments, low-RAM VMs, and
containerized users.

## Recommendation

DO NOT SHIP. Without a way to distinguish "real user on a 2GB-heap server"
from "headless on default settings", this signal is unusable.

## Alternative

Combine with `navigator.deviceMemory`: if deviceMemory=8 AND heap limit <2.5GB,
that's suspicious (real desktops with 8GB RAM would have 4GB+ heap). But
deviceMemory is spoofable, so the combination is fragile.

## Files

- `demo.html`
