Popunder — Traffic Dashboard Real /w/<id>.js traffic — requests, hits/miss, geo, referrers, networks, devices — plus per-wrapper drill-down and cost. Engine (cloudfroze.com) is aggregate-only. Per-request wrapper analytics from Analytics Engine (popunder_stats). The time range below is global; it drives every panel + query. Reads are billed per query ({freeAeRead}/mo free, un-billed in preview) and cached ~45s in the worker.
Set by the Worker from the span.
Global wrapper trafficEvery /w/<id>.js request, sample-weighted: requests = SUM(_sample_interval·SAMPLE). hits = pop opened (double2=1); miss = requests − hits. One folded time-series query fills these tiles + the chart.
In target / not in targetLevel 3 of the hierarchy: level 1 = requests (what you pay), level 2 = hit/miss (why the cost is what it is), level 3 = how many visitors could actually SEE a pop. In target = requests − refused − undetermined. Undetermined is a THIRD bucket, never folded into either side. Same time-series query as the KPIs above → 0 extra AE reads. ABSENT IS NOT ZERO: when the gate reports no coverage, no claim is made either way; and when it was enforcing on nothing, ‘not in target’ reads 0 BY DESIGN — never evidence that the traffic was in target.
Window cost — what each outcome actually costs
Requests over time Sample-weighted requests per bucket, hits + miss stacked. The dashed line is delivered (in target) on the same scale — the gap between it and Requests is traffic you paid for that could not see a pop. Hover for exact values; switch the metric with the chips. In-target % is the RATIO per bucket — the overlay on the Requests view is a count, so it climbs with volume and a targeting collapse inside a traffic ramp is invisible.
Breakdowns Each dimension is one AE query (single table → one GROUP BY per query), cached ~45s and opened lazily. Top-N via LIMIT; the 'Others' row = grand total − Σ shown (0 extra reads). Hit/miss AND the full level-3 target split come free in every row of every dimension — they ride on the same query.
In target (gate checked it) Not checked (gate off/observe) Not in target (refused) Undetermined One bar per row, drawn against THAT ROW'S OWN requests — so a small country and a large one are directly comparable. The four parts are mutually exclusive and sum exactly to the row's requests: in target = armedreq − cloaked, not checked = requests − armedreq − coldpass, not in target = cloaked, undetermined = coldpass. The first two together are 'delivered', the single In-target segment the card bar above draws — the hatch splits it into the part EdgeGate actually vetted and the part it never saw. A row with few refusals because the gate was off is therefore mostly hatched, and cannot be misread as 'targeting is working'.
Global Engine — cloudfroze.comThe engine (/e/<id>.js) is served R2-direct with no Worker → there is NO Analytics Engine datapoint for it. Numbers here come from one GraphQL call (R2 bucket metrics + optional cloudfroze.com zone) and cost 0 AE reads.
Per-wrapper drill-downPick a wrapper id (datalist filled from the ids query, shared with Costs). Same metrics as global, filtered by blob1 (the AE index → cheapest filter).
KPIsThis wrapper's share of the account, hit-rate, unique IPs, and an engine-load estimate (≈ requests). All derived from the drill series + the account Rtot — 0 extra reads for engine + cost.
In target / not in targetOf THIS wrapper's requests, how many visitors could actually see a pop. In target = requests − refused − undetermined; undetermined (cold) is a third bucket, never folded into either side. Folded out of the same per-id series query → 0 extra AE reads.
Window cost — what each outcome actually costs
Requests over time
Breakdowns
In target (gate checked it) Not checked (gate off/observe) Not in target (refused) Undetermined One bar per row, drawn against THAT ROW'S OWN requests, so rows of very different size stay comparable. in target = armedreq − cloaked · not checked = requests − armedreq − coldpass · not in target = cloaked · undetermined = coldpass. The four sum exactly to the row's requests; the first two together are 'delivered'. Hatched = nobody checked it, so it can never be read as evidence that targeting passed.
Estimated costMarginal + base-share, identical method to the Wrappers Manager. Marginal = share × account over-tier × {$worker}; base = share × {$base}/mo (informational). Engine ≈ $0 (R2-direct).
Global projected cost/w/ wrapper request run-rate × (days-in-month / N) + {$base} base — projected to the CURRENT month. An allocation/projection, not a bill — marginal is $0 until the account crosses {freeWorker} requests/mo. A FLOOR, not the account total: /geo and /admin are billed Worker requests that write no Analytics Engine datapoint, so the real run-rate is higher. Reconciles with the per-id ‘bill’ column at any window.
Per-wrapper cost Per-id marginal + base-share (share of Rtot, the /w/ wrapper request total over the window). Total = marginal + base, never the gross weight. Same math + CSV columns as the Wrappers Manager. Uses the ids query (all ids, no LIMIT) so Rtot is exact for /w/ — but /geo and /admin are billed with no AE datapoint, so the over-tier is a floor.
| id | Requests | Hit-rate | Real (to-date) · Est. / mo REAL = gross weight actually accrued in the window, un-projected. EST. /mo = the same, scaled to month-end at {$worker}. You PAY only the ‘bill’ underneath: this row's share of the account marginal beyond the {freeWorker}/mo free tier, $0 below it. | Base * | Total |
|---|---|---|---|---|---|
| Σ | — | — | — | — |
* Base share = proportional slice of the flat {$base}/mo platform fee — informational, not a marginal charge. Marginal $ stays $0 until the whole account crosses {freeWorker} requests/mo.
AE read budgetThis dashboard's own AE read-query cost. Reads are billed per query; {freeAeRead}/mo free, un-billed in preview today. Reload / theme toggle / a second viewer within 45s = 0 reads (worker cache keyed by the SQL).
📖 One AE query per dimension · reads cached ~45s · level 3 costs 0 extra reads
- Analytics Engine is a single table — no JOIN / UNION / ROLLUP. Each GROUP BY dimension = one read query.
- Reads are billed per query (not per row). {freeAeRead}/mo free; un-billed in preview today.
- Each SQL result is cached ~45s in the worker (keyed by the SQL text) → refresh / reload / a second viewer = 0 reads.
- The time-series query folds in the overview (client sums buckets → total requests/hits/hit-rate). Breakdowns load lazily per open tab; top-N via
LIMIT; hit/miss are free columns. - The three level-3 outcomes are billed the same per /w/ request but do not cost the same overall: an in-target visitor also pays a second Worker request (
/geo, cached {geoCacheH} h inlocalStorage), the cfg object and the engine {engineGets}×; a refused one pays the {denyBytes}-byte 403 and nothing after it./geowrites no AE datapoint, so it never appears in the request counts on this page. Prices come fromcost-model.js, the panel's single rate list. - Level 3 (in target / not in target / undetermined) rides on the same queries as extra
SUMcolumns — 0 extra reads.cloakedis 0 by design wheneverEG_MODEis off/observe: nothing was refused, which is not the same as “no out-of-target traffic”.ccfail/devfailare independent axes — a request can fail both, so they are never summed.
⚙️ Needs /admin/traffic + AE_API_TOKEN · engine needs /admin/enginestats + MGMT_API_TOKEN
- The Worker needs the route
/admin/traffic+AE_API_TOKEN+CF_ACCOUNT_ID(same token that powers/admin/stats). - Engine metrics need
/admin/enginestats+MGMT_API_TOKEN(Account Analytics: Read + R2 read; optional Zone Analytics: Read on cloudfroze.com for real engine requests + egress). - The browser sends only
ADMIN_TOKEN(from the controls above) to the Worker; the powerful tokens stay Worker secrets — no CORS, no secret in the browser.