How we count & filter traffic
The rules behind every number we bill and report.
Counting
A billable impression is the render-confirmed served beacon, never the ad request. Clicks deduplicate per impression: only the first can bill, and repeats redirect but carry the original click id. Every billable event becomes exactly one double-entry ledger transaction, and this CSV, your dashboard totals, and your balance all derive from that one event log, so they cannot disagree with each other.
We also count a viewed event on the IAB bar: at least 50% of the ad's pixels on screen for at least one continuous second, deduplicated per impression and accepted only after the ad has rendered. Your viewability rate is that viewed count divided by served impressions (the same render-confirmed event we bill on, never the ad request, never the fill count), computed over all of your traffic in the window, filtered impressions included. It is measured and reported from day one and never billed. See Viewability for what it means and how a publisher improves it.
Daily figures are bucketed by UTC day, everywhere: reports, charts, and budget windows all cut at midnight UTC, regardless of the display timezone picked in Settings (which shifts only rendered timestamps, never the day a figure lands in).
First-price auction: win_price_micros equals your bid. To join clicks in your own tracker, add {PUFF_CLICK_ID} / {PUFF_IMP_ID} macros to your landing URL, or read the pclid parameter we append when no macro is present.
Filtering
Every billed or filtered event is recorded row-by-row at full fidelity, and each one that fails an invalid-traffic check is marked. Two purely informational event kinds are aggregated into your daily totals instead of row-logged: render-only view-tracking events, and all but a 1-in-100 sample of raw ad requests. Neither kind is ever billed, and neither carries a filter outcome. Filtered events are never billed and never hidden. On the advertiser raw export each appears with its exact reason:
| filter_reason | Meaning |
|---|---|
bot_ua |
Known bot / automated user-agent. |
rate_ip_hour |
Per-network (/24) hourly rate cap exceeded. |
rate_ip_day |
Per-network (/24) daily rate cap exceeded. |
rate_uid_hour |
Per-user hourly rate cap exceeded. |
rate_uid_day |
Per-user daily rate cap exceeded. |
dup_window |
Same user re-rendered the same ad in the same zone inside the dedup window. |
rate_zone_min |
The zone's automatic rate brake is active, so serving is paused for a cooldown after its per-minute rate spiked. |
rate_campaign_min |
The campaign's per-minute served-event ceiling was crossed. |
The publisher view, coarse categories
Publishers see the same filtered impressions on their reporting, but grouped into a few plain categories rather than the exact reason. We show the category, not the precise cap or threshold, so a bad actor can't read the rules and pace under them. The fact is disclosed, the parameter is not. The mapping:
| Category | filter_reason(s) |
|---|---|
| Automated | bot_ua |
| Rate-limited | rate_ip_hour, rate_ip_day, rate_uid_hour, rate_uid_day |
| Duplicate | dup_window |
| Rate protection | rate_zone_min, rate_campaign_min |
| Other | any newer reason not yet categorised |
See Filtered traffic on your zones for the publisher-facing explanation. Country/network blocklist drops are counted separately. A blocked request never renders an ad, so it never becomes a filtered impression here.
Retention
We keep the event-level raw log, every impression and click, transaction by transaction, for at least 90 days, so your CSV export can always reach back that far to reconcile against your own tracker. In practice the window runs a little longer: the log is stored in monthly slices we age out whole, so effective retention is roughly 90-120 days.
Aggregate reporting is not affected. Your dashboard totals, reports, and everything the ledger derives, invoices and balances, are kept indefinitely. Only the row-by-row raw log ages out. An export aimed at a window inside the retention horizon returns every matching event.
Identity
We identify a viewer by a first-party cookie, or, when none is set, a keyed hash of coarse request signals. Your full IP address is never stored: we keep only its /24 network prefix.