Methodology

How this was measured

Everything needed to reproduce these numbers, check the work, or challenge what the findings page claims.

In plain English

What we did and what we found

We drew 2,500 businesses at random from the 43,469 active business registrations in Richmond, Henrico, Chesterfield and Hanover, then audited the web presence of the 574 we could confirm are customer-facing operations rather than holding entities. About a third of those — 33.1%, give or take 3.9 points — have no website at all. Among the ones that do, most are missing the basic technical signals search engines and AI assistants use to identify a business: 40.6% carry no structured data and 73.7% have no llms.txt file.

Everything below is how that was measured and where it can be wrong. If you only read one more section, read known limitations.

Population

What "Richmond small business" means here

The population is every business entity with ACTIVE status in the Virginia State Corporation Commission's corporation and LLC files whose registered address falls in Richmond city, Henrico, Chesterfield, or Hanover county. As of this run, that is 46,543 unique entities.

3,074 were excluded before sampling as entities that would not be expected to have a customer-facing website: holding companies, single-property real estate vehicles, homeowner and condo associations, churches, and foundations. The exclusions are name-pattern based and listed in full below. That leaves an eligible population of 43,469.

Excluded patternEntities
Holdings713
Foundation640
Properties Llc506
Homeowners306
Church284
Condominium204
Ministries147
Owners Association145
Ministry49
Holding Co37
Property Owners33
Hoa7
Condo Association1
Parish1
Family Trust1
Sampling

A random draw, not a lead list

2500 businesses were drawn using Python's random.sample with seed 20260825 against the eligible population sorted by entity type and ID. The seed is published so the identical sample can be redrawn by anyone.

This matters more than it may sound. The obvious shortcut would have been to reuse a prospecting database — but a prospecting database is deliberately weighted toward businesses that look underserved, which would inflate every "missing X" figure here. A random draw from the full registry is the only version of this worth citing.

Measurement

How each business was audited

Sectors

How businesses were grouped

Google assigns each business a category, and across a randomly drawn registry sample those fragment badly — 105 distinct categories across the confirmed businesses, only three of which clear 30. Reporting per category is therefore not possible from this sample; reporting per sector is.

Categories are grouped by keyword into nine sectors, of which seven cleared the 30-business threshold. The groupings are deliberately coarse, and the keyword lists live in sectors.py in the published pipeline so they can be disagreed with specifically rather than in general. Categories that carry no sector meaning — "Services", "Building", "Point of interest" — are left unclassified rather than forced into a bucket; 189 businesses fall there. Every business's raw Google category is in the CSV, so a different grouping can be applied to the same data.

Honesty

Known limitations

Reproduce it

Run it yourself

The full pipeline — registry pull, sampling, audit, statistics, and this site — is a small Python project. With the same seed, it produces the same sample. The audited records behind every figure are published as CSV, one row per business, including the evidence for each website match.