Growth Index 2026 methodology
How we picked, crawled and scored 451 local operators, and what the data can't tell you.
Version 1.0. Snapshot date: October 20, 2026. Author: Matt Lawler, LVL3. This page explains how we picked, crawled and scored the operators behind the Home Services Growth Index 2026, and what the data can and can't tell you.
1. Scope
We covered 25 US metros and 4 trades: HVAC, Plumbing, Electrical, Roofing. We ran 100 searches, one per trade per metro ("hvac company <metro>", "plumber <metro>", "electrician <metro>", "roofing company <metro>"), using residential-intent keywords only so commercial and industrial firms didn't crowd out home services operators. For Detroit HVAC, "hvac company detroit" returned no search data, so we used "hvac detroit".
2. Sample construction
For each search, we kept the top organic operator results after removing directories, review sites, social profiles, media, manufacturers, job boards, government sites and other non-operator domains. We took the top remaining operator domains per metro and trade, in search-result order, for a starting sample of 490 operators. A company ranking in more than one cell is tagged multi-trade. Firms flagged as commercial or industrial by domain or page content were reviewed by hand and excluded where the review confirmed they don't serve residential customers (see Validity and exclusions, below).
3. Data collection
Site metrics
For every domain we pulled organic and paid search metrics, AI Overview appearance data (the share of a domain's ranking keywords where Google shows an AI Overview, and the share of those where the domain is a linked source), and local pack appearances.
HTTP and crawler-access checks
We checked each site's robots.txt rules for GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, anthropic-ai, PerplexityBot, Google-Extended, CCBot, Bytespider and Applebot-Extended, and requested each homepage with a browser user agent and with the user agents of the major AI crawlers, from more than one network, to separate a deliberate block from anti-spoofing behavior that a verified bot would pass. We also checked for a valid llms.txt file.
Rendered crawl
Every site was crawled on a real mobile browser (an emulated phone screen, not a desktop view) to read what a visitor would actually see and do: a tap-to-call number and a book or schedule button on the first screen, online booking, chat, financing and emergency-service messaging, and the tracking tags, pixels and schema markup present on the page. The crawl was re-run with parallel browser workers performing the same real-interaction pass used in the pilot, scrolling and waiting for the page to settle before reading it, so slow-loading widgets and lazy content were captured on the re-run as well as the first pass.
Online booking means a visitor can pick a specific appointment time slot, on the homepage or one click from it. A request form with no slot picker doesn't count as online booking, even if it leads to a callback. Instant price-quote tools are tracked separately and aren't scored as booking.
Call tracking counts a site as having call tracking if it either shows different phone numbers by traffic source (dynamic number insertion) or has Google Ads' own website call conversion tracking installed. Call tracking inside a phone system or field-service platform, invisible from a website crawl, isn't counted; see Known limits.
Google Ads tag means a Google Ads tag that fires when the homepage loads. An Ads ID that's only configured inside a tag manager container, with no tag firing, isn't counted.
4. Validity and exclusions
Of 490 sampled operators, 464 were valid and scored. The rest were excluded for the reasons below. Every excluded site was reviewed by hand before exclusion, and sites that were wrongly excluded on the first pass (blocked a bot, or ambiguous on trade words) were re-crawled with a slower pass and added back where they turned out to be real operators.
| Reason | Count |
|---|---|
| commercial | 3 |
| bot challenge | 2 |
| not an operator site | 4 |
| load failed | 2 |
| commercial-only (manual review) | 12 |
| duplicate | 1 |
| not an operator (manual review) | 2 |
Commercial-only exclusions came from a manual review of every site flagged by domain or page text as commercial or industrial; only the sites that review confirmed don't serve residential customers were dropped. "Not an operator" exclusions are sites that never mention the trade they were sampled for.
Of the 464 valid operators, 13 are national brands. They're scored on the Booked and Measured layers but excluded from the Found and AI-visible layers, and from the index ranking, because search metrics are measured at the national domain, not the local page. That leaves 451 local operators in the index.
We ran 3 blind validation rounds on detection accuracy, covering 128 sites. Each site was checked against a live reload of the site rather than against our own crawl output. The last round was a fresh sample of 40 sites, drawn after our detection fixes and weighted toward the call-tracking finding. On the 39 we could check, the crawl's call-tracking result matched the hand-coded result on 38.
5. Scoring
Each operator is scored 0 to 25 on four layers (Found, AI-visible, Booked and Measured) for a Growth Index out of 100. Booked and Measured are based on what the rendered crawl found on the site; Found and AI-visible are based on search and AI Overview metrics and apply to local operators only. Percentiles are computed within the 451 local operators.
We treat groups under 30 operators, and shares built on fewer than 5 operators, as directional only, report the sample size behind every figure, and don't claim causation from the size or multi-trade associations in the findings.
6. Known limits
- Geography. We approximate local results with city-name searches, not geo-located search results.
- One-day snapshot. Sites change after the crawl date. The crawl is a record of that day, not an ongoing measurement.
- Lower bounds. Chat and above-the-fold call-to-action counts are lower bounds: a banner or widget our crawler can't see as a link or button is missed.
- Online booking is also a lower bound. We can only detect a scheduler that appears, or links out, from the homepage; a booking flow hidden behind a login or a separate app isn't counted.
- Invisible call tracking. Call tracking inside a phone system, a call extension, or a field-service platform's own reporting isn't visible from a website crawl and isn't counted here.
- Bot blocking is an upper bound. Server-side tests of AI crawler access can trip anti-spoofing rules that a verified bot would pass, so the blocking share is an upper bound. The hard-block count (a clear refusal across multiple bots) is more reliable.
- Some sites couldn't be crawled. A small number of sites blocked every crawl attempt, including the re-crawl, and are excluded rather than guessed at.
- Crawl-resistant sites skewed toward one website platform. Sites we couldn't crawl on any attempt were not evenly spread across platforms. We don't name a platform negatively on the strength of that pattern; it may reflect how that platform's hosting handles bot traffic rather than anything about the operators using it.
- Metros. Each metro holds 16 to 20 operators across all four trades, too few to rank metros against each other.
- Speed. Mobile speed isn't scored yet. Real-user Core Web Vitals are planned for a future update.
- Naming. The top 10 is the highest-scoring operators in our sample, not a national ranking.
- Causality. None claimed. Size and multi-trade differences are associations, not effects.