This guide explains why rows with zero metrics appear in Google Ads API reports and how
to exclude or handle them in your queries.

## Zero metrics in search results

When you execute a query, you may encounter metrics for entities that are zero.
This could be because:

- The entities are ineligible for display.
- They were paused within the report's date range.

With query results, you often want to obtain information about how your
campaigns are performing. In this context, zero metrics may not be desirable. To
produce a more useful report, you can explicitly exclude zero metrics.

## Exclude zero metrics with a predicate

A predicate is an expression that evaluates to `TRUE`, `FALSE`, or `UNKNOWN`.
Predicates are used in the search condition of the `WHERE` clauses in
[Google Ads Query Language](https://developers.google.com/google-ads/api/docs/query/structure).

The following query demonstrates how to explicitly remove zero metrics with a
predicate:

    SELECT
      campaign.id,
      metrics.impressions
    FROM campaign
    WHERE metrics.impressions > 0

## Exclude zero metrics by segmenting

Zero metrics are always excluded when segmenting a report, provided all
*selected* metrics are zero (see
[Returned rows with zero metrics](https://developers.google.com/google-ads/api/docs/reporting/zero-metrics#rows_returned)).

Segmenting a report is done by including any `segments` field in the `SELECT`
clause of the search query (filtering on a core date segment in `WHERE` without
selecting it in `SELECT` does not segment the report). For example, if you
segment a report by `segments.date`, metrics are broken down with one row for
each date. Dates with no metrics are not returned in such a report.

For the following query, the report won't include zero-metric rows:

    SELECT
      campaign.name,
      metrics.impressions,
      segments.date
    FROM campaign
    WHERE segments.date DURING LAST_30_DAYS

## Returned rows with zero metrics

Rows whose selected metrics are all zero won't be returned when segmenting. For
example, consider the following query that selects `metrics.impressions`,
`metrics.clicks`, and `metrics.conversions`:

    SELECT
      ad_group_criterion.criterion_id,
      metrics.impressions,
      metrics.clicks,
      metrics.conversions,
      segments.date
    FROM keyword_view
    WHERE segments.date BETWEEN '2026-01-01' AND '2026-01-31'

The resulting report won't contain any rows in which all three selected metrics
are zero, but it will return rows where at least one of the three selected
metrics is greater than zero.

When querying historical data beyond the
[data retention period](https://ads-developers.googleblog.com/2026/05/new-data-retention-policy-for-google.html), granular data older than 37 months is
unavailable and won't return rows. Requests for granular date segments
(`segments.date`, `segments.week`, and `segments.hour`) covering ranges older
than 37 months return `DateRangeError.REQUESTED_DATE_GRANULARITY_NOT_SUPPORTED`
in v24 and later (or `DateRangeError.UNKNOWN` in v23). High-level aggregated
data (`segments.month`, `segments.quarter`, and `segments.year`) is retained for
11 years, aligned to the start of the next complete calendar period. For
example, if the 11-year lookback cutoff falls on `2015-03-22` (or `2015-03-01`),
monthly data is available starting from the first full calendar month after the
cutoff (`2015-04-01`). See [Date Ranges](https://developers.google.com/google-ads/api/docs/query/date-ranges#lookback-limits) for details.

## Reach metric suppression and zero values

In addition to entities that didn't serve impressions, reach metrics (such as
[`metrics.unique_users`](https://developers.google.com/google-ads/api/fields/v26/metrics#metrics.unique_users) and frequency bucket metrics
`metrics.unique_users_two_plus` through `metrics.unique_users_ten_plus`) can
appear as zero or be omitted when reach data is suppressed. The
`metrics.unique_users` metric (and `metrics.unique_users_info`) is supported on
Display, Video, Demand Gen, and App campaigns, whereas the
`metrics.unique_users_*_plus` frequency bucket metrics (and
`metrics.unique_users_*_plus_info`) apply to Video campaigns.

Reach suppression happens for several reasons:

- **Privacy thresholds**: Reach data is suppressed when user counts don't meet privacy thresholds (such as k-anonymity) to protect user identity.
- **Quality thresholds**: Reach data may be withheld if the data doesn't meet quality standards.
- **Data retention** : Historical reach data is retained for 3 years (36 months). Queries spanning dates beyond this 3-year retention window can't return reach metrics. While queries covering dates between 36 and 37 months ago succeed without returning `DateRangeError.REQUESTED_DATE_GRANULARITY_NOT_SUPPORTED` described in the preceding section, they omit reach metrics (and return `DATE_RANGE_BEYOND_RETENTION` when companion reach metadata is selected).

In v26 and later, each unique user reach metric has a companion metadata field
of type [`ReachMetricInfo`](https://developers.google.com/google-ads/api/reference/rpc/v26/ReachMetricInfo) (such as
[`metrics.unique_users_info`](https://developers.google.com/google-ads/api/reference/rpc/v26/Metrics#unique_users_info) and
`metrics.unique_users_two_plus_info` through
`metrics.unique_users_ten_plus_info`).

In Google Ads Query Language (GAQL), companion reach fields are `MESSAGE` metrics selected
directly in the `SELECT` clause (for example, `metrics.unique_users_info`).
Don't append `.reach_metric_states` in the `SELECT` clause, because selecting
nested message fields in GAQL fails with `UNRECOGNIZED_FIELD`. Instead,
selecting `metrics.unique_users_info` returns a
[`ReachMetricInfo`](https://developers.google.com/google-ads/api/reference/rpc/v26/ReachMetricInfo) message containing the repeated enum
field `reach_metric_states` of type [`ReachMetricState`](https://developers.google.com/google-ads/api/reference/rpc/v26/ReachMetricStateEnum.ReachMetricState),
which describes whether the metric was suppressed or is complete.

Whenever a reach metric is suppressed or outside the retention window
(`PRIVACY_SUPPRESSION`, `QUALITY_SUPPRESSION`, or
`DATE_RANGE_BEYOND_RETENTION`), its `optional int64` field on `Metrics` is
unset (which evaluates to `0` if field presence isn't checked), whereas
`LOW_QUALITY` still populates the numeric metric:

- `COMPLETE`: The reach metric is complete with no suppression.
- `PRIVACY_SUPPRESSION`: Reach data was suppressed due to privacy constraints.
- `QUALITY_SUPPRESSION`: Reach data was suppressed due to data quality reasons.
- `LOW_QUALITY`: The reach metric was calculated but is flagged as low quality.
- `DATE_RANGE_BEYOND_RETENTION`: Reach metrics are unavailable because the date range falls outside the 3-year data retention limit for reach data.

By selecting both the reach metric and its companion metadata field, your
application can distinguish between genuine zero reach and reach values that
were suppressed:

    SELECT
      campaign.id,
      campaign.name,
      metrics.unique_users,
      metrics.unique_users_info,
      metrics.unique_users_two_plus,
      metrics.unique_users_two_plus_info,
      metrics.unique_users_ten_plus,
      metrics.unique_users_ten_plus_info
    FROM campaign
    WHERE campaign.advertising_channel_type = 'VIDEO'
      AND segments.date DURING LAST_30_DAYS

> [!NOTE]
> **Note:** Companion reach metadata fields (`metrics.unique_users*_info`) are `MESSAGE` metrics with `filterable: false` and `sortable: false`, so they can't be used in `WHERE` or `ORDER BY` clauses. In addition, reach metrics can't be aggregated across rows. The `metrics.unique_users` metric can only be requested for date ranges of 92 days or less, while `unique_users_*_plus` frequency bucket metrics can only be requested for date ranges of 31 days or less. See [Campaign
> reach and frequency reporting](https://developers.google.com/google-ads/api/docs/video/overview#campaign-reach-reporting) for the full list of Video reach and frequency metrics.