Skip to content

Source-of-truth document

Methodology

Where haio’s numbers come from, how comparables are chosen, and what this dataset cannot tell you. Written so a journalist can cite a figure on any property page without legal or factual exposure, and so a first-time buyer can decide whether to trust it.

Retrieved 2026-06-03· coverage refreshed hourly

1. Coverage

1.1 Data sources

haio is a join over four public Singapore datasets. Nothing here is proprietary; every figure on the site can be reproduced from the sources below.

SourceCoversLast refreshRows last run
URA (Urban Redevelopment Authority)Private resale caveats — condo, apartment, EC, private landed. 1995–present.2026-06-0282,136
HDB via data.gov.sgHDB resale transactions, full historical depth. Daily delta from 2026-06-02 onwards.2026-06-020
SLA OneMapLanded property registry, polygon-keyed addresses.2026-06-02101,814
MAS (Monetary Authority of Singapore)SORA daily snapshots (1m / 3m / 6m), used for mortgage rate display only.

— means the source had not yet written a watermark at page-build time. All four datasets are public and free; haio adds no proprietary data on top.

1.2 Coverage by tenure

Live counts from the address-keyed properties and transactions tables. Pulled at page build, refreshed hourly.

HDB
9,972 blocks
1,207,537 txns
Condo / Apartment / EC
3,125 projects
597,065 txns
Landed
96,931 addresses
81,306 txns

Corpus total: 1,885,908 transactions across 110,028 addresses.

1.3 Update cadence

  • Daily cron on the Valcan worker, scheduled 19:00–22:00 UTC (03:00–06:00 Singapore time). Delta writes only — the watermark per source is in sync_state above.
  • SORA refreshed daily. URA caveats land roughly weekly behind URA’s own release schedule (caveats are lodged retrospectively).
  • HDB resale: full historical backfill is in the database; the daily delta is keyed by last_max_updated_at to avoid the memory pressure of re-uploading the full 1.2M-row corpus each run.

2. Comparable selection

On every property page, the “Comparable transactions” table is populated by the following query (source: lib/data/comparables.ts). The filter is deliberately conservative — a buyer should be able to walk to every comparable.

  • Same district as the subject property.
  • Same tenure cohort (HDB, condo, or landed) — never mixed.
  • Floor area within ±15% of the subject’s area_sqft.
  • Transacted in the last 3 years, rolling from page-load date.
  • Ordered by txn_date DESC, default LIMIT 12.

No locality (street-level) filter, no price filter, no outlier trimming. What you see is what URA / HDB recorded, filtered by the five rules above.

3. Price estimate

The estimate on each property page is the median price-per-square-foot (PSF) of the comparables defined in §2, multiplied by the subject property’s floor area. Source: lib/estimate.ts.

3.1 Range, not a point

The displayed PSF range is the 25th–75th percentile of comparable PSFs (the interquartile range), not a fixed ±percent band. This makes the range tighter where the market is tight and wider where it is dispersed, which is the honest behaviour.

3.2 Gating

  • n < 1 (no comparables in scope): no estimate. The card shows the last recorded sale instead, if one exists.
  • 1 ≤ n < 5: estimate is shown but marked “indicative, wide uncertainty band” with the n explicit. The page never hides that the sample is thin.
  • n ≥ 5: estimate shown without caveat (other than the universal “not an appraisal” disclaimer).

3.3 Time window

Comparables are drawn from the last 3 years (per §2). The estimate card’s default narrative window is 12 months, settable per page via the windowMonthsprop. The number on the card is always the median of whatever set of comparables matched the §2 rules.

4. Lease decay

Leasehold property value decays with remaining tenure. We surface a projected residual value on leasehold pages using the Bala’s Tablecoefficients — the standard curve published by SLA / URA for leasehold valuation.

Implementation: lib/calculators/lease-decay.ts. Eleven anchor points from 99 years remaining (multiplier 1.000) down to 0 years (multiplier 0.000); intermediate years are linearly interpolated between adjacent anchors.

Applied only when tenure_type is 99 or 999 AND lease_start is populated. Freehold and properties with unknown lease start show no decay projection.

5. Affordability: LTV / TDSR / MSR

The affordability calculator implements the MAS envelope as published in MAS Notice 645 (TDSR) and the corresponding MSR framework for HDB / EC purchases. Source: lib/calculators/affordability.ts.

TDSR cap
55% of gross monthly income, inclusive of all recurring debt obligations.
MSR cap
30% of gross monthly income, HDB and EC only. The tighter of TDSR and MSR binds.
Stress-test rate
4.00% p.a. — MAS-mandated medium-term rate. Used for the TDSR / MSR repayment calculation regardless of the live SORA rate, exactly as banks underwrite.
Default LTV
75% — standard first-loan LTV on a private property or an HDB resale bank loan. Lower (55% or 45%) tiers apply where the loan tenor extends past age 65, or beyond 25 (HDB) / 30 (private) years; surface those through the calculator’s tenor input.
Default tenor
30 years. Cap is 25 (HDB) / 30 (private) by regulation; the calculator enforces this.

This is a structural calculator, not a credit decision. Banks add their own underwriting (credit history, employment type, foreign-income haircut, etc.) on top.

5b. Mortgage rates

The Mortgage calculator quotes a monthly payment built from a live reference rate plus a bank spread. Two distinct rates do different jobs — one for the payment shown, one for the affordability check — and conflating them is a common source of confusion. Source: lib/calculators/mortgage.ts.

5b.1 SORA — the live reference

SORA (Singapore Overnight Rate Average) replaced SIBOR in 2024 as the MAS-endorsed reference for SGD floating-rate loans. The calculator uses the published 3-month compounded SORA from www.mas.gov.sg/statistics/sgs-rates, updated each business day. The headline rate you see at the top of the calculator is SORA + spread— this is what your actual monthly payment is computed against.

5b.2 MAS 4% stress test — the affordability gate

For TDSR / MSR (see section 5), MAS requires banks to underwrite at a medium-term floor of 4.00% p.a., regardless of the live SORA. This is a regulatory minimum to keep borrowers solvent if rates rise. Haio applies the same 4% rate inside the affordability check, exactly as a bank would. That means the maximum loan you qualify for is computed at 4%, while the monthly payment shownis computed at the live SORA + spread — usually lower.

5b.3 Bank spread variability

The spread over SORA (typically 50–100 basis points) varies by bank, by loan size, by lock-in tenor, and by whether the loan is for a private property, HDB resale, or commercial. The calculator uses a neutral default; real bank packages can come in tighter or wider. Treat the payment shown as directional — for a binding quote, speak to a mortgage broker or the lender directly.

6. Stamp duty

Implemented per IRAS-published bands. Source: lib/calculators/stamp-duty.ts.

6.1 BSD — Buyer’s Stamp Duty (residential)

Band of purchase priceRate
First $180,0001%
Next $180,0002%
Next $640,0003%
Next $500,0004%
Next $1,500,0005%
Remainder6%

6.2 ABSD — Additional Buyer’s Stamp Duty

Buyer1st property2nd property3rd+ property
Singapore Citizen0%20%30%
Singapore PR5%30%35%
Foreigner60% on every purchase
Entity / Trust65% on every purchase

6.3 SSD — Seller’s Stamp Duty

If the property is resold within:

  • 1 year: 12% of resale price
  • 2 years: 8%
  • 3 years: 4%
  • Beyond 3 years: nil

Source: IRAS Singapore. Rates correct as of the last review on 2026-06-02. ABSD remission schemes (matrimonial, mixed-nationality) are not modelled.

7. Known data limitations

What this dataset cannot tell you. Read this before citing a figure.

7.1 Cadastral-only landed addresses

Of the 96,931 landed addresses we surface, 50,903 (53%) come from the SLA polygon registry alone — we have a postal address but no transactional evidence (no caveat ever lodged). These pages carry a cadastral_onlyflag and explicitly say so. Treat them as “this address exists”, not “this address is on the market”.

7.2 Private leasehold reclassification

Prior to commit e803379 (2026-06-02), private condo rows defaulted tenure_type = freeholdwhen URA’s caveat had no explicit field. This systematically misclassified an unknown number of leasehold projects. The ETL now derives tenure_type and remaining_leasedirectly from URA’s parquet feed. If you are citing a tenure label, prefer a page retrieved after 2026-06-02.

7.3 Sparse HDB floor area

HDB area_sqft is missing on a non-trivial share of older resale rows. When a transaction has no area, no PSF can be computed; charts that aggregate PSF silently drop these. Whereall rows in scope lack area, the chart falls back to absolute price and labels the axis accordingly.

7.4 Floor band granularity

URA publishes the floor of a caveat as a 5-storey band (e.g. 06–10), not an exact floor. We surface the band as-is. Two units on different floors of the same band are indistinguishable to us.

7.5 HDB watermark seeded 2026-06-02

The historical HDB resale corpus is in the database. The daily delta-write watermark was seeded at 2026-06-02T04:00:58Z to keep the cron memory-bounded. Any HDB row with updated_at earlier than that came in via backfill; later rows came in via the daily delta.

7.6 What we don’t have

No rental yields are computed (rental data for HDB exists in our ETL but is not surfaced on property pages). No predicted appreciation. No future-supply impact modelling beyond the raw upcoming-supply registry. No agent or developer ratings. No listings; haio is a transaction-history site, not a marketplace.

8. How to cite haio

haio is a free public resource. We’d rather you cite the underlying URA / HDB / SLA / MAS sources where possible — haio is a convenience layer over them, not a separate authority. When a figure comes directly from a haio computation (e.g. our price estimate, our comparables ordering, our lease-decay projection), please attribute it.

Suggested format

Source: haio (https://haio.sg), based on URA / HDB / SLA /
MAS public data, retrieved 2026-06-03.

Per-property pages have stable URLs of the form /{tenure}/{slug}— for example /condo/the-orie or /hdb/ang-mo-kio-ave-3-block-123. Linking to a property page is the best way to let a reader audit the number you’re quoting.

9. Contact

Data corrections, methodology questions, or a row that looks wrong: wttg72@gmail.com. haio is built and maintained by one person in Singapore. The codebase is private; this document is the most authoritative public description of how it works.