Disclosure: I'm Zayed, and I build ClearCalc Tools, a free calculator site. This post explains the logic behind one of its calculators.

Stamp Duty Land Tax (SDLT) in England and Northern Ireland is a banded tax, a bit like income tax: each slice of the price is charged at its own rate, and you add the slices up. A common mistake is to apply one rate to the whole price.

Current standard residential bands (from 1 April 2025)

Portion of the price Rate
Up to £125,000 0%
£125,001 to £250,000 2%
£250,001 to £925,000 5%
£925,001 to £1.5 million 10%
Above £1.5 million 12%

Source: GOV.UK, "Stamp Duty Land Tax: residential property rates". Always check GOV.UK for the current rules; first-time buyer relief and the surcharge for additional properties change the numbers.

The algorithm

const BANDS = [ { upTo: 125000, rate: 0 }, { upTo: 250000, rate: 0.02 }, { upTo: 925000, rate: 0.05 }, { upTo: 1500000, rate: 0.10 }, { upTo: Infinity, rate: 0.12 }, ]; function stampDuty(price) { let tax = 0; let lower = 0; for (const { upTo, rate } of BANDS) { if (price <= lower) break; const slice = Math.min(price, upTo) - lower; tax += slice * rate; lower = upTo; } return Math.round(tax); } console.log(stampDuty(300000)); // 5000 

Worked example: £300,000

  • First £125,000 at 0% = £0
  • Next £125,000 (to £250,000) at 2% = £2,500
  • Final £50,000 at 5% = £2,500
  • Total = £5,000

Things the simple version leaves out

  • First-time buyer relief (0% up to £300,000, 5% to £500,000, no relief above £500,000).
  • Additional properties: a surcharge of 5 percentage points on every band.
  • Non-UK residents: a further 2% surcharge.
  • Scotland (LBTT) and Wales (LTT) have completely different systems.

If you'd rather not code it, I put a version that handles the first-time buyer and additional-property cases here: https://clearcalctools.com/calculators/england-stamp-duty-calculator/ (my own site; it's free and has no sign-up).

Happy to hear how you'd structure the band table differently, e.g. for testing.