Skip to content
Fraud Prevention

Google Ads IP Exclusion Limit: The 500 Cap, CIDR, and What It Can't Block

22 min readGeoIPHub Team

You have a click log. A handful of addresses keep coming back, the exclusion box holds 500, and you are wondering what happens when it fills. Search for the limit and nearly every page that answers you is a click-fraud vendor, and nearly every answer ends the same way: our tool rotates the list for you.

We think that is the wrong question. Google's own API documentation counts the limit in "IP blocks", so one entry can cover a whole range, and the useful question becomes which ranges earn a slot. Our position is simple. An exclusion list is for stable nuisances, such as your own office or a hosting block that keeps showing up, not for fraud. Google says it already filters invalid clicks on its side, and we quote that page near the end.

Below we give both limits in Google's own words, show how to enter a range in the interface and as CIDR through the API, run six real addresses through our API to decide which ones deserve a slot, and list what no exclusion can stop. For the wider case for scoring each click instead of banning it, start with our click fraud guide.

Isometric illustration of click traffic flowing past a small gate of exclusion slots into a scoring stage
An exclusion list has 500 slots; everything else has to be scored at click time.

You can exclude 500 IP entries per campaign and 500 per account. The two numbers live on different Google pages, which is why so many write-ups get the second one wrong.

We opened every Google page quoted in this post at 06:12 UTC on 14 October 2026. The campaign cap is on Google's help page, Exclude IP addresses:

"You can exclude up to 500 IP addresses per campaign."

The help page gives no number for the account level. The account cap is in the Google Ads API reference for CustomerNegativeCriterion, the resource that holds account-level exclusions. Its ip_block field reads: "Immutable. IpBlock. You can exclude up to 500 IP addresses per account." Some ranking pages miss this. Lunio's post on the 500 limit, which we opened at the same time, says "The 500 IP exclusion limit applies per campaign, not per account." Google's reference says the account list has its own cap of 500.

The unit matters more than the number. Google's API system limits table lists the row as "Excluded IP blocks per campaign", value "500", error ResourceCountLimitExceededError.CAMPAIGN_LIMIT. One criterion is created per address or per CIDR block, so in Google's API documentation a /24 entered once is one entry. We have not tested this in a live account. That is why we call them 500 slots, not 500 addresses.

When both levels hold entries, Google's help page says the lists merge:

"If you have IP exclusions set up at both the account level and the campaign level under the same CID: Google Ads will merge the exclusion lists. This means all the IP addresses excluded at either level will be blocked from viewing your ads for that campaign."

Google's own example: "Imagine you exclude IP addresses 1, 2, and 3 at the campaign level (Campaign A). Then, you exclude IP addresses 4, and 5 at the account level. For the campaign you set up (Campaign A), Google Ads will effectively block IP addresses 1, 2, 3, 4, and 5." Google says nothing more about how the two caps interact, so neither do we.

LevelCapWhere Google says itCovers
Campaign500Help page 2456098; API CampaignCriterion.ip_blockOne campaign, and not every campaign type
Account500API CustomerNegativeCriterion.ip_block onlyAll campaigns in the account, Performance Max included
Both setLists merge per campaignHelp page 2456098Each campaign blocks its own entries plus the account's

Account level or campaign level: where to add IP exclusions

Add an exclusion at the account level when it should apply everywhere, and at the campaign level only when one campaign has its own problem. Google's own example of a good exclusion is your own staff: "you decide to exclude your company's network IP address." That address belongs at the account level.

These are Google's steps for the account level, from the same help page:

  1. In your Google Ads account, click the Admin icon.
  2. Click Account settings.
  3. Go to the "IP exclusions" section.
  4. Enter the IP addresses you want to exclude from seeing your ads.
  5. Click Save.

And for one campaign:

  1. In your Google Ads account, click the Campaigns icon.
  2. Click the Campaigns drop down in the section menu.
  3. Click Campaigns, then Settings.
  4. Select the campaign you'd like to exclude IP addresses from.
  5. On the "Settings" page, click Additional settings.
  6. Expand the "IP exclusions" section, enter the addresses and click Save.

Removing an entry uses the same path at either level. Google's instructions are to follow the steps above, "Remove any IP address exclusions that you don't want to apply," and click Save. One trap: "You cannot edit or remove account level exclusions from within the individual campaigns." If an entry seems stuck in a campaign, look in Account settings.

Good account-level entries are your office, your agency's office, and a confirmed hosting block that keeps clicking. A competitor's fixed office range is a fair campaign-level slot too. If your real goal is geography, Google points you elsewhere: "If you're trying to prevent your ads from showing in certain geographical locations, try excluding ads from a geographic location instead of excluding IP addresses."

Which campaign types can't use campaign-level IP exclusions?

Video, hotel, App, Performance Max and Smart Display campaigns can't take campaign-level IP exclusions. Google's help page puts it in one note:

"Note: IP exclusions aren't available for video campaigns, hotel campaigns, App campaigns, Performance Max campaigns, and Smart Display campaigns."

The account level reaches further. Google says you can use it "to exclude specific IP addresses from seeing your ads across all campaigns in your account including Performance Max, Demand Gen, Search, Shopping, Display, Discover, and YouTube." So Performance Max takes IP exclusions only at the account level, and that list is the same 500 entries every other campaign shares.

Campaign typeCampaign-level exclusionsAccount-level exclusions
Search, Shopping, DisplayAvailableNamed by Google
Performance MaxNot availableNamed by Google
VideoNot availableGoogle names YouTube
Hotel, App, Smart DisplayNot availableNot stated on the page
Demand GenNot in Google's unsupported listNamed by Google

Vendor pages disagree about this list, partly because Google's own pages differ. The older Search Ads 360 help page names video, App, Smart Display and Discovery campaigns. We use the five from the current Google Ads page only.

How to exclude an IP range: the asterisk, CIDR and IPv6

In the interface, the documented range form is an asterisk on the last octet. Through the API, any IPv4 or IPv6 CIDR block is one entry.

Google's help page says "You can enter specific IP addresses, or use an asterisk (*) to replace the last 3 digits if you want to exclude a block of addresses." The last three digits means the last octet: 198.51.100.* covers 256 addresses, the same as a /24. Google documents one asterisk in that position and nothing else. Forms with two asterisks, or an asterisk at the front, appear on some ranking pages, but Google documents no such syntax, so don't rely on them.

The API is more flexible. Google's IpBlockInfo reference says: "We support excluding individual IP addresses or CIDR blocks. Create one IpBlockInfo criterion for each individual IP address or CIDR block you want to exclude." Its examples are 192.168.0.0/24 and a single address as 192.168.0.1/32 for IPv4, and 2001:db8::/48 and 2001:db8:a0b:12f0::1/128 for IPv6.

The interface documents single addresses and the asterisk. CIDR and IPv6 blocks are documented for the API. We have not tested what the interface does with a CIDR or IPv6 entry, so we won't tell you it works.

The slot arithmetic is where CIDR pays. Take a range from 194.83.41.0 to 194.83.47.255, the example a UK agency uses on WebSuccess Insights. We ran it through Python's ipaddress.summarize_address_range:

What you typeWhereAddresses coveredEntries used
194.83.41.* to 194.83.47.*, one row per /24Interface1,7927
194.83.41.0/24, 194.83.42.0/23, 194.83.44.0/22API1,7923
2001:db8::/48API65,536 /64 subnets1

Google's IPv6 example is a /48, which holds 65,536 /64 subnets. A single device's network is usually one /64, while ISPs commonly hand a home a /56 or a /48, so a /48 entry can cover a whole customer site. We explain what a /48 covers compared with a /64 in our IPv6 post.

Google adds one more line: "IP addresses can appear in different versions, so make sure you use all versions of the IP address you’d like to exclude." Read that as: an office or server with both an IPv4 and an IPv6 address needs both entries.

Adding IP exclusions in bulk through the Google Ads API

Through the API, a campaign exclusion is a negative CampaignCriterion with an ip_block, and an account exclusion is a CustomerNegativeCriterion with an ip_block. Google's criteria table lists IP block as excludable only, at the campaign and customer levels.

Before you push anything, shrink the list. This script turns candidate addresses and blocks into the fewest CIDR entries that cover them, busiest first, capped at 500. It is the exact code we ran on 14 October, on Python 3.9.6, standard library only:

GeoIPHub API
"""Turn candidate IPs and CIDR blocks into a Google Ads exclusion list of at most 500 entries. Input: one entry per line, an IPv4/IPv6 address or a CIDR block (for example the registered block you looked up in RDAP), optionally followed by a click count. Output: the fewest CIDR entries that cover every input, busiest first, capped at 500. """ import ipaddress import sys GOOGLE_ADS_LIMIT = 500 # per campaign, and per account, in Google's API reference def build_exclusions(lines, limit=GOOGLE_ADS_LIMIT): clicks = {} for line in lines: line = line.split("#", 1)[0].strip() if not line: continue parts = line.split() net = ipaddress.ip_network(parts[0], strict=False) # 1.2.3.4 -> 1.2.3.4/32 clicks[net] = clicks.get(net, 0) + (int(parts[1]) if len(parts) > 1 else 1) merged = [] for version in (4, 6): # collapse_addresses refuses to mix IPv4 and IPv6 nets = [n for n in clicks if n.version == version] merged += ipaddress.collapse_addresses(nets) # Credit each merged entry with the clicks of everything it now covers. totals = {m: sum(c for n, c in clicks.items() if n.version == m.version and n.subnet_of(m)) for m in merged} ranked = sorted(merged, key=lambda m: totals[m], reverse=True) return ranked[:limit], ranked[limit:], totals if __name__ == "__main__": keep, dropped, totals = build_exclusions(sys.stdin) for net in keep: print(f"{net}\tclicks={totals[net]}") print(f"# {len(keep)} entries kept, {len(dropped)} over the limit", file=sys.stderr)

We have no real click logs to publish, so we fed it a synthetic sample built only from documentation address ranges. These are not real clicks and were never looked up:

GeoIPHub API
# SYNTHETIC sample: documentation ranges (RFC 5737, RFC 3849), not real clicks 198.51.100.7 3 198.51.100.0/25 12 # a registered block you looked up 198.51.100.128/25 9 # its neighbour: merges with the line above into one /24 203.0.113.10 2 203.0.113.11 2 # adjacent to .10: the two merge into one /31 192.0.2.200 1 2001:db8::42 4 2001:db8::/48 6 # covers the address above

Running python3 -I build_exclusions.py < synthetic_clicks.txt printed:

GeoIPHub API
198.51.100.0/24 clicks=24 2001:db8::/48 clicks=10 203.0.113.10/31 clicks=4 192.0.2.200/32 clicks=1 # 4 entries kept, 0 over the limit

Eight lines became four entries. We also fed it 600 non-adjacent synthetic /32s from 198.18.0.0/15, and it kept the 500 busiest and reported 100 over the limit.

Three things the script deliberately does not do:

  • It never widens an address. collapse_addresses merges only blocks that touch or overlap. Turning one address into its /24 is a decision you make after an RDAP lookup, not something code should guess.
  • It doesn't care about interface syntax. A /31 or a /48 is fine for the API. In the interface you would type the /31 as two addresses, and Google documents no IPv6 range form there.
  • It doesn't filter shared addresses. Run it only after the rule in the next sections has removed relay and carrier NAT addresses.

It also never calls our API. If you add a lookup step, it is one GET per address with the IP in the path and your key in the x-api-key header, as the API reference shows. There is no batch call. From Python's urllib, set an explicit User-Agent, because our API currently returns 403 to urllib's default one.

Pushing an entry looks like this. We wrote it from Google's IpBlockInfo and CampaignCriterion reference, which showed v25 on 14 October, using the Python client library's naming. We did not run it against a live account.

GeoIPHub API
# Written from Google's IpBlockInfo and CampaignCriterion reference (v25); not run against a live account. operation = client.get_type("CampaignCriterionOperation") criterion = operation.create criterion.campaign = client.get_service("CampaignService").campaign_path(customer_id, campaign_id) criterion.negative = True # IP blocks can only be excluded criterion.ip_block.ip_address = "198.51.100.0/24" # one CIDR block = one criterion client.get_service("CampaignCriterionService").mutate_campaign_criteria( customer_id=customer_id, operations=[operation] ) # Account level: CustomerNegativeCriterionOperation, criterion.ip_block.ip_address, # CustomerNegativeCriterionService.mutate_customer_negative_criteria. # At 501 campaign entries the API returns ResourceCountLimitExceededError.CAMPAIGN_LIMIT.

Google documents the error for the campaign cap only. We found no documented error code for the account cap, so we don't name one. Google Ads Editor's version 2.11 notes have a heading "Account-level placement and IP exclusions", but we have not tested Editor, so we give no Editor steps.

Why 500 entries can't hold a hosting network

Five hundred entries can't hold a large cloud provider, because Google documents no way to exclude a network by its ASN and a big provider announces thousands of prefixes. We counted at 06:14 UTC on 14 October:

NetworkEntries you would needSource
AS16509 (Amazon)27,319 announced prefixes (21,267 IPv4, 6,052 IPv6)RIPEstat announced-prefixes, window 2026-09-30 to 2026-10-14
AWS published ranges11,336 unique prefixes (7,863 IPv4, 3,473 IPv6)ip-ranges.amazonaws.com, createDate 2026-10-14-03-37-06
AS63949 (Akamai Connected Cloud, formerly Linode)452 (354 IPv4, 98 IPv6)RIPEstat, same window
AS39351 (31173 Services, Mullvad's network)74 (53 IPv4, 21 IPv6)RIPEstat, same window
AS60729 (TORSERVERS-NET)6 (3 IPv4, 3 IPv6)RIPEstat, same window

RIPEstat counts include overlapping more-specific prefixes and anything seen during the two-week window, so treat them as an upper bound on entries, not unique address space. They drift daily. Even so, Amazon alone needs more entries than both of your lists hold together, many times over.

So the hosting question is not "can I exclude the cloud?" You can't. It is "which hosting blocks keep showing up in my own log?" We explain what makes an address a datacenter IP separately. Our API flags hosting from 890 curated hosting ASNs plus official ranges from 10 cloud providers, and you can test one address in the free datacenter IP check.

One caution before you write a rule on that flag. Hosting alone scores low by design: 45.33.32.156 below returns detection.is_hosting: true and a score of 10, allow. For paid clicks, whether hosting traffic should see your ads is your rule to write, not the score's.

Which addresses deserve one of your 500 slots

A slot should go to a stable range that nobody else shares and that you have seen in your own click log. To show what that looks like, we looked up six public addresses at 06:12 UTC on 14 October with an anonymous GET https://api.geoiphub.com/v1/lookup/{ip}. All six returned HTTP 200. None of them clicked anyone's ad. They stand in for the kinds of addresses a click log contains.

Our response has no prefix field, so we took each registered block from RDAP at 06:14 UTC, through rdap.org, which redirected to ARIN and RIPE.

IP, what it isasn / orguser_typeis_hostingis_vpnis_relayis_cgnatScore, actiondetection_methodsRDAP blockSlot?
45.33.32.156, scanme.nmap.org63949 AKAMAI-LINODE-APhostingtruefalsefalsefalse10, allowdatacenter_ip45.33.0.0/17 (LINODE)Only if this block repeats in your click log, as your own ad-traffic rule
185.220.101.1, Tor exit, Hamburg60729 TORSERVERS-NEThostingtruefalsefalsefalse100, blocktor_exit, datacenter_blocklisted, rdns_tor, known_spammer185.220.101.0/27 (ARTIKEL10)Yes: a stable operator block with four independent reasons
45.83.220.7, Mullvad's network, Malmö39351 31173 Services ABhostingtruetrue, "Mullvad (31173 Services)", 85falsefalse46, reviewknown_vpn_server, datacenter_ip45.83.220.0/24No by default: score it at click time
185.213.155.73, Mullvad de-fra-wg-00139351 31173 Services ABhostingtruetrue, "Mullvad", 95falsefalse100, blockknown_vpn_server, wireguard_open, datacenter_with_vpn_proxy, no_ptr_datacenter185.213.155.0/24Possible, but the same operator scored 46 on the row above
104.28.46.99, iCloud Private Relay13335 Cloudflareconsumer_privacy_networkfalsefalsetruefalse9, allowrelay_ip104.16.0.0/12 (CLOUDFLARENET)Never
172.224.226.1, iCloud Private Relay36183 AKAMAI-ASconsumer_privacy_networktruefalsetruefalse24, allowdatacenter_ip, no_ptr_datacenter, relay_ip172.224.0.0/12 (AKAMAI)Never. A relay with is_hosting: true

Two rows need a note. The VPN name on 45.83.220.7 comes from our table of VPN hosting networks at confidence 85, not from Mullvad's own server list, which did not include it when we checked on 13 October. And 104.28.46.99 sits inside Cloudflare's registered /12 but outside the ranges Cloudflare publishes for its own network, so "exclude Cloudflare's block" would cut Apple relay users, not Cloudflare servers.

One address, end to end

Follow 185.220.101.1 from click to entry. With auto-tagging on, Google adds a GCLID to your landing URL, "www.example.com/?gclid=123xyz" in Google's example. Log the client IP next to that gclid on your landing page, because that pairing is what ties an address to a paid click.

Then look the address up. This is a trimmed copy of our 06:12 UTC response, nesting kept, values unedited:

GeoIPHub API
{ "ip": "185.220.101.1", "asn": { "asn": 60729, "org": "TORSERVERS-NET - Stiftung Erneuerbare Freiheit", "user_type": "hosting" }, "whois": { "netname": "ARTIKEL10", "status": "ASSIGNED PA" }, "detection": { "is_vpn": false, "is_tor": true, "is_hosting": true, "is_relay": false, "is_anonymous": true }, "threat": { "is_spammer": true, "is_cgnat": false }, "scoring": { "fraud_score": 100, "recommended_action": "block", "detection_methods": ["tor_exit", "datacenter_blocklisted", "rdns_tor", "known_spammer"] } }

detection.is_tor is true, the score is 100, and four separate methods fired. The response names the registered network but not its size, so we asked RDAP: 185.220.101.0 to 185.220.101.31, a /27. That block becomes one entry, 185.220.101.0/27, through the API. It costs one of 500 slots and covers 32 addresses run by one Tor operator. That is a good trade.

The rule we'd follow

  1. Spend slots only on stable, non-shared ranges you have seen in your own click log: hosting blocks with is_relay: false, and Tor operator blocks.
  2. Never spend a slot on an address with detection.is_relay or threat.is_cgnat true, whatever the score.
  3. Score everything else per click at landing, VPNs included, because one VPN operator scored 46 and 100 on two of its addresses.
  4. Take the block from RDAP or the provider's own range file, not from our response.

The score bands behind those actions are allow up to 25, review up to 50, step_up up to 75 and block above 75. We explain how the fraud score bands work in a separate post, and you can check an address in the free IP fraud score checker before you spend a slot on it.

Never spend a slot on a shared address: carrier NAT and Private Relay

Carrier NAT and iCloud Private Relay addresses carry many real people at once, so excluding one hides your ads from all of them. No score or click count changes that.

Start with Private Relay. Many Apple users share each egress address, and our scoring caps a relay at 60, so a Private Relay IP can never reach block. The trap is in the table above. 172.224.226.1 is on Apple's relay list and still returns detection.is_hosting: true, because it runs in Akamai's data centers. A rule that says "exclude every hosting block" would exclude Apple users. Check is_relay before anything else, as we explain in letting relay and VPN users through.

Carrier NAT is the mobile version of the same problem. We have no safe carrier address to show you, because we never look up or publish consumer addresses, so this part is prose only. threat.is_cgnat marks addresses shared by many carrier subscribers, and our scoring has a carrier NAT cap of 50, so a shared carrier address with nothing else against it stays below step_up. The range in RFC 6598, 100.64.0.0/10, is the carrier's internal side and never appears as a click IP. You will see the carrier's public address instead.

The cost of getting this wrong was written down years ago. RFC 6269 warns that with shared addresses "one user who fails a number of login attempts may block out other users who have not made any previous attempts but who will now fail on their first attempt." Swap login attempts for ad clicks and you have the exclusion problem. Our hub post covers why banning a shared address hits real customers in more depth.

What an IP exclusion can't block

An IP exclusion can't stop every click from an address, can't name a network, and doesn't touch clicks you have already paid for. Google says the first part itself, on Why do I get clicks from excluded IP addresses?:

"When you use the Internet Protocol (IP) exclusion tool, clicks from excluded IP addresses may still appear in your web logs."

It gives three reasons:

  • Rotation. "Some Internet Service Providers continuously rotate users' IP addresses." The ad shows on one address and the click lands from another.
  • Missing data. "Some Google Network sites don't provide IP information, so users with your excluded IP addresses may see your ad on these sites. We can't guarantee there will be no clicks from a particular IP address."
  • Organic clicks. "the referrer URL for a click on both the organic Google search results and an ad will be the same. Because IP exclusion is only applicable to ads, it's possible that the click that you're seeing actually originated from our search results."

And then the sentence that shapes our whole position:

"Google automatically and proactively filters invalid clicks from your account. You don't have to do anything in order to receive this protection. However, you can use the IP address exclusion tool to gain additional control over the placement of your ads."

Placement control, in Google's words, not fraud defence. Google also documents no ASN, ISP, VPN, proxy or data-center setting for exclusions, and an exclusion does not get you money back for clicks already charged.

Our side has limits too. Our API classifies an IP you give it. It cannot see your Google Ads clicks or GCLIDs, which come only from your own landing-page log. It returns no prefix, so the block always comes from RDAP. And lookups drift: until 13 October our click fraud guide used 45.83.220.7 as a plain hosting example, and today the API names it as Mullvad's network. Date every result you act on.

What to do with each kind of address:

Address typeWhat to doWhy
Your office, a fixed competitor office range, a stable hosting or Tor block seen repeatedly in your logExclude, one CIDR entry per block, at the account levelStable, not shared, few entries
Carrier NAT (threat.is_cgnat: true), iCloud Private Relay (is_relay: true)Never excludeMany real users per address
VPN exits, one-off hosting addresses, anything that rotatesScore at landing with scoring.recommended_actionThe same operator scored 46 and 100

Two checks on your own exclusion list this week:

  • Shrink it. Export your current entries and run them through the script above. Entries that merge free slots, so count what is left before you add anything new.
  • Remove shared addresses. Look up one address from each entry in the fraud score checker. Delete any entry where is_relay or is_cgnat comes back true.

Frequently Asked Questions

How many IP addresses can you exclude in Google Ads?

Up to 500 per campaign, and Google's API reference sets the same 500 cap for account-level exclusions. The account list is not a bigger pool.

Can you use CIDR or IPv6 in Google Ads IP exclusions?

Through the Google Ads API, yes: each IPv4 or IPv6 CIDR block is one entry. Google's help page documents only single addresses and a last-octet asterisk for the interface.

Can you exclude IP addresses from Performance Max?

Only at the account level. Campaign-level IP exclusions aren't available for video, hotel, App, Performance Max and Smart Display campaigns.

Why do clicks still come from excluded IP addresses?

Google gives three reasons: some ISPs rotate users' addresses, some Google Network sites don't provide IP information, and organic and paid clicks share the same referrer.

Does excluding an IP address refund clicks you already paid for?

No. An exclusion stops your ads showing to that address from then on. Credits for invalid clicks are a separate process.

Should you exclude a mobile carrier or iCloud Private Relay IP?

No. Many real people share each of those addresses, so score the click instead of spending a slot on it.

Written byGeoIPHub Team

The team behind the GeoIPHub API

Written by the GeoIPHub team, the people who build the GeoIPHub IP intelligence API and its scanner. Drafts are prepared with AI assistance and edited by the team; API examples are real lookups against the live API unless labelled illustrative.

Share this article
More articles