All articles
SEO & GrowthSeptember 6, 2026 7 min read

Index Bloat on Programmatic Sites: A Pruning Playbook That Actually Moves Traffic

Most programmatic SEO sites don't have a ranking problem — they have an index bloat problem. Here's the pruning workflow we run when a 200k-page site is quietly suffocating itself in Google's index.

Index Bloat on Programmatic Sites: A Pruning Playbook That Actually Moves Traffic

A programmatic SEO site with 200,000 URLs and 3,000 that actually earn clicks is not a scaling success — it's a pruning problem waiting to hurt you. Google has been increasingly explicit that low-value pages drag down site-wide quality signals, and the Helpful Content system doesn't forgive at the URL level, it judges at the site level. If you run a large templated site and traffic has flatlined despite adding pages, index bloat is the first thing to rule out.

What index bloat actually looks like in 2026

Index bloat isn't just "too many pages indexed." It's a specific pathology: a growing gap between the pages you want Google to treat as your site, and the pages Google is actually using to characterize your site's quality.

The symptoms are familiar:

  • Impressions grow, clicks don't.
  • Average position drifts down across the board, not on specific queries.
  • Search Console shows a widening gap between "Crawled - currently not indexed" and "Indexed."
  • New pages take weeks to enter the index, or never do.
  • Core Web Vitals and content quality are fine on the pages you check — but Google seems to disagree.

The underlying mechanic: crawl budget gets spent on pages that don't earn it back, quality classifiers see a long tail of thin pages, and the pages you actually care about get less crawl attention and less trust. Pruning fixes both.

The 90/9/1 rule we see in real audits

In most programmatic audits we've done, the traffic distribution looks roughly like this:

  • ~1% of URLs drive the majority of clicks.
  • ~9% get impressions but few clicks (borderline).
  • ~90% get essentially nothing — under a click a month, sometimes zero impressions for 90+ days.

That bottom 90% is your pruning candidate pool. The interesting work is deciding which of them to kill, which to merge, and which to fix.

Step 1: Build the URL classification table

Before you prune anything, you need one table that joins everything: your CMS/database, GSC performance, GA4 engagement, and crawl data from a log file or a crawler like Screaming Frog or Sitebulb.

Your row per URL should look roughly like this:

CREATE TABLE url_health AS
SELECT
  u.url,
  u.template_type,           -- e.g. 'city_service', 'category', 'comparison'
  u.created_at,
  u.word_count,
  u.internal_links_in,
  gsc.impressions_90d,
  gsc.clicks_90d,
  gsc.avg_position_90d,
  ga.sessions_90d,
  ga.engaged_sessions_90d,
  ga.avg_engagement_time,
  logs.googlebot_hits_90d,
  logs.last_crawled_at,
  idx.is_indexed              -- from URL Inspection API
FROM urls u
LEFT JOIN gsc_performance gsc USING (url)
LEFT JOIN ga4_sessions ga USING (url)
LEFT JOIN log_summary logs USING (url)
LEFT JOIN index_status idx USING (url);

Without this table, every pruning decision is a guess. With it, you can segment by template type — which is usually where the real pattern hides. It's almost never "the site is bloated." It's "the /compare/[a]-vs-[b]/ template generated 40,000 pages and 38,000 of them are dead."

Step 2: Define the pruning thresholds

Hard rules beat vibes. Pick thresholds before you look at specific URLs so you don't emotionally rescue pages you built.

A reasonable starting framework, assuming the page has existed for at least 6 months:

BucketCriteriaAction
WinnerClicks_90d ≥ 10, or clearly ranking (avg pos ≤ 20)Keep, consider expanding
ContenderImpressions_90d ≥ 50, clicks_90d < 10Improve or merge
Dead weightImpressions_90d < 10, clicks_90d = 0Prune
Never indexedNot in index after 90+ days, no impressionsPrune or block

Adjust the numbers to your site's scale — a site with 10M pages needs stricter cutoffs than one with 20k. The point is the shape of the framework, not the specific numbers.

Don't just look at clicks

A page can have zero clicks and still be valuable if:

  • It receives meaningful internal links to other important pages.
  • It's part of a hub structure (category or index page).
  • It gets referral traffic from outside search.
  • It's ranking on the second page for a commercially valuable query — pruning that is malpractice.

Always cross-check pruning candidates against internal link graph position and non-search traffic before you pull the trigger.

Step 3: Choose the right removal mechanism

This is where most teams mess up. noindex, 410, 301, and canonical are not interchangeable, and using the wrong one wastes months.

noindex

Use when the page must remain accessible to users (say, a filter or a low-value but linked page) but shouldn't be in the index. Google needs to recrawl to see the tag, so removal takes weeks. Leave the page crawlable — do not block it in robots.txt at the same time, or Google can't see the noindex.

410 Gone

Use when the page has no reason to exist anymore. 410 is a stronger, faster signal than 404 that a URL is intentionally dead. In our experience, 410s drop out of the index noticeably faster than 404s, especially at scale.

301 redirect

Use only when there is a genuinely equivalent destination. Redirecting 30,000 dead comparison pages to your homepage is a soft signal to Google that they were all worthless — and it can taint the destination. If there's no clear 1:1 target, prefer 410.

rel=canonical

Use for consolidation between near-duplicates that both need to remain live. Canonicals are hints, not directives — if the pages diverge in content, Google will ignore you.

A rough decision tree:

Does the page need to stay accessible to users?
├── Yes → noindex, follow
└── No
    ├── Is there a true 1:1 replacement? → 301
    ├── Is it a near-duplicate of a page that stays? → canonical
    └── Otherwise → 410

Step 4: Prune in waves, not one big drop

Do not deindex 80,000 URLs in a single deploy. Even when the decision is correct, a sudden mass removal looks like a site incident and can trigger unrelated re-evaluation.

Our usual cadence:

  1. Wave 1 (10–15% of prune list): clearest dead weight — zero impressions, zero clicks, zero backlinks, zero internal links.
  2. Wait 3–4 weeks. Watch GSC coverage, sitewide impressions on the surviving pages, and crawl stats.
  3. Wave 2 (next 25–30%): low-impression pages.
  4. Wait, measure, adjust thresholds.
  5. Wave 3+: the remainder, including the harder judgment calls.

Update your XML sitemaps in lockstep — pruned URLs must leave the sitemap the same day they're deindexed or 410'd. Submitting sitemaps that reference dead URLs is a self-inflicted crawl waste.

The metric that tells you it's working

Don't watch total indexed pages — that's the whole point, it should drop. Watch:

  • Impressions and clicks on retained URLs (should trend up within 4–8 weeks).
  • Average crawl frequency on retained URLs from log files (should increase).
  • Time to index for new pages (should shrink).

If those three move in the right direction, the pruning is working even before overall traffic recovers.

Step 5: Fix the generator, or you'll be back here in a year

Pruning without fixing the upstream content generation is a treadmill. If your template produced 40,000 near-empty pages once, it will do it again.

Before new templated pages are allowed to publish, they should pass a pre-publish quality gate — a simple set of checks in your build pipeline:

  • Minimum unique content threshold (not just word count — actual uniqueness vs sibling pages, measured with something like MinHash or simple shingling).
  • Data completeness check: does this page have enough underlying data to be useful, or is it 80% boilerplate?
  • Search demand check: does the target query have non-trivial volume, or are we generating a page for nobody?
  • Internal link plan: will this page receive at least N contextual internal links on publish?

Pages that fail the gate either don't get built, or get built but excluded from the sitemap and marked noindex until they earn their way in.

If you want a deeper look at how we design that upstream data model, we've written about it in our programmatic SEO content model post, and the pruning workflow above assumes something like it is in place.

Where we'd start

If you're staring at a bloated site and don't know where to begin: skip the tooling debate and build the URL health table this week. One row per URL, joining CMS + GSC + GA4 + logs. Ninety percent of the pruning decisions become obvious once that table exists. Then run a small first wave — a few thousand URLs of the most clearly dead template — and measure for a month before you touch anything else. Pruning is a scalpel, not a bulldozer, and the sites that recover fastest are the ones that treat it like an engineering rollout, not a one-shot cleanup.

#SEO#Programmatic SEO#Technical SEO#Growth Engineering

Want a team like ours?

72Technologies builds production software for the kind of teams who actually read this blog.

Start a project