Blog

Comparison Tables That Survive Extraction

Most vendor comparison tables are built for a human scanning a page: logos down the left column, green checkmarks across the middle, “Contact us” where the price should be. An engine that retrieves that page gets a grid of image tags and empty cells, and it goes and finds the facts somewhere else. This post covers what an engine can take out of a table and what it cannot, what the first Index run cited in place of vendor comparison pages, and one row rewritten so the facts in it can be lifted and quoted.

What an engine can take out of a table

The engines read text. OpenAI’s web search documentation describes the model retrieving page content and attaching url_citation annotations to the passages it used; Perplexity’s documentation describes answers composed from retrieved search results, each carried as a citation; and Google Search Central’s guidance on images says to keep important text in HTML rather than inside an image, because text inside an image is not read as text. A comparison table is therefore a text extraction problem, and the question for each cell is whether a program reading the HTML could state the fact in that cell as a sentence.

Seven properties decide that. One fact per cell, so “Per-unit monthly” and “$160 minimum” are not fused into a paragraph a parser has to split. A header row in a thead element, so each value has a column name to attach to. Units in the header or in the cell, so a number reads as dollars per unit per month and not as a bare figure. A caption or a sentence beneath the table that states the data in words, so the fact exists in prose as well as in a grid. A source and a date per row, so the engine, and the buyer, can see where the fact came from and when someone last checked it. No logos standing in for names, because an image of a wordmark carries no name unless the alt text does, and no checkmark images standing in for facts, because a checkmark says nothing about which PMS the product connects to. And no merged cells, because a cell spanning three columns breaks the header-to-value mapping for every column it spans.

Getting those seven right is a decision about what the table is for, and it does not need a designer.

What the one run cited instead

The September 2026 preview is a single run of a single prompt on one engine, and it should be read as that. The ChatGPT answer to prompt mvn-best-01 cited 124 sources. The top domain was reddit.com at 38 citations, then appfolio.com at 16, then buildium.com. Property Meld, named first in the answer, and Latchel, named second, each had their own domain in the citation list. capterra.com appeared once, and no other review platform appeared at all.

Two things stand out in that list, with the caveat that one run is one run. The sources were forum threads and vendor sites, including the sites of the property management systems the maintenance products integrate with, and the review-platform grids that most vendors assume are the engine’s comparison table were close to absent. Our working hypothesis, to be tested across the full three runs and four engines in the October edition, is that a vendor’s own page can be a cited source for a comparison question when it holds a stated price and a stated integration list, and that a checkmark grid on a third-party site is not what an engine reaches for.

The notes on how engines read a vendor page cover the paragraph-level version of the same problem. The table version is below.

One row, before and after

The before is a composite of what a maintenance software comparison table usually looks like. No vendor is quoted; the pattern is the point.

Vendor Integrations Pricing Rating
(logo image) Contact us ★★★★★

A typical comparison row: the vendor’s name exists only inside an image, the integrations column holds a checkmark with no PMS named, the pricing cell contains no price, and the rating is five star glyphs with no source.

A parser reading that row gets a vendor with no name, an integration with no partner, a price that is a verb, and a rating with no count behind it. Every fact a buyer would ask an engine for is missing from the row that was built to display it.

The after uses only facts from our vendor file, which carries a source URL and a verification date for each one.

Vendor Pricing model PMS integrations Source and date verified
Property Meld Per-unit monthly, $1.60 to $2.00 per unit, $160 per month minimum AppFolio, Buildium, Rent Manager, Propertyware, Yardi, Rentvine propertymeld.com pricing page and integrations post, verified 2026-09-02

Property Meld charges per unit per month, between $1.60 and $2.00 per unit with a $160 monthly minimum, and integrates with AppFolio, Buildium, Rent Manager, Propertyware, Yardi and Rentvine, per the vendor’s own pricing page and integrations post, checked on 2026-09-02.

Each change does one job. The name is text, so it matches the name an engine already associates with the domain. The pricing cell carries the model, the range and the minimum, with units, so an engine can answer “how much does it cost” with a number instead of “pricing available on request”. The integrations cell names six PMS products, so a prompt that says “integrates with Buildium” has a string to match. The last column says where the facts came from and when, which is what separates a fact from a claim on a page that could be four years old. The caption restates the row in prose, so a page that loses its table markup in conversion still carries the facts.

The rating column is gone. A star count with no review count and no source is decoration, and a review count copied from a platform that appeared once among the 124 citations in the one run we have is a fact about that platform rather than about the product.

Keeping the row true

A dated row is a promise to re-check it. The verification date in the last column is the mechanism. When the vendor changes its pricing page, the row is wrong until someone re-verifies it, and the date tells a reader how stale it might be. On this site every vendor fact lives in one file with a source URL and a last verified date, and the pages are generated from that file, so a correction lands everywhere at once. A vendor maintaining its own comparison page should do the same for its competitors’ rows, with the same care it would want for its own, since a wrong fact about a competitor on a page an engine cites becomes the wrong fact the engine repeats.

The name in the vendor column should also be the name everywhere else. The entity consistency guide covers why a product that is “Property Meld” on its site, “PropertyMeld” in a directory and “Meld” in a forum thread is three entities to a matcher until someone lists the aliases. And where a table’s facts also belong in markup, the structured data guide covers which properties the engines’ documentation says they read.

The table is one page element. The rest of what a vendor page needs is laid out in the AI search optimization overview, and the field notes continue on the blog.

Part of the methodology pillar.