---
title: "How Epom computes your numbers: General, Advanced and raw-log reports"
description: "What each report type is answered from — stored daily and hourly totals for General, Header Bidding and Targeting Cookie, request-level logs for Advanced and the event logs — why the figures can disagree, and which report to trust for billing versus exploration."
type: "concept"
audience: [network-manager, admin]
keywords: [analytics pipelines, general report, advanced report, header bidding report, targeting cookie, raw log, request-level logs, freshness, latency, filter-only dimensions, billing, which report]
---

Fetch the complete documentation index at: https://epom.com/ad-server/docs/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# How Epom computes your numbers: General, Advanced and raw-log reports

Two Epom reports over the same dates can show different numbers, and both can be correct. That
is expected — it is the direct consequence of Epom answering different report types from
different data, with different freshness, different dimensions and, in places, different
counters. This page explains what each type reads and why, so you can tell which report to trust
for what.

If you just need the "why don't my numbers match" checklist, go to
[Analytics discrepancies](https://epom.com/ad-server/docs/troubleshooting/analytics-discrepancies.md). This page is the mental
model behind that checklist.

## Which data answers which report

When you run a report, the **Type of reports** selector on the Filter tab decides which data
answers it:

| Type | Reads from | Row = | How it runs |
|---|---|---|---|
| **General** | Daily and hourly aggregates the ad servers produce | One aggregated row per your group-by | Inline, no progress bar |
| **Header Bidding** | Its own daily and hourly aggregates | One row per fill source (direct campaign, publisher ad server, AdX / AdSense, a bidder, unfilled) | Inline |
| **Targeting Cookie** | Its own daily cookie-targeting aggregates | Cookie name/value statistics | Inline |
| **Advanced** | The full ad-request log | Aggregates with many extra dimensions | Background job with a progress bar |
| **Raw logs** | The individual event logs | One row per event | Background job with a progress bar |

Only Advanced and the raw logs read the full event logs; the other three read pre-aggregated
statistics. The per-type availability, permissions and controls are in
[Report types](https://epom.com/ad-server/docs/guides/analytics/report-types.md); the rest of this page is about General,
Advanced and the raw logs, because those are the ones that get compared.

### General — the aggregated statistics

General reads hourly and daily aggregates of what the ad servers recorded. There is no
background computation and no progress bar: you ask, it queries, it answers. It is the type that
feeds [dashboard widgets and scheduled e-mails](https://epom.com/ad-server/docs/guides/analytics/dashboards.md), together with
Advanced, and it is the type that carries the advertiser **Status** (finalization) grouping.

### Advanced — recomputed from the ad-request logs

Advanced recomputes aggregates from the **full ad-request log**, which is why it can break your
data down by dimensions General doesn't carry (browser, OS, device model, carrier, risk, custom
parameters, and more — see [Analytics dimensions](https://epom.com/ad-server/docs/reference/analytics-dimensions.md)). It runs
as a background job, and its results are **cached per query window**: a repeat of the same query
is answered from the cache until a newer hour of data has loaded (or for good, once the window
ended two or more days ago).

### Raw logs — one row per event

The Impressions / Clicks / Conversions Log types read the individual event records — the actual
per-impression, per-click, per-conversion rows — with the same cache rule as Advanced. Use them for auditing a specific event, comparing an event stream against a
partner, or inspecting invalid traffic. They have **no group-by** — they are event lists, not
aggregates.

## Freshness: nothing shows the current hour

No report type is live. Ad servers collect events in **hourly batches**, and a batch becomes
reportable only once its hour has **ended**, so the hour in progress is never in any report. The
aggregated types (General, Header Bidding, Targeting Cookie) and the log-based types (Advanced and
the raw logs) load on **separate schedules** — by default about a minute past the hour and roughly
25–30 minutes past the hour respectively. The exact schedule is a per-network setting that Epom
support or your account manager can change.
[Report types](https://epom.com/ad-server/docs/guides/analytics/report-types.md#freshness-nothing-shows-the-current-hour) has the
table.

## Why they disagree — the real reasons

### 1. The newest hours differ by report family

Both families lag by at least the hour in progress, and because the two loads run on their own
schedules, General and Advanced can include a different last hour. For **today**, any difference
between them may be nothing more than "one family has loaded an hour the other has not". "Today"
is **always provisional** in every type — for final daily numbers, report on yesterday or
earlier.

### 2. Yesterday can still move

A day is assembled from hourly batches as they are loaded, so a batch that arrives late revises
the day after the fact. Advanced and the raw logs add their cache on top: two runs of the same
query minutes apart return the *cached* result and look identical, and a run after the next hour
loads can differ.

### 3. The two report families count differently

General and Advanced are not two views of the same numbers; each computes its ratios from its own
counters:

- **eCPM and the other money-per-thousand figures.** On General, eCPM divides money by
  **impressions**. On Advanced it divides by **eligible impressions** — deliveries minus matched
  passbacks minus rejected impressions — so the same money over the same traffic gives a higher
  eCPM there when some impressions were rejected. See
  [CPM, eCPM and RPM](https://epom.com/ad-server/docs/concepts/revenue-metrics-cpm-ecpm-rpm.md) and
  [invalid traffic](https://epom.com/ad-server/docs/concepts/invalid-traffic-and-risk-scoring.md).
- **Conversions.** System conversions — the VAST quartile, viewability and player-interaction
  events — are left out of the **Conversions** column on General (from the release-152 upgrade
  day on; earlier days keep their old totals) and on Advanced (which recomputes from the raw logs,
  so it drops them for every day since release 149). On a network whose Advanced report runs on
  compacted logs the count comes from a pre-aggregated figure that still includes them, so the
  same network can show more conversions there. Their money still
  lands in Gross and Net; group by **Action** to see the system events themselves.

### 4. A compacted Advanced setup drops some group-by dimensions

Advanced reads either the full logs (the default) or, on some networks, **compacted logs** that
don't carry every field. On compacted logs a set of Advanced dimensions becomes **filter-only** — you can filter by them but not group by
them. The list removed from group-by includes:

> Mobile Carrier, Connection Type, Language, Accept-Language, Time Zone Name, Browser Country,
> Traffic Source, Incognito Mode, Is Web App, Platform, Placement Size, Placement Type, Device
> Format, Proxy, Device Release Year, Device Vendor / Model / Model Code, Risk Level and Risk
> Category — plus, on some networks, a few further fields.

The practical trap: **filtering** an Advanced report on one of these can legally return **zero
rows** even though the totals report shows traffic — because the field the filter needs may be
absent from the compacted logs. If a filtered Advanced report comes back empty, drop the exotic
dimension and re-run before concluding "data loss". Full per-dimension detail is in
[Analytics dimensions](https://epom.com/ad-server/docs/reference/analytics-dimensions.md); ask Epom support or your account manager whether your network
runs on compacted logs.

## Two more sources of "different numbers" that aren’t the report type

These get blamed on the report type but are independent:

- **Time zone.** Only the **Advanced** report has its own **Time zone** selector (default UTC);
  every other type (and dashboards) has no zone control: days are cut where the ad servers cut
  their hourly logs, the network's reporting time zone. Two reports comparing different zones
  shift events across the midnight boundary. This is a bucketing difference, not a data difference — see [Which time zone do reports use?](#which-time-zone-do-reports-use).
- **Permissions and sharing.** Column families, individual columns, group-by and filter options
  are each permission-gated, and reports only include entities you can view. A colleague seeing
  different numbers or columns is usually a *role* difference, not a report difference. The
  shipped Publisher and Advertiser roles, for instance, read the Publisher or Advertiser column
  family rather than Base. See [metrics](https://epom.com/ad-server/docs/reference/metrics.md) and
  [dimensions](https://epom.com/ad-server/docs/reference/analytics-dimensions.md).

## Which time zone do reports use?

| Where | Time zone | Can you change it? |
|---|---|---|
| **General** report, dashboards, widgets | The network's **reporting time zone** — one zone for the whole network | No. There is no per-user or per-account setting; General rows are kept per day and hour in that zone |
| **Advanced** report | The **Time zone** you pick on the Filter tab, **UTC** when you pick nothing | Yes, per report |
| Scheduled report e-mails | Sent at the hour you choose, **in UTC** | The data inside follows the report's own type |

To find your network's reporting time zone, call `GET /rest-api/network/settings.do` — the
answer carries `reportingTimeZone` with its `id` and current `utcOffset`. Dashboards show day
labels exactly as stored, without shifting them into your browser's zone.

The Advanced selector offers **fixed UTC offsets** (UTC−12 … UTC+14), not named regions: there is
no daylight-saving switch, so a report that should follow New York time uses UTC−5 in winter and
UTC−4 in summer. Over the API the same choice is the `usersTimeZoneId` parameter with the enum
name — `UTC_0`, `UTC_PLUS_2`, `UTC_MINUS_5` — and an unknown value silently falls back to UTC.

**If you need daily totals in your own time zone** and your network's zone is a different one,
run the numbers as an **Advanced** report with your zone selected, over settled days. A General
report cannot be re-bucketed.

## How far back each report goes (data retention)

- **General** is the long-term store; its **hourly** breakdown covers only the most recent two
  weeks by default, so an hour-by-hour General report for an older period comes back empty.
- **Advanced** and the **raw logs** read the event logs, which are kept only for a short window —
  a few days, set per network (two days by default). An Advanced report for
  "last 30 days" returns only the days still in that window; use **General** for longer periods
  and for invoicing. Some event types (for example clicks or conversions) can be kept longer than
  the rest, so the Clicks Log may reach further back than the Advanced report.
- To keep event-level data longer, use the
  [raw event export](#raw-event-files-in-your-own-storage-s3-google-cloud-storage-sftp) to your own
  storage.

## Which report to trust for what

| You want to… | Use | Because |
|---|---|---|
| Bill, reconcile, close a period | **General**, over yesterday or earlier | It carries the finalization **Status** grouping |
| Explore by browser / OS / device / risk / custom params | **Advanced** | Only it carries those dimensions |
| Audit an individual impression / click / conversion | **Raw logs** | One row per event, with per-event attributes and validity flags |
| Power a dashboard widget or scheduled e-mail | **General** or **Advanced** | Those are the two types widgets and scheduled e-mails run; the raw logs, Header Bidding and Targeting Cookie cannot back one |
| Match a partner's daily totals precisely | **Advanced with the partner's time zone**, over settled days | Only Advanced lets you align the day boundary |
| See which source filled a header-bidding slot | **Header Bidding** | It is the only type with the fill-source split |

> **Note:** for anything financial, prefer **General over yesterday-or-earlier**. It is the
> report that reflects accounting-period status — Advanced and raw logs
> are for analysis, not billing. It is not "fresher" than the others: every type waits for the
> hour to end.

## General vs Advanced vs raw logs: which report counts requests, impressions and no ads

The same word means a slightly different count in each report. Read this table before comparing a
General number with an Advanced one:

| Question | General | Advanced | Raw logs (Impressions / Clicks / Conversions Log) |
|---|---|---|---|
| What is **Requests**? | **Impressions + No-ad answers** for the placement — General has no separate request counter | **Direct requests**: every original ad request the ad server received (repeats are a separate **Repeated requests** column) | No request rows at all — the logs list impressions, clicks and conversions |
| What is an **Impression**? | Counted impressions (invalid ones excluded) | **Impressions** = eligible impressions: deliveries minus rejected (invalid) impressions and matched passbacks | One row per impression event, with a validity filter where the network stores invalid events |
| Where are **no-ad answers**? | Inside Requests (and so inside Fill Rate) | **No ads**, **Returned requests**, **Wasted requests** — see [Advanced report metrics](https://epom.com/ad-server/docs/reference/metrics.md#no-ads-vs-wasted-requests-vs-lost-opportunities) | Not listed |
| **Fill Rate** | impressions ÷ (impressions + no-ad answers) | eligible impressions ÷ direct requests | — |
| Money from a **fixed daily / monthly** price | Spread over the period's impressions (see below) | Not included | Not included |
| City, browser, OS, referer, custom parameters | No | Yes | Per event (IP, user agent, location, referer, custom parameters) |
| How far back | Months and years (hour rows ≈ two weeks) | A few days | A few days |
| Time zone | Network reporting time zone | Your pick on the Filter tab, UTC by default | No selector |

So **General Requests is usually lower than Advanced Direct requests**: a request whose ad was
returned but never rendered — the visitor left, an ad blocker removed it, a third-party tag inside
the ad failed — produces neither an impression nor a no-ad answer, so General never counts it,
while Advanced counted the request the moment it arrived. Advanced is the report to use when the
question is "how many requests did the placement get"; General is the one for "how many
impressions do we bill".

> **Corner case:** General's Requests and Fill Rate exist only on the supply side. Group or filter
> by an advertiser, campaign, banner or conversion action and both columns disappear — a request
> happens before a banner is chosen, so it belongs to no advertiser.

## Fixed daily or monthly price: why Net is spread and missing from the logs

A site or placement priced **Cost per day** or **Cost per month** pays a flat fee, not a price per
impression. The ad server cannot put that fee on any single impression, so:

- **General** spreads the fee over the period's impressions: every day row of the placement gets
  `fee × its impressions ÷ all impressions of the day (or month)` as Net, so the period's Net adds
  up to the fee. The spreading runs several times a day for today and this month, re-runs for
  yesterday after midnight, and settles last month on the 1st — so the per-day Net of the current
  month keeps shifting until the month is over.
- **Hour rows** are not spread — an Hour breakdown of such a placement shows no fee.
- **Advanced** and the **raw logs** carry no share of the fee at all: an exported Impressions Log
  shows those impressions with no Net. This is expected, not lost revenue — invoice from General.

## Raw event files in your own storage (S3, Google Cloud Storage, SFTP)

Besides the Impressions / Clicks / Conversions Log reports, Epom can switch on a
**raw event export** for your network: every hourly event file the ad servers write is also uploaded, as gzipped
Parquet, to a bucket you own — Amazon S3, Google Cloud Storage or an SFTP server. Files land under
`stream=<stream name>/t=<event type>/dt=<YYYY-MM-DD>/h=<hour>/`, one file per ad server per hour.
The export is set up by Epom support (bucket, credentials, which stream); there is no self-serve
page for it, so send the storage details to support. It includes the same per-event fields as the log reports — IP, user agent, location,
referer, custom parameters, entity ids, money — and is the way to keep event-level data longer
than the few days the log reports keep.

> **Corner case:** an upload to your bucket that fails is retried by the ad server itself, once
> an hour, from the copy on the analytics cluster — so a missing hour normally appears within the
> next hour. That copy is kept only for the cluster's retention window (often three days); a gap
> older than that cannot be re-sent. To re-send an hour on demand while it is still inside that
> window, ask Epom support or your account manager.

## Related

- [Report types — freshness and gating](https://epom.com/ad-server/docs/guides/analytics/report-types.md)
- [Analytics dimensions reference](https://epom.com/ad-server/docs/reference/analytics-dimensions.md)
- [Analytics metrics reference](https://epom.com/ad-server/docs/reference/metrics.md)
- [Analytics discrepancies — the checklist](https://epom.com/ad-server/docs/troubleshooting/analytics-discrepancies.md)