Methodology
What this site publishes
For every region, district and neighbourhood in Singapore, and for the median resale price per square foot, the median resale price, the 20th–80th percentile spread, a 95% interval on the median, the transaction count, the share of local stock that changed hands, a quarterly history back to 1990 in cash terms and in today’s money, cuts by flat type, storey band and remaining lease, rent and gross yield by flat type, and a table of the submarkets inside it.
This build covers 983,157 resale transactions from January 1990 to July 2026, against a stock of 1,175,956 flats in 10,796 residential blocks.
Four registers, four anchors
Everything on this site is computed from four public registers, and the registers are never pooled: HDB resale registrations and HDB renting-out approvals from Data.gov.sg, and URA private sale caveats and private lease contracts from the URA Data Service. Each register records a different event, on a different filing rhythm, under a different licence, and each therefore carries its own anchor month: the latest month whose filings have substantially arrived, computed per register as the most recent month holding at least 40% of that register’s baseline monthly volume. An HDB resale is registered on completion, weeks after the price was agreed; a URA caveat is lodged when the buyer exercises the option, closer to the agreed price, but lodging is voluntary and recent months fill in late. Ending every register at the same calendar month would quietly turn the newest month of the slower register into a half-empty sample, which is how a “latest figure” comes to describe a month that has not finished arriving.
The practical consequence is visible on every page: an HDB figure and a private figure on the same page may state windows ending in different months, and each names its own. Any figure built from two registers at once, which on this site means only the gross yield, is published solely where the two anchors agree, and is withheld with its reason stated where they do not.
What a number may claim
A handful of editorial rules bind every figure on the site, and each exists because its absence produced a defect that was measured before it was fixed. A count printed beside a figure is that figure’s own denominator, never a larger number borrowed from a wider sample. Every count states the window it was counted over. Each quantity has one renderer, so a price, a rate or a percentage cannot appear in two formats on one site. A statistic withheld is withheld with its reason in the open: the three states, no data at all, an estimate below the floor, and a sample too thin to publish, render differently, and a bare dash is forbidden everywhere. Rounding happens once, at export, and what the reader sees is what every downstream surface, the JSON files included, carries.
The window each figure covers
Each area uses the shortest window in 12, 18 or 24 months that holds at least 30 resales.
A median over six sales is not a market statistic. Counts and medians are only comparable between areas that share a window, so every figure states its own.
The UK build ladders out to 60 months because its market is broadly flat over that span. Singapore's is not: the national median ran $470/ft2 in 2021 and $603 in 2026, up 28%. A five-year median here would blend a market a quarter cheaper into today's figure, and its interval would still describe only sampling error.
The floor is 30 resales, and the window an area actually used is published on the area itself (window_months on every area), beside every count it governs. Two areas are compared only when their windows are stated, and the compare pages suppress their verdict when the windows differ.
The headline figure
The area headline is the median price of a named flat type: the 4-room where the area has one, its commonest type otherwise.
HDB flats come in standardised types; a 4-room is 93 square metres across the island. A buyer transacts on the price of a 4-room in Tampines, not on a rate. The rate is published beside it, mix-adjusted.
The headline names its flat type everywhere it appears, so the figure can never be read as “this area’s price”. Where the headline sample sits below the publishing floor, the figure still renders, with a qualifier in the sentence itself and a banner naming the parent level whose sample does clear it: a thin median stated as plain fact and a thin median hidden entirely are both failures, and the page does neither.
The mix-adjusted rate
Every area also publishes its per-flat-type medians restated at Singapore's national flat-type distribution, weighted from the stock rather than from what transacted.
Smaller and older flats carry a higher price per unit area, so a raw blended rate is substantially a statement about an area's flat-type mix. Kallang blends to $749/ft2 against $958 for its own 4-room stock. Comparing two areas on the raw figure compares their stock composition as much as their prices, so the league tables rank on the adjusted one.
Withheld where an area's flat types cover under 60 percent of the national weight: an adjusted figure standing on a fifth of the distribution is not a national-mix figure.
This is the site’s one rule about ranking, and it is enforced rather than preferred: every ordered list of areas anywhere on the site, the league tables, the 2026 report, the flat-type pages and the compare verdicts, ranks on the mix-adjusted rate at the same floor and window, and the build fails if any surface orders areas on anything else. A raw blended rate appears only beside its adjusted counterpart, labelled unadjusted.
Where the sample is too small
Below 30 resales even at 24 months (the longest rung of the ladder), the figure is marked below the floor: the page says so in a banner, names the parent area whose published figure stands in, and carries no confidence grade at all, because grading an estimate the page refuses to stand behind would dress it as one it does.
Withholding it entirely would leave a reader with nothing where a caveated figure plus a comparison is more use. What is never done is presenting it as reliable.
In this build 19 areas sit below the floor and carry that flag.
Outliers
An impossibility band, not a statistical fence: a price per square foot outside $5 to $3,000, or a floor area outside 15 to 600 m2, is withheld as a keying error. Nothing is ever dropped: only the rate is withheld, and the sale keeps its place in every count.
NOTHING IS DROPPED. An outlier verdict withholds the row's price per unit area and nothing else: the sale still counts in the transaction count, still appears in the resales table, still contributes to the median price.
Measured over all 983,157 rows, this register contains no detectable errors. The extremes are $15 per square foot (1990 one-room flats of 31 square metres at $5,000) and $1,500 (Central Area 4-room flats at $1.5m), both real, and floor areas run 28 to 366.7 square metres with nothing impossible in between.
HDB publishes the exact floor area on the same row as the price, so unlike a certificate-derived area there is no measurement error for a statistical fence to find. A 3.0x log-IQR fence was tried: pooled over 36 years it was inert, withholding nothing in the last two years and leaving the national median bit-identical; detrended by year it became active and started withholding real million-dollar flats instead. The band that replaced it currently withholds nothing, and publishing that it withholds nothing is the honest outcome: the previous rule's 0.020% measured the rule, not the data.
In this build the fence withheld a price per unit area from 0 of 983,157 priced sales (0.000%). The effect by flat type:
| Flat type | Priced sales | Withheld | Share | Range withheld |
|---|---|---|---|---|
| 1 ROOM | 1,323 | 0 | 0.000% | n/a |
| 2 ROOM | 13,585 | 0 | 0.000% | n/a |
| 3 ROOM | 309,530 | 0 | 0.000% | n/a |
| 4 ROOM | 376,663 | 0 | 0.000% | n/a |
| 5 ROOM | 208,439 | 0 | 0.000% | n/a |
| EXECUTIVE | 73,064 | 0 | 0.000% | n/a |
| MULTI-GENERATION | 553 | 0 | 0.000% | n/a |
It currently withholds nothing, which is a statement about the register rather than about the rule.
What each figure is a figure of
Every HDB resale registered in the window. First-hand BTO sales are not resales and are not in this source.
Every residential block in the area, from HDB Property Information, including blocks that have never transacted. Non-residential blocks (carparks, markets, pavilions) are excluded.
Resales in the window as a share of the flats that were legally ABLE to sell, annualised. A flat inside its five-year Minimum Occupation Period cannot be resold, so it is excluded from the denominator; without that, young estates are mechanically understated and two areas of different vintage are not comparable. Nationally this runs at roughly 2 to 3 percent a year.
MOP runs from the first owner taking keys, which the published data does not give. Completion year plus five is the closest available proxy.
Price and floor area arrive on the same HDB record, so unlike England and Wales there is no address match to run, no match rate to publish and no matching bias to correct for.
Uncertainty
A 95% interval on every published median, from order statistics: for a sample of n, the (n/2 +/- 1.96*sqrt(n)/2)-th ordered values bracket the population median.
Distribution-free, and exact for the statistic actually published. A median with no interval invites a reader to treat two areas 1 percent apart as different when the samples cannot tell.
The same interval per quarter where the quarter holds at least 20 resales; this is the band behind the trend line.
The confidence label beside a headline grades the width of that interval as a share of the figure itself: High within ±3%, Medium within ±6%, Low wider than that. The thresholds were set for this market rather than copied from the UK build, whose ±5 and ±10 would have graded 71% of Singapore’s areas High and drained the label of meaning. Two areas whose medians differ by less than their intervals cannot be told apart by their samples, and the compare pages say exactly that rather than crowning a winner.
Rounding
Three significant figures on every price per unit area.
A median of 693 sales is not precise to the dollar, and printing $971.43 would claim it is.
Remaining lease
Every HDB flat is a 99-year leasehold, and the remaining lease is the figure the whole market prices against: financing tightens as the tail shortens, CPF usage is restricted against it, and a 49-year flat and an 87-year flat are different assets at the same address. So the lease figure on this site comes from HDB’s own published value, not from arithmetic. The resale files carry a remaining-lease column from 2015 onwards, in two formats across the years, and both are parsed; for transactions before HDB published one, the value is computed as 99 years from the lease commencement date.
The distinction matters because the arithmetic is wrong in a way that is invisible until it is measured. Lease commencement year plus 99 ignores the month the lease started, and mis-bands 3.79% of the rows from 2023 onwards against HDB’s own figure, 3,564 transactions in that span alone. Every lease surface on the site, the price-by-lease bands, the median lease beside every yield and the two lease league tables, derives from the published column where it exists, and the build fails if a parseable value goes unparsed.
The price-by-lease section on an area page conditions on the area’s reference flat type, so the curve is a lease effect rather than a mix effect, and it requires at least 8 resales in each band over up to 36 months before drawing anything. Where fewer than two bands clear that, the section says so instead of disappearing.
The quarterly series
Quarterly medians back to 1990. A quarter with fewer than ten resales publishes no median and leaves a gap in the line; its sales still count and its volume bar is still drawn, because a count needs no sample. The newest quarter is marked provisional while the anchor month is not its third, and is excluded from every growth figure.
Restated with SingStat Consumer Price Index (All Items), in 2026-06 money.
Growth endpoints are averaged over up to three quarters at each end, so a single unusual quarter cannot swing the figure.
Compound annual change between the two named quarters, in cash terms.
Geography
The hierarchy is region, then district, then neighbourhood: three levels, each one a measured subset of the one above, from URA Master Plan 2019 boundaries. Nothing is in it that does not nest: 0 districts cross a region boundary and 0 neighbourhoods cross a district boundary. Street is not a level. A road crosses these boundaries too often to be one, so it resolves a search to the page that publishes its figures instead, and a road crossing a neighbourhood line resolves to its district rather than picking a side.
URA Master Plan 2019. A block is assigned by point-in-polygon on its own coordinate where OpenStreetMap has one, otherwise by its street, and only where the blocks already resolved on that street agree.
Where an area does not lie wholly inside a layer, that rung is left out rather than guessed, and the same rule resolves a street search: a road that runs through more than one neighbourhood resolves to its district, the finest level all of it agrees on. A missing rung costs one level of detail; a chosen one would put a sale in the wrong market.
URA’s postal districts (D1–D28) and market segments (CCR/RCR/OCR) are not part of this taxonomy and have no pages. Neither nests: a postal district cuts across the districts here, 10 of 160 neighbourhoods straddle one, and a market segment is defined over a postal district and a planning area at once. A classification that cannot be an ancestor is not a level. The postal-district names remain searchable, and answer with every district and neighbourhood they cover rather than picking one.
CCR, RCR and OCR follow URA's own definition, which reads both postal district and planning area at once, which is exactly why they cannot be a parent of either. The Central Region is part CCR and part RCR, and its page says so.
Postal sector was tested as a level and refused. 15 of the 53 sectors with resale data straddle a planning-area boundary and those 15 hold 34.8% of all transactions, so a sector level would assert a containment that is false for a third of the market. It is kept internally, as the lookup from a postcode to its district.
How a transaction is placed
HDB publishes a block and a street on every resale, and placement runs in strict order of evidence quality. A block whose own coordinate is known is placed by point-in-polygon against the URA Master Plan 2019 boundaries. A block with no coordinate inherits from its street, first by the consensus of the other addresses on that street, then by the street’s centreline, and a street centreline is trusted for neighbourhood-level placement only when at least two independent points support it: one frozen point asserting subzone certainty for a 21-block street is exactly the class of false precision the rule exists to refuse. A block that none of those can place is published as unplaced rather than guessed, because a guess renders identically to a fact.
Which rung placed each block ships in the data (placed_by), and the area pages state it: a measured placement and an inherited one must not read identically. The universe of blocks itself is derived from the registers inside the pipeline on every run, so the geography cannot depend on a file the repository does not carry, and the whole placement is deterministic: the build runs the pipeline twice and fails unless all 1,138 published payloads are byte-identical.
Entities are keyed on URA’s own codes rather than on their names, and each build diffs code-to-name against the previous baseline, so a Master Plan revision that renames a subzone produces a redirect rather than a broken page and a duplicate.
How much of the register each level covers
Every transaction belongs to exactly one entity at each level below, or to none of them; where it belongs to none, it is counted here rather than dropped. “Recent” is the 12 months every published figure is drawn from; “all years” is the 1990-01 to July 2026 register behind the long trend charts, where the gaps are.
| Level | Recent | All years | Not placed, all years |
|---|---|---|---|
| Region | 100.0% | 99.9% | 499 |
| District | 99.8% | 99.8% | 2,399 |
| Neighbourhood | 99.6% | 99.1% | 8,604 |
| Street | 100.0% | 99.9% | 499 |
Where a block cannot be placed, it is COUNTED as unplaced rather than dropped or guessed at. The remainder is almost entirely blocks in estates demolished in the 1990s, which no coordinate source has ever held; they affect the long trend charts and no current figure. Every level is checked on each build to make sure its placed and unplaced rows still add up to the whole register.
Rent and yield
Rent self-declared by the flat owner on the renting-out application and approved by HDB. It is not a registry price and not an asking rent.
HDB withholds a median where a town and flat type had fewer than 20 approved rentals in the last 12 months; so does this site.
Gross yield is a year of median rent divided by the median resale price FOR THE SAME FLAT TYPE. An area-wide rent over an area-wide price is a mix artefact: the rental market skews to small flats and the resale market to large ones.
A yield is published only where its two halves cover the identical 12 months: both sides clear 30, the price side is on the 12-month window, and the two registers agree on the latest complete month. Where any of that fails the yield is withheld with the reason stated, never computed across mismatched spans.
Every HDB flat is a 99-year leasehold, so a gross yield here is not comparable to a freehold yield. A shorter lease is cheaper to buy and therefore yields more while wasting faster; the remaining lease is published beside every yield.
The HDB rental register carries its own anchor month, computed by the same rule as the resale register’s (the latest month holding at least 40% of the baseline volume), and the yield is withheld whenever the two anchors disagree: a ratio whose numerator and denominator end in different months is not a yield, it is two statistics wearing one name. On the private side the join is stricter still: URA reports rental floor areas in bands, so a private yield is computed only where the rental band is exactly ten square metres wide and matches the sale band like for like. Wider bands exist in the register and are excluded from yields entirely, because a 61%-contaminated band match produces a plausible-looking figure with no meaning.
Revisions
HDB restates months as registrations land. Each build compares itself against the last and refuses to ship on a transaction-count move beyond 10 percent.
Every check the pipeline ran for the build you are reading, and its result, is published at /data/quality.json, and the table at the end of this page renders it in full.
Citing these figures
Every statistical page carries a citation line naming the page, the dataset version and the licences, and links its own data as JSON. When citing a figure, cite its window and its count with it: “the median 4-room resale price in Tampines” is not one number across time, it is a number per window, and the dataset version is what makes a quoted figure checkable against the build that produced it. The full dataset behind every page is described at /dataset, and the machine-readable endpoints at /api.
Sources
| Dataset | Publisher | Grain | Coverage | Licence |
|---|---|---|---|---|
| HDB Resale Flat Prices | HDB via Data.gov.sg | transaction | 1990-01 to 2026-07 | SODL v1.0 |
| HDB Property Information | HDB via Data.gov.sg | block | current residential stock | SODL v1.0 |
| URA Master Plan 2019 boundaries | URA via Data.gov.sg | subzone / planning area / region | all of Singapore | SODL v1.0 |
| List of Postal Districts | URA, crediting SingPost | district | all of Singapore | public reference |
| Consumer Price Index (All Items) | SingStat via Data.gov.sg | month | to 2026-06 | SODL v1.0 |
| Block coordinates | OpenStreetMap | block | see the geography section | ODbL |
| Private residential transactions (caveats) | Urban Redevelopment Authority, Data Service | caveat | 2021-08 to 2026-08 | URA Data Service terms: derived statistics only, records not redistributed |
| Private residential lease contracts | Urban Redevelopment Authority, Data Service | lease contract | 2021-07 to 2026-06 | URA Data Service terms: derived statistics only, records not redistributed |
| Renting Out of Flats | HDB via Data.gov.sg | approved rental application | 2021-01 to 2026-07 | SODL v1.0 |
What the build checks before it ships
The pipeline refuses to publish data that fails an invariant, and warns on data that moved more than expected since the last build. This is the result for the build you are reading.
63 of 63 checks passed
| Check | Result |
|---|---|
| transactions present | 983,157 transactions (expected >900,000) |
| geography closes | districts hold 24,262 of the 24,284 in regions |
| every median carries its sample and window | all published medians carry both |
| no figure without sales | none |
| low-sample medians are flagged | 19 area(s) below 30 sales, all flagged Low with a parent to compare against |
| turnover is published | 191 areas carry a turnover rate (expected >100) |
| turnover is plausible | 191 areas carry a turnover rate, max 6.4%/yr |
| outlier fence is not editorialising | 0% of priced rows withheld (0 of 983157) |
| the taxonomy has its three levels, whole | 5 regions, 55 districts, 332 neighbourhoods: every Master Plan entity has a page |
| geographic ids are unique | 392 areas, no duplicate id or slug within a level |
| breadcrumbs follow the spine | 392 payloads; every chain is a prefix of region > area > subzone |
| no orphaned geographic links | every ancestor, child and facet link resolves |
| no published page is unreachable | 307 pages are linked from a submarket table or the streets hub |
| strict containment closes both ways | region>area and area>neighbourhood are exact inverses |
| facets never appear as ancestors | no breadcrumb places a page under a market segment or a postal district |
| every fallback parent publishes a median | no page quotes a parent that has no figure |
| every non-leaf publisher carries a reconciliation | 36 region and district pages each carry one |
| spine totals reconcile exactly | 36 of 36 parents reconcile to the transaction; 105 transaction(s) reach no child and are counted as such |
| every transaction at the finest grain carries an address | 155 neighbourhoods, every counted resale on a named block |
| index region figures match the region pages | 5 regions quote one median each |
| coverage is published for every level | 11 rows over 4 levels and 2 scopes |
| every level accounts for every transaction | 11 level-scopes close exactly; residual published, not absorbed |
| every level measures the same register | 983,157 transactions, all-time, at every level |
| the private register measures one denominator | 135,166 caveats at every private level |
| levels are mutually exclusive | 3 levels: one entity per transaction, no double counting |
| URA subzone names are globally unique | 332 polygons, 332 distinct names, none shared across planning areas |
| ci contains its median | every published interval brackets its own median |
| ci bounds are ordered | no reversed interval |
| every quarter key is a quarter | all trend points carry an integer year and q in 1-4 |
| sold-price list is the whole window | every payload ships exactly its own window |
| a thin hero names its parent | every hero below 30 carries a parent pointer |
| a rate rests on rows that carry a rate | no rate published on fewer than 10 usable rows |
| no private cut pools sale types | every private cut names its sale type |
| private headline reconciles with its cuts | every headline count equals its own segment row |
| a launch rate rests on launch sales | no new-sale rate published on fewer than 10 caveats |
| only the newest quarter is provisional | every partial flag is on the final point |
| mix adjustment agrees with its coverage | no area withholds a mix figure it had the coverage for |
| the confidence pill grades a published figure | every pill rates a hero interval, and none sits on an unpublishable one |
| turnover publishes its own denominator | every turnover rate ships the stock it was computed on |
| a yield rests on two full samples | every published yield clears 30 on both sides in one 12-month window |
| a rental rate carries its coverage | every published rental rate states the projects behind it |
| a private yield rests on two full samples | every private yield clears 30 lettings and 30 resales in one band |
| no yield is matched on bedrooms | yields are matched on area band, the key both registers share |
| rental quarters are real and only the newest is provisional | every rental trend point is a whole quarter |
| the two rental registers stay separate | each rental block names its own register and window |
| the MOP cohort fits inside its own stock | every published cohort is a subset of the stock it comes from |
| a rental rate names its own quarter | every published rental rate states the quarter it covers |
| the private trend flags its newest quarter | every private trend carries a partial flag on the newest quarter only |
| no league table mixes windows | every table ranks one window |
| every private figure carries sample and window | private medians all carry n and window_months |
| no zero coordinates | no entity ships a null-island coordinate |
| no rental rate is derived from a banded area | every published rental rate is URA's own, with its quarter and its project count |
| no public rental flat enters a MOP cohort | every cohort sits inside the sold, resaleable stock |
| the hero equals the table row it comes from | every hero matches its own flat-type row on price, rate and count |
| no payload outlives its index | 392 payloads, all present in their level index |
| URA entity names are stable | 332 URA codes carry the same names as the last build |
| transaction count drift | 0.00% vs the last build (983,157 → 983,157) |
| region count stable | 5 → 5 |
| area count stable | 55 → 55 |
| subzone count stable | 332 → 332 |
| the coverage ratchet still measures what it pins | 11 level-scopes pinned, all still produced |
| geographic coverage has not fallen | 11 level-scopes at or above the last build |
| median stability | no area median moved more than 15% |
The private market
This site publishes two registers, and never combines them. HDB resale prices come from the Housing & Development Board via Data.gov.sg. URA Data Service: private residential caveats (sales) and lease contracts (rentals), both rolling five-year windows.
Private and HDB are published side by side and never combined: different buyers, eligibility, tenure, and a three- to five-fold price gap. A median across both would describe neither. Where an area has both, both are shown side by side; where it has only one, the page says which.
The private headline is RESALE. A new sale is a developer pricing unbuilt stock at launch, and blending the two put District 9 at $2,995/ft2 against a resale reality of $2,330: 59 percent of its caveats were launches, and 52 percent came from two projects. The launch median is published beside the headline, never inside it.
Price per unit area covers strata units only. A landed plot is measured by its land area, so its rate is not comparable to an apartment's floor area; landed sales keep their price and their place in every count.
The two registers also record different events. An HDB resale is registered on completion, weeks after the price is agreed. A URA caveat is lodged when the buyer exercises the option, so it sits closer to the agreed price, but lodging is not compulsory and recent months are still filling in, which is why the private window ends on the last month that is substantially complete rather than on the same month as the HDB one.
Measured across Singapore, new sales run 41 to 42 per cent above resales per square foot in every part of the island, which is why the two are never pooled. Executive condominiums are separated for a different reason: an EC is sold under HDB eligibility rules with a five-year minimum occupation period, so it is cheaper than a comparable condominium because of its restrictions rather than its location, and folding it into the condominium figure would pull that figure down for reasons no buyer of either product experiences. Collective (en-bloc) sales are land transactions between owners and a developer, and are counted separately from dwelling resales; they are never given a price per square foot.
Private rents and yields
Private rents come from lease contracts lodged with URA. A published rental price per square foot is URA's OWN median, not one computed here: URA reports each contract's floor area as a BAND rather than a figure, so a rate cut from contract data would be a band-midpoint estimate wearing the precision of a measurement. The number of projects behind that rate is published with it, and it covers roughly a third of the projects that transact rather than the whole market.
Private gross yield is a year of median rent divided by the median resale price FOR UNITS OF THE SAME FLOOR-AREA BAND, over the same twelve months, and only where both sides clear 30 transactions. Matching on size is what stops it being a mix artefact: the rental market skews to small units and the sale market to large ones. Gross means before maintenance, property tax, agent fees, income tax and vacancy.
URA records a bedroom count on a rental contract and does not record one on a sale caveat, so bedrooms describe what renting costs and can never be matched to what buying costs. Contracts with no bedroom count are excluded from that table and counted rather than folded into a bucket.
HDB and private rents are two registers and are never combined. HDB counts approved renting-out applications; URA counts lodged lease contracts. The only figure that legitimately spans them is the gross yield, because it is a dimensionless ratio, and even there the assets differ: every HDB flat is a 99-year lease that cannot be let at all during its first five years, while a private unit may be freehold.
Comparing two areas
The compare pages apply every rule above at once, which makes them the strictest surface on the site. A pair is offered only where both sides publish, so the picker cannot lead to an empty page. The verdict, which area is dearer, is computed on the mix-adjusted rate, never the raw one, and it is suppressed entirely when the two medians’ 95% intervals overlap: the honest sentence there is that the samples cannot tell the two areas apart, and the page says exactly that instead of crowning a winner by a margin narrower than the noise. Where the two sides publish on different windows, the verdict is withheld and both windows are stated. Nothing on a compare page averages the two areas, and nothing on it compares an HDB figure with a private one.
The policy timeline
Singapore’s resale market moves on policy as much as on demand: loan-to-value ceilings, the Mortgage Servicing Ratio, Additional Buyer’s Stamp Duty rounds and grant changes each mark visible breaks in the series. The quarterly charts therefore carry the major cooling and support measures as a dated list beside the chart, not as annotations painted onto it: a list can be read, cited and corrected, while an annotation at a chart’s scale is decoration. Each event states its date, and the list states the date it was last reviewed, so a measure announced after that date is a known gap rather than a silent one. The affordability tab’s figures (BSD and ABSD schedules, the LTV ceiling, MSR and TDSR at the regulated stress rate) each carry an as-at date in the data, and the build warns when any of them falls more than a year behind the dataset anchor, because a stale rule stated confidently is worse than none.
Addresses and names
HDB records street names in abbreviated source forms, and the site expands them before they reach a heading, a title or a sentence: Bt to Bukit, Jln to Jalan, Lor to Lorong, Ave to Avenue, C’wealth to Commonwealth, and the rest of the standard set. Names are title-cased once, in one function, at the pipeline, so a street cannot be spelt three ways on three surfaces. Where an expanded street name collides with a neighbourhood’s (a Lorong 8 Toa Payoh street inside a Lorong 8 Toa Payoh neighbourhood), the street’s pages say the word street, so no two pages share a title. HDB’s own town names are an alias layer rather than a page level: most HDB towns match a planning area of the same name and resolve straight to it, and the two that straddle several (Central Area, Kallang/Whampoa) resolve to every planning area that covers them, listed, rather than to one silent guess.
How this site is tested
The build is the test suite. Before a page is written, the pipeline’s output passes a validation gate that checks the data’s invariants: every level’s placed and unplaced counts sum to the register, no published median sits below its floor, every ordered list agrees with the league tables’ estimator, and coverage may not fall by more than a tenth of a percentage point against the recorded baseline without the change being deliberate. After the pages are rendered, a second gate reads the HTML itself and checks the sentences: that the answer paragraph and the machine-readable answer are one string, that a claimed window matches the emitted one, that no page carries an impossible percentage, that suppressed figures render their reasons. The pipeline is then run twice and the build fails unless every published data file is byte-identical across the two runs. The full result of every check, for the build you are reading, is published at /data/quality.json and rendered at the end of this page.
What this site does not cover
First-hand sales are not here. BTO flats sold by HDB and the developer’s own first-hand records are not resale transactions and are not in either source, beyond the launch caveats URA lodges.
Net yields are not published. What a landlord actually keeps depends on maintenance, property tax, agent fees, vacancy and their own tax position, none of which this site knows. Every yield here is gross and says so.
No valuation, of any kind. This site publishes statistics about transactions that have already happened. It does not estimate what any particular flat or unit is worth.
No distance factors, yet. Distance to an MRT station and school catchments move prices, and no figure here adjusts for either, because no data layer on this site currently measures them. That is stated as a limit rather than bolted on badly: a distance adjustment needs its own geocoded source, its own methodology and its own gates, and it will be added as one or not at all.
No income-based affordability. The affordability tab computes the transaction costs and financing rules that apply to a purchase (stamp duties, the loan ceilings, MSR and TDSR at the regulated stress rate); it makes no claim about local incomes, because no income data at this geography exists in the sources.
Search an area
Median HDB resale price per square foot, resales and price history for any district or neighbourhood in Singapore.