---
id: agencias/recortes-de-publico
industry: Marketing agencies
usage: common
effort: low
grain: Ad x day x breakdown type x value (long format)
---

# Audience breakdowns

Each client's age, gender, placement, device and region, showing who converts without adding up what does not add up.

## Executive summary

**For:** Agencies that need to show the client who saw, who clicked and who converted.

**What it solves**

- Each breakdown is read on its own and never added to another.
- The client knows how much of the budget the breakdown covers before drawing conclusions.
- Region, age and placement have the same names on Meta and Google.

**Why it matters:** Audience breakdowns are where the client makes targeting decisions, and where it is easiest to get the total wrong. The same spend shows up by age, by gender and by region, and Google does not publish demographics for Performance Max. Adding wrong or ignoring the unattributed part leads to cutting the audience that sells most.

**Business questions it answers**

- Which age range has the lowest cost per lead?
- Which states do conversions come from?
- Reels, feed or stories: where does the ad perform best?
- Mobile or desktop: where do leads convert more?
- How much of the budget has no identified age or gender?

**What you need**

- Meta and Google breakdown reports connected per client
- The portfolio's media table, which is the reference for the total
- Google's location names table to translate the codes

**What you get**

- A long-format table, one breakdown type at a time, with budget coverage
- Cost per result by age range, gender, placement and region
- A coverage badge on every breakdown chart
- An AI agent that reads one breakdown at a time

## Detailed

### The problem

Platforms split the same spend by age, by gender, by placement and by region. Whoever stacks the breakdowns in one table and sums everything multiplies the budget. On Google, Performance Max does not publish age or gender, so the breakdown covers only part of the spend, and the largest range is often the unidentified one.

### Business rules

1. **One breakdown type at a time.** Store breakdowns in long format (ad, day, breakdown type, value) and always filter one type. Within a type the sum closes; across types, the same spend appears several times. In a real base, summing every row gave about four times the spend. (Avoid: Grouping by type and value and summing the total.)
2. **The total comes from the media table.** The client's total spend comes from the daily campaign performance table. Breakdowns answer relative composition. Every reading shows coverage: breakdown spend / total spend for the same period and accounts. (Avoid: Using the age breakdown sum as the client's spend.)
3. **Performance Max has no demographics.** On Google, Performance Max does not publish age or gender: breakdown coverage is 100% minus the PMax share, and in accounts heavy on PMax it fell below 30%. Do not work around it by prorating PMax spend across ranges: say the reading applies only to spend outside PMax. (Avoid: Distributing PMax proportionally across ranges.)
4. **Unidentified is not an audience.** AGE_RANGE_UNDETERMINED, UNDETERMINED and unknown are the part the platform could not attribute. On Google, the unidentified range can be larger than the largest real range. Show it separately and compute range shares over the identified total and over the full total, labeling each. (Avoid: Saying the audience is 25-34 without separating unidentified.)
5. **Reach stays out.** Reach is not additive across ads, days or ranges. Breakdown tables carry only additive measures: spend, impressions, clicks, link clicks, leads, purchases and purchase value. Rates are computed at read time from the sums. (Avoid: Summing reach by age range for the month.)
6. **Location has two meanings.** On Google, the location type separates where the person was (presence) from the place they showed interest in. Both split the same spend and, added together, exceed the real spend. Treat them as different breakdown types. (Avoid: Adding presence and interest.)
7. **A place name is not a key.** On Google, criteria_id becomes a name through the geo targets table; the same city name exists with different IDs, and a region is not always a state. On Meta, the region comes with suffixes like (state): normalize before matching with Google. Store the code and the label. (Avoid: Joining Meta and Google by city name.)
8. **Result by objective in the breakdown too.** Cost per result by range uses the same action_type of the ad set objective as the main table. A reach campaign breakdown has no cost per lead. A range with few results is not a conclusion: show volume next to the rate and a declared minimum. (Avoid: Cost per lead by range adding leads from every objective.)
9. **Placement is platform plus position.** On Meta, the real placement is publisher_platform plus platform_position (Instagram Reels, Facebook Feed, Stories). Device (impression_device) is another breakdown type. Do not mix the two on the same axis. (Avoid: Comparing feed with mobile on the same chart.)

### Breakdown types and coverage

Where each breakdown comes from and whether it closes with total spend.

- **Meta · age and gender** → Closes with the total (`adsinsights_by_age_and_gender`)
- **Meta · platform and position** → Placement (`publisher_platform + platform_position`)
- **Meta · device** → Mobile, desktop (`impression_device`)
- **Meta · region and country** → Region, normalize suffixes (`adsinsights_by_region, adsinsights_by_country`)
- **Google · age and gender** → No Performance Max (`age_range_performance, gender_performance`)
- **Google · location** → Presence and interest separate (`user_location_performance + geo targets`)
- **UNDETERMINED, unknown** → Unidentified (`own row`)
- **reach** → Out of breakdown tables (`not additive`)

### Definitions

| Metric | Definition |
|---|---|
| Breakdown spend | sum of spend for the rows of one breakdown type and one value, in the period |
| Share | value spend / breakdown type spend, same client, accounts and period |
| Identified share | value spend / type spend excluding unidentified |
| Coverage | breakdown type spend / total spend in the media table, same accounts and period |
| Breakdown cost per result | value spend / objective result for that value, in the period |
| Breakdown CTR | sum of link clicks / sum of impressions for the value |

### Pitfalls

- **Four times the budget.** Summing every row of the segments table, without filtering the type, gave about four times the real spend. How to avoid: Filter one breakdown type at a time.
- **Total below the account.** Google's age report was used as the client's total and came in well below the account, because Performance Max is not in it. How to avoid: Total from the media table, coverage alongside.
- **The biggest audience was nobody.** The unidentified age range had more spend than the 25-34 range, which the report presented as the main audience. How to avoid: Unidentified on its own row.
- **States that did not match.** Meta returned the state with a suffix and Google without it, and the regional comparison left half the states unpaired. How to avoid: Normalize labels and use the code as key.
- **Presence plus interest.** Adding Google's two location types gave more spend than the account actually had. How to avoid: Treat presence and interest as separate breakdowns.

Validated on real data: In Nekt's own Meta Ads account, the age and gender and the region reports close with the main table's spend for closed months, within cents, and unknown age or gender stays below 1% of spend. The coverage gap is a Google Performance Max issue, not a Meta one.

### Acceptance test

- [ ] Within each breakdown type, spend is equal to or lower than the media table total for the same accounts and period, and coverage shows on every reading.
- [ ] No query sums rows from different breakdown types.
- [ ] On Meta, each breakdown type for a closed month closes with total spend (difference below 0.1%).
- [ ] On Google, age breakdown coverage equals 100% minus Performance Max's share of the account's spend.
- [ ] Unidentified appears as its own row in age and gender.

### Context document

```text
Audience breakdowns
- Breakdowns are in long format. Always filter one breakdown type; never sum across types.
- The client's total spend comes from the media table, not from breakdowns. Show breakdown coverage.
- Google: Performance Max has no age or gender. The reading applies only to spend outside PMax.
- Unidentified (UNDETERMINED, AGE_RANGE_UNDETERMINED, unknown) is its own row, not an audience.
- Reach is not in the breakdowns. Rates are recomputed from sums.
- Google location: presence and interest are different breakdowns. The location code is the key; the name is a label.
- Result by breakdown uses the ad set objective's result. Show volume next to the rate and do not conclude with fewer than <n> results.
Per-client exceptions:
- <client>: regions of interest <list>; other regions grouped as Other.
- <client>: account <id> with <x>% in Performance Max; demographic breakdown only for the rest.
- <client>: target audience is the <range> range; highlight it.
```

### Variations

- **Lead breakdown:** Assign age, gender and platform to the form lead by matching entry order within the same ad and day.
- **Site and e-commerce:** Apply GA4 shares by device, city and age to the official order and revenue totals.
- **Hour of day:** The hourly report shows when leads arrive, to schedule ads and customer service.
