HomesIndex

About HomesIndex

HomesIndex geolocates every sold house price recorded by HM Land Registry for England and Wales, and uses that record to tell you whether a home you are looking at is priced fairly against what has been selling around it.

This page is the long technical answer to “how does it work”. It follows the data from the moment it leaves HM Land Registry to the moment it appears on the website. If you only want the short version: 31,370,645 sales are ingested, 97.5% of them are geolocated to the exact coordinates of their building, and every statistic on the site is then computed from that record.

Everything on the site comes out of one pipeline that runs monthly, and every page is rebuilt from its output. There are six stages:

  1. Ingest. Read HM Land Registry's Price Paid file, the complete record of sales in England and Wales.
  2. Geocode. Turn each sale's address text into the identifier of a real building, then into coordinates, and check the result against the postcode's own boundary before trusting it.
  3. Enrich. Attach the property facts from the Energy Performance Certificate register: floor area, habitable rooms, energy rating, construction age.
  4. Aggregate. Compute medians, means, counts and price per square metre for every postcode area, district and sector, by year and by month.
  5. Publish. Cut the results into vector tiles and sharded files so a browser downloads only what is on screen.
  6. Score. Read live estate agent feeds and measure each asking price against the sold record for homes of the same type, the same size, in the same place.

Stage 1: ingesting the register

The source is HM Land Registry's Price Paid Data, the complete file of residential sales lodged for registration in England and Wales since 1995. It is a 5.4 GB CSV of roughly 31 million rows.

Each run rebuilds everything from that file rather than patching what came before. It reads the file row by row, geocodes every row, and writes one file per postcode district. Rebuilding from scratch means any correction Land Registry has made since the last release is picked up automatically.

Two kinds of row are excluded, and both are logged as they go: sales carrying Scottish postcodes, because Scotland keeps its own register, and the handful of rows whose price field will not parse. The Scottish test is a fixed list of postcode prefixes:

SCOTTISH = {"AB","DD","DG","EH","FK","G","HS","IV","KA",
            "KW","KY","ML","PA","PH","TD","ZE"}

Land Registry writes an address across separate fields, and we keep them exactly as they arrive rather than mashing them into one line. The primary name, the secondary name and the street stay separate, so “Flat 3, 12 Palatine Road” stays a different property from “12 Palatine Road”, and a property's sale history is looked up on the full postcode plus those exact fields rather than on anything approximate. We found out the hard way why that matters: two different homes that shared a house name within the same postcode district were being merged into a single sale history. Using the full postcode in the key fixed it, and it is why the history panel shows you each row's address fields rather than a tidied version of them.

Land Registry also tells you which sales were ordinary market transactions and which were not. Category A is a standard full-market-value sale. Category B covers repossessions, buy-to-let and company transfers, and other prices that may not represent open-market value: 1,774,047 records, or 5.7% of the file, and a noticeably larger share of recent years. Every median, mean, price per square metre and deal verdict on this site is computed from Category A alone. Category B rows are still shown in a property's own sale history, labelled “Non-market record”, because the history is a record of what happened rather than an edit of it. They are simply never allowed to stand as market evidence.

Stage 2: putting a sale on its building

Land Registry records a sale as text: a house number, sometimes a flat number, a street and a postcode. Turning that text into a point on a map is the hardest part of this whole system, and it is where most of the engineering has gone.

Most public tools stop at the postcode, so every sale in it gets the same dot and a block of forty flats becomes one point on the map. HomesIndex resolves each sale to the individual building it happened in, which is why a block of flats appears here as separate homes at separate prices, and why a terraced street reads as a street rather than as a cluster.

Every building already has an identifier

Ordnance Survey gives every addressable building in Great Britain a Unique Property Reference Number, a UPRN, and publishes the coordinates of each one as open data. If we can establish which UPRN a sale belongs to, we know exactly where it happened, to the rooftop. So the real problem is matching address text to a UPRN.

Two bridges from text to UPRN

The first bridge is the Energy Performance Certificate register. Nearly every home sold or let since 2008 has a certificate, and each certificate carries both the written address and the UPRN. That gives roughly 23 million worked examples of “this address text means that building”, which we turn into a lookup table.

Certificates only exist for homes that have needed one, so a house that last changed hands in 1997 and has never been assessed is invisible to that bridge, and most pre-2010 sales are of exactly such homes. The second bridge fills the gap. Researchers at the University of Glasgow's Urban Big Data Centre matched every Price Paid transaction from January 1995 to January 2022 against Ordnance Survey AddressBase Plus and published the result as open data: 25,950,983 rows of transaction identifier to UPRN, at a 96% match rate against a reference register our certificate-derived lookup structurally cannot equal. Those matches are folded into the same lookup table, and they face exactly the same checks as everything else.

The same address gets written many ways

A certificate might say “Apartment A, 12 High Street” where Land Registry says “Flat A” at “12” on “High Street”. One source writes “St Johns Road” and the other “Saint Johns Road”. One writes “12A” and the other “12 A”. A plain string comparison misses all of these, and they are common.

So both sides get cleaned up the same way, by one shared piece of code that three programs all call: the one that builds the lookup out of EPC certificates, the one that looks up every Land Registry sale in it, and the one that merges in the Glasgow dataset. Because all three run the same rules, they cannot end up disagreeing about what an address looks like.

The rules themselves are borrowed rather than invented. They come from five published open-source address matchers, and where two of them had independently arrived at the same rule, that was the reason to adopt it here: the Ministry of Justice's uk_address_matcher, the Urban Big Data Centre's os_epc_ppd_linkage, Centre for Net Zero's epc-ppd-address-matching, the ONS address index, and Endeavour Health's ASSIGN.

Each rule can be traced to where it came from. The abbreviation map is vendored verbatim from uk_address_matcher, and so are the number-letter fusion, the compacted spelling and the refusal to expand ST or DR. The sub-building rules, meaning the descriptor stripping and the zero-stripped flat numbers, come from the two projects that had already tackled this exact join, os_epc_ppd_linkage and epc-ppd-address-matching. The numeric ranges, the first-of-range variant and the vocabulary of descriptor words come from the ONS address index and ASSIGN.

Cleaning up an address means upper-casing it, removing apostrophes, turning the remaining punctuation into spaces, expanding its 162 abbreviations, and joining up the number forms that trip up a plain comparison. Two rules do that last part:

_NUM_LETTER = re.compile(r"\b(\d+)[ \-/]+([A-Z])(?= |$)")
_RANGE_RE   = re.compile(r"\b(\d+[A-Z]?) *(?:-|/|TO) *(\d+[A-Z]?)\b")

Put through that, real addresses come out like this:

12 A HIGH STREET      ->  12A HIGH STREET
12-A HIGH STREET      ->  12A HIGH STREET
2 TO 4 MILL LANE      ->  2-4 MILL LANE
2/4 MILL LANE         ->  2-4 MILL LANE
14 KING'S RD          ->  14 KINGS ROAD
APT 4, 9 ST JOHNS RD  ->  APARTMENT 4 9 ST JOHNS ROAD

Two abbreviations are never substituted, on purpose. ST is either SAINT or STREET and DR is either DRIVE or DOCTOR, and a wrong guess there produces a confident match to the wrong building. Instead, ST gets a second spelling offered alongside the original: an ST at the end of the address, or one followed by a number, becomes STREET, an ST followed by a word becomes SAINT, and both are stored, so whichever the source used will be met. The original is untouched, which is what makes a wrong guess free.

Each address is then stored under several spellings at once rather than one, in descending order of confidence: the full form, a form with words like Flat and Apartment removed so that FLAT 01, APARTMENT 1 and 1 all share a spelling, the ST-expanded form, a fully compacted form with every space and punctuation mark removed, and a first-of-range form so that “2-4 High Street” can meet the certificate that was issued for number 2. Every spelling has the full postcode built into it, without exception, so “12 High Street” in one town can never borrow coordinates from a 12 High Street in another.

Every spelling we store an address under is also a spelling we try when looking a sale up, and we try the most exact spelling first and the vaguest last. That is the whole of it:

def lr_keys(paon, saon, street, postcode):
    bases = ([_join(s, p, st), _join(p, s, st), _join(s, p)] if s else []) + [_join(p, st)]
    for b in bases:            add(b)          # the exact spellings first
    for b in bases:
        for v in _variants(b): add(v)          # then the looser ones, same order
    add(p)                                     # bare house number last of all

When the evidence disagrees, we refuse to guess

Sometimes two genuinely different buildings produce the same cleaned-up text. When that happens the spelling is deleted from the lookup entirely, because a match through it would be a guess.

Sometimes the source data is simply wrong. A certificate can name a UPRN in a different town: the register really does contain a Water Lane in London pointing at a Water Lane in Richmond, 24 km away. To catch that, every matched building is tested against the real boundary of the postcode it claims, using the open GB postcode polygons, which were themselves grown outward from the actual address points of each postcode. A match that lands inside its postcode, or close enough to it to be ordinary boundary slack, is accepted. One that lands well outside is rejected, and the rejection is written down so the same bad claim cannot walk back in on a later rebuild.

One wrinkle would otherwise throw out good matches. A sale carries the postcode as it was recorded at the time, and postcodes get terminated and recoded over thirty years, while the polygon set is current. A correct match on a 1990s postcode that no longer exists would fail the test through no fault of its own. Those cases are rescued two ways: where several claims on the same dead postcode agree with each other, they are accepted together, and where there are too few claims for that, the point is checked against the ONS Postcode Directory, which keeps terminated postcodes along with their old centres. Within 500 m of the old centre is accepted. That is generous, but it still kills the wrong-town errors, which are kilometres out, and those are the ones that matter.

The Glasgow lookup passes through the same gates in a fixed order: claims we have already proved wrong are dropped first, because those matches were made against the same national data our errors came from and some of their rows repeat them, and then every surviving pair has to land inside its own postcode's boundary or within 100 m of it. Nothing from that source is trusted unvalidated, because it was published without an accuracy check of its own.

Where every sale ends up

Every sale gets the best answer the evidence supports and nothing better. There are three outcomes:

  • Matched to its exact building through a validated UPRN: 97.5% of sales, 30,577,188 of them.
  • Placed at the centre of its postcode, which is the average position of that postcode's buildings and usually within a street or two of the truth: 2.4%, 750,484 sales.
  • No usable postcode at all: 0.1%, 42,973 sales. These are drawn nowhere on the website, and having no postcode they feed no local statistic either.

The same matching engine runs behind our EPC Geocoder, where you can put your own address list through it.

Stage 3: what we know about each home

The Price Paid record carries a price, a date, a built form, a tenure and an address, and nothing else. Everything else about a sold home comes from its Energy Performance Certificate, taken from the newest certificate for that building and stored under deliberately short names, because these files get downloaded by browsers:

fa  total floor area, whole m2      er  energy rating (A-G)
hr  habitable rooms                 ab  construction age band

Floor area is what makes price per square metre possible on this site, and that is the one figure here that lets two homes of different sizes be compared honestly. It is computed over the last five years only, so it describes the market as it is now rather than an average of the last three decades.

Floor area is also how a sold home gets a bedroom count, which it needs before it can be compared with a home that is for sale. Land Registry records no bedrooms at all, so the number has to be worked out, and it is worked out from a physical measurement rather than a rule of thumb. A home is placed at the bedroom count whose measured size band it falls into, and the bands are the midpoints between the median floor areas of adjacent bedroom counts.

Those bands are measured for each postcode area separately, because a 2-bed flat in Manchester is not the size of a 2-bed flat in south-west London, and one national set of bands mislabels homes at both ends of the country. The measurement comes from 104,307 sold homes: each one's bedroom count taken from the property's published sold-price listing, joined to the floor area on its own Energy Performance Certificate and the built form on its Land Registry sale. Take the size at which a terraced home stops being a 3-bed and becomes a 4-bed. Nationally that is 102 m2, but measured area by area it runs from 92 m2 in Romford to 118 m2 in south-west and west London:

terraced homes, m2 at which each bedroom count starts
                     2-bed   3-bed   4-bed   5-bed   6-bed
Manchester (M)          61      78      96     118     143
SW London (SW)          64      88     118     157     199
Cornwall (TR)           52      68      96     126     153
England and Wales       56      76     102     130     158

An area measures its own band wherever it has the homes to measure it. Where it does not, at the rare sizes, the band is not borrowed from the national figure: it is scaled from that area's nearest measured band by the national step between the two, so the answer still carries that area's own scale. The national figures are used directly only where an area has almost none of a built form at all, which in practice means detached houses in central London.

Floor area is on 96.2% of the sales in the four-year window the comparables are built from, and on 83.1% of the whole record since 1995. The gap between those two is the certificate era: certificates only exist for homes assessed since 2008, so a house that last changed hands in 1997 and has never been assessed carries no measurement at all. Where a sold home has no floor area it is left out of the bedroom-matched comparables rather than guessed at, and a home for sale with no stated floor area simply shows no price per square metre.

Stage 4: turning sales into statistics

For every postcode area, district and sector, the pipeline computes the total number of sales on record, the mean and median price rounded to the nearest £100, and the same figures broken down by year and by month.

The headline figure on every page is the median, not the mean. A handful of very expensive sales pulls an average well above what a typical home actually sold for, and in a thin market that handful can be a single house. Both figures are published so you can see the gap.

One rule is worth stating, because it explains why some areas on a map carry no figure at all. If a place has recorded no sale in the latest year, it is left blank rather than filled in with an older year's median. Falling back would quietly show you a stale number as though it were current.

The colour scale on the maps is not a fixed set of price bands. For whichever period you are looking at, it is stretched between the 5th and 95th percentile of every value in that period, which keeps the ramp readable in 1996 and last month alike:

const at = (q) => vals[Math.min(vals.length - 1, Math.floor(q * vals.length))];
return [at(0.05), at(0.95)];

Where prices are shown in today's money, the adjustment uses the ONS CPIH index, annual averages, with the base year always being the latest year we hold.

Stage 5: getting 31 million sales into a browser

Your browser only ever downloads what is on your screen, and two things make that possible.

Boundaries are vector tiles rather than one national file per level. The map used to fetch 42 MB of sector shapes, 25 MB of districts and 12 MB of areas before it could draw anything. As tiles, it fetches roughly 8 KB per district tile, and only the tiles in view. The tiles carry the boundary code and nothing else, because the time slider spans thirty years and the statistics live in their own files.

Individual sold homes have a stripped-down file of their own, holding only what the map needs to draw a dot, in columns rather than as objects, which is about seven times smaller than the full record and far quicker to read:

{ lat: [...], lng: [...], p: [...], m: [...] }

The full record, with the address, the certificate facts and the links, is fetched for one postcode district only when you actually open a home's popup.

Stage 6: pricing homes that are for sale

The sold record tells you what a street has been going for. The homes-for-sale map answers the next question, which is whether the home in front of you is priced fairly against it.

Where the listings come from

Asking prices come from estate agents' own published feeds and from agents whose software sends us their listings directly, the same feed they already send the major portals. Each run replaces the whole dataset with whatever the feeds are serving at that moment, which is why a home that comes off the market disappears from this map on its own without anyone pruning it. Runs happen on Mondays and Thursdays.

Only agents whose sites offer an easy public feed are read. A site that has deliberately made itself hard to read is not scraped, and those agents are approached by email instead. Agents can connect a feed here.

The comparable

The verdict rests on one number: the median sold price of homes of the same built form with the same bedroom count in the same postcode sector, over the last four years of market sales. A group needs at least 15 sales behind it before its median is used at all. At sector level, groups meeting that bar cover 93% of the market, which makes the postcode sector both the most local option and a dense enough one.

Where a group is too thin, the comparison steps outward to the district, then the postcode area, then a national figure, and the popup always tells you which one produced the number and how many sales are behind it. Roughly a third of comparisons end up on the national figure, which for a 2-bed flat is the median of 186,031 sales, and calling that “nearby” would not be true, so it does not.

Matching on size is the part that matters most. When the comparison was made against a median that mixed studios and six-bedroom houses together, a one-bed looked cheap whatever it cost and a four-bed looked expensive: 51% of one-beds landed in “below sold prices” and 30% of four-beds in “far above”. The verdict was sloping with the size of the property, which is the one thing it must never do.

Price per square metre is computed and shown next to the verdict as a second opinion, and it never moves the verdict itself. Two independent numbers side by side are easier to judge than one number that has averaged several things together.

The bands

The asking price is divided by the comparable, and that ratio picks the band. This is the entire rule:

band = ("below"     if rel <= 0.85 else
        "inline"    if rel <= 1.12 else
        "above"     if rel <= 1.5  else
        "far-above")

One guard sits alongside it. A sector or district median wildly out of step with its own postcode area is usually not a housing market at all, it is a commercial district leaking into the residential record, so where the local median runs past four times the area median it is capped rather than allowed to dominate.

Where we refuse to give a verdict

Some asking prices mean something other than a price. An auction guide is set low deliberately to draw bidders. Retirement and age-restricted homes trade at a structural discount for a real restriction on who is allowed to buy them. A park home, a houseboat or a static caravan is not comparable to the bricks-and-mortar sold record at all.

All three used to be coloured like anything else, and on one build 1,042 of the 2,026 auction listings on the map were wearing “below sold prices”. A confidently wrong green is the worst thing this site can produce, so none of the three gets a value verdict now. The arithmetic is still there in the popup if you want it; it simply no longer colours the map.

Importing a listing from elsewhere

The map's Import listings button takes a link to a property or a page of search results and puts those homes on your map, scored the same way. Imported homes are yours alone: they are never saved, never added to the map anyone else sees, and they disappear when you reload. Their score is rebuilt in your browser from nearby sold prices, which makes it an estimate rather than the full comparison, and each one says so.

What the data cannot tell you

  • Recent months are incomplete. Registration takes weeks, so the newest month or two always fills in on later releases. Every page states the release it was built from for exactly this reason.
  • “No sales” and “no data” are different things. Within England and Wales the Price Paid file is the complete record of registered sales, so an empty street genuinely means no registered sales in the window you chose. Scotland and Northern Ireland keep separate registers, so homes there are excluded and the site says so rather than showing them as empty.
  • These are sold prices, not valuations. Nothing here is an estimate of what a home is worth. The figures are what buyers actually paid, which is a firmer basis for judging a market than a model, and a poorer basis for judging one specific house than a surveyor.
  • Bedroom counts on sold homes are worked out, not recorded. They come from floor area, as stage 3 explains.
  • Same-day twins are real. The register does contain a few genuine duplicate-looking records, and they are kept and shown, because this site displays the register rather than our opinion of it.
  • Crime is shown as a band, not a rate. The underlying police data is noisy at street level, and presenting it to three significant figures would be dressing uncertainty up as accuracy, so it appears as a band instead.

Sources, licences and attribution

  • Sold prices: HM Land Registry Price Paid Data, every residential sale in England and Wales lodged for registration since 1995. Crown copyright, published under the Open Government Licence v3.0.
  • Property coordinates: Ordnance Survey Open UPRN, plus ONS postcode data for the postcode-centre fallback and for terminated postcodes.
  • Address to building: the England and Wales Energy Performance Certificate register, and the Price Paid Data to UPRN Lookup from the Urban Big Data Centre at the University of Glasgow, used under the Open Government Licence. Required citation: Urban Big Data Centre. Economic and Social Research Council. Price Paid Data to UPRN Lookup, 2024 [data collection]. University of Glasgow, Urban Big Data Centre.
  • Property attributes: the same EPC register, for floor area, habitable rooms, energy rating and construction age band.
  • Postcode boundaries: the open GB postcode polygon set, used to test every geocode against the postcode it claims.
  • Inflation: ONS CPIH.
  • Local context in popups: crime from police.uk (twelve months of recorded offences per neighbourhood, against Census 2021 population), flood risk from the Environment Agency and Natural Resources Wales, schools from the DfE register, bus stops from NaPTAN.

Coverage and updates

HomesIndex covers England and Wales. Scotland and Northern Ireland keep separate land registers, so homes there are not included and cannot be scored. Sold prices are refreshed monthly from HM Land Registry as new sales are registered, and every asking price on the site is re-measured against the new medians in the same run. Homes for sale are refreshed every Monday and Thursday.

Who writes HomesIndex, and how to reach us

Aadityaa Mehrotra is the name HomesIndex publishes its analysis under, on the blog and on any piece we contribute elsewhere. It is a pen name for the site's editor. HomesIndex is an independent site and does not put the names of the people behind it on the product.

If a figure looks wrong, the fastest thing you can send is the address or postcode and what you expected, because that lets us trace a matching error directly. Email aadi@homesindex.co.uk. The underlying record belongs to HM Land Registry, so a genuine registry error needs reporting to them, but we will check our end first. If you cite a HomesIndex figure, a link back to the relevant page is appreciated.

See homes for sale priced against the sold record →

Browse the local market reports →

Or look up a place now:

Contains HM Land Registry data © Crown copyright and database right 2026. This data is licensed under the Open Government Licence v3.0. Contains Ordnance Survey data © Crown copyright and database right. HomesIndex is an independent tool and is not affiliated with HM Land Registry or Ordnance Survey.