End-user privacy is at the core of everything that Ads Data Hub does; it's
the foundation that our platform is built upon. In order to help maintain that
privacy and help our customers with regulatory compliance, we impose certain
checks and restrictions, designed to help prevent the transmission of data about
individual users^[1](https://developers.google.com/ads-data-hub/guides/privacy-checks#fn1)^ in the data that you get out of the platform.

> [!IMPORTANT]
> **Key Term:** **Filtered rows** are rows omitted from results due to privacy restrictions.

Here is an overview of Ads Data Hub's privacy features, with more detail
in the sections that follow:

- **Static checks** examine the statements in your queries to look for obvious and immediate privacy concerns.
- **Data access budgets** limit the total number of times that you can access a given piece of data.
- **Aggregation checks** ensure that every row contains a large enough number of users to protect end-user privacy.
- **Noise injection** adds precisely calibrated random noise to an aggregating `SELECT` clause to protect user privacy while providing reasonably accurate results.
- **Difference checks** (or "diff checks") is a legacy alternative to noise injection that compares result sets to help prevent combinations that could identify individual users. This avoids noise but often leads to significant and unpredictable data redaction.

> [!NOTE]
> **Note:** Whenever possible, use [sandbox data](https://developers.google.com/ads-data-hub/guides/sandbox) to iterate on and test queries. Jobs using sandbox data don't contribute to privacy history.

[Video](https://www.youtube.com/watch?v=mDy5Bry0bRs)

## Static checks

Static checks examine the statements in your queries to look for obvious and
immediate privacy concerns, such as exporting user identifiers, any function of
user identifiers, or using disallowed functions over fields that contain
user-level data. To avoid query errors from static checks, review the
[best practices](https://developers.google.com/ads-data-hub/guides/best-practices) and understand
[which functions are allowed](https://developers.google.com/ads-data-hub/reference/allowed-functions).

## Data access budget

Your data access budget limits the total number of times that you can access a
given piece of data. Users approaching the end of their budget will be notified
with a [privacy message](https://developers.google.com/ads-data-hub/reference/rest/v1/QueryResponse) with
type `DATA_ACCESS_BUDGET_IS_NEARLY_EXHAUSTED`. You may monitor the budget using
the [data access budget](https://developers.google.com/ads-data-hub/reference/rest/v1/customers.adsDataCustomers/getDataAccessBudget) entry point
or by observing budget notifications in the UI.

## Aggregation requirements

At the core of Ads Data Hub's privacy checks is the user aggregation
threshold. The specific threshold depends on privacy mode and accessed data:

- Noise injection requires approximately 20 unique users per result row.
- Difference checks require approximately 50 unique users per result row.
- Queries of only click and conversion data require approximately 10 unique users per result row.

> [!NOTE]
> **Note:** events with zeroed or null user IDs don't count toward the aggregation threshold.

In the following example (using noise injection), the row containing campaign
125 would be filtered from the final results, because it aggregates results from
18 users, which is below the 20-user minimum.

| Campaign ID | Users | Impressions |
|---|---|---|
| 123 | 314 | 928 |
| 124 | 2718 | 5772 |
| *125* | *18* | *45* |

## Privacy modes

> [!WARNING]
> **Warning:** As per the [Ads Data Hub policies](https://developers.google.com/ads-data-hub/resources/policies), don't attempt to disaggregate data to disambiguate sets of users that don't meet our aggregation requirements.

Ads Data Hub offers two privacy modes---*noise injection* and *difference
checks*. See the following pages for details on each mode:

- [Noise injection](https://developers.google.com/ads-data-hub/guides/noise-injection) (Recommended)
- [Difference checks](https://developers.google.com/ads-data-hub/guides/legacy-diff-checks) (Legacy)

### Compare difference checks to noise injection

In difference checks mode, rows are filtered if they don't meet the
50-user aggregation requirement or if they trigger difference check violations.

In noise injection mode, rows are only filtered if they don't meet the
aggregation requirement (approximately 20 users for impression data), and random
noise is added to the aggregate results.

> [!NOTE]
> **Note:** noised `COUNT` results are returned as non-negative integers.

Actual data Campaign ID Impression count 101 35 102 63 201 142 202 21 301 56 302 99 Results using difference checks Campaign ID Impression count 101 35 102 63 201 142 202 21 301 56 302 99 Results using noise injection Campaign ID Impression count 101 38 102 61 201 182 202 26 301 58 302 98 Example of Campaign 101 in noise mode Campaign ID Actual impressions Noise added Returned impressions (noised `COUNT`) 101 35 2.8373 38

## Explicit privacy filtering

In cases where you need to break your query up but want to combine the
aggregated results, you can explicitly apply privacy checks to several smaller
queries and then aggregate those results together in a privacy-safe way.

Example use cases:

- You are an advertiser looking for all conversions by attribution event type in your linked Google Ads account, which includes EEA data.
- You are a measurement partner looking for all conversions by attribution event type in your linked Google Ads account.

To get the sum of conversions for your Google Ads account, you can rewrite the
query using an `OPTIONS(privacy_checked_export=TRUE)` clause to apply privacy
checks to each Google service individually.

The example rewrite in this section does the following:

1. It queries each Google service individually, explicitly applying privacy checks to each intermediate results set.
2. It creates a separate [temp table](https://developers.google.com/ads-data-hub/guides/create-tables#temporary_tables) for the privacy-checked results of each Google service: YouTube, Gmail, and Network.
3. It aggregates and sums the privacy-checked conversion counts from the temp tables.

    CREATE TEMP TABLE youtube_agg OPTIONS(privacy_checked_export=TRUE) AS
    SELECT
     impression_data.campaign_id,
     attribution_event_type,
     COUNT(1) AS num_convs
    FROM adh.google_ads_conversions_policy_isolated_youtube
    WHERE impression_data.campaign_id IN UNNEST(@campaign_ids)
     AND conversion_type IN UNNEST(@conversion_type_list)
    GROUP BY campaign_id, attribution_event_type;

    CREATE TEMP TABLE network_agg OPTIONS(privacy_checked_export=TRUE) AS
    SELECT
     impression_data.campaign_id,
     attribution_event_type,
     COUNT(1) AS num_convs
    FROM adh.google_ads_conversions_policy_isolated_network
    WHERE impression_data.campaign_id IN UNNEST(@campaign_ids)
     AND conversion_type IN UNNEST(@conversion_type_list)
    GROUP BY campaign_id, attribution_event_type;

    CREATE TEMP TABLE gmail_agg OPTIONS(privacy_checked_export=TRUE) AS
    SELECT
     impression_data.campaign_id,
     attribution_event_type,
     COUNT(1) AS num_convs
    FROM adh.google_ads_conversions_policy_isolated_gmail
    WHERE impression_data.campaign_id IN UNNEST(@campaign_ids)
     AND conversion_type IN UNNEST(@conversion_type_list)
    GROUP BY campaign_id, attribution_event_type;

    SELECT
     campaign_id,
     attribution_event_type,
     SUM(num_convs) AS num_convs
    FROM (
     SELECT * FROM youtube_agg
     UNION ALL
     SELECT * FROM network_agg
     UNION ALL
     SELECT * FROM gmail_agg
    )
    GROUP BY campaign_id, attribution_event_type

Note that this query does not use a `JOIN` to directly combine data between the
tables, but instead performs the query for each table first, applies privacy
checks to each intermediate table, then uses a `UNION` to sum the
privacy-checked values.

## Query advisor

If your SQL is valid but might trigger privacy issues, the **query advisor**
surfaces actionable advice during the query development process, to help you
avoid undesirable results.

To use the query advisor:

- **UI**. Recommendations will be surfaced in the query editor, above the query text.
- **API** . Use the [`customers.analysisQueries.validate`](https://developers.google.com/ads-data-hub/reference/rest/v1/customers.analysisQueries/validate) method.

*** ** * ** ***

1. Other than data they have consented to share, such as in the case of panelists. [↩](https://developers.google.com/ads-data-hub/guides/privacy-checks#fnref1)