Stamp Duty Land Tax#

Stamp Duty Land Tax (SDLT) is a tax imposed on the purchase and rental of properties or land with values over a certain threshold in England and Northern Ireland. It applies to both residential and non-residential (commercial) properties.

Stamp Duty Land Tax parameters can be found in policyengine_uk/parameters/gov/hmrc/stamp_duty and logic in policyengine_uk/variables/gov/hmrc/stamp_duty_land_tax.py.

Legislation#

The regulation of SDLT is defined in part 4 of the Finance Act 2003.

Rates#

The rates of SDLT depend on various factors, including the purchase price of the property, property type, and whether it is an additional property or a purchase by a first-time buyer. Generally, SDLT rates are higher for properties or land with a purchase price exceeding a specific threshold, often referred to as “stamp duty bands” or “stamp duty brackets.” The rules and thresholds for SDLT may change over time due to government policy adjustments. First-time buyers may be eligible for reduced SDLT rates if the purchase price of the property is not more than £500,000.

Here we show current rates and thresholds for SDLT under different situations in 2023 below:

  • Residential
    • Rent

      Up to £125,000: 0%

      Over £125,000: 1%

    • Purchase

      • Main property

        • First-time

          Up to £300,000: 0%

          £300,000 to £500,000: 5%

          Over £500,000: Ineligible for relief, follow standard rates

        • Subsequent (standard rates):

          Up to £125,000: 0%

          £125,000 to £250,000: 2%

          £250,000 to £925,000: 5%

          £925,000 to £1,500,000: 10%

          Over £1,500,000: 12%

      • Additional property

        An additional 3% on top of the standard rates for each band. However, a secondary property or land with a purchase price or market value less than £40,000 will be exempt from SDLT.

        Less than £40,000: 0%

        £40,000 to £125,000: 3%

        £125,000 to £250,000: 5%

        £250,000 to £925,000: 8%

        £925,000 to £1,500,000: 13%

        Over £1,500,000: 15%

  • Non-residential
    • Rent

      Up to £150,000: 0%

      £150,000 to £5,000,000: 1%

      Over £5,000,000: 2%

    • Purchase

      Up to £150,000: 0%

      £150,000 to £250,000: 2%

      Over £250,000: 5%

    Hide code cell source
    import pandas as pd
    import plotly.express as px
    from policyengine_core.charts import format_fig
    
    residential_rent = pd.DataFrame(
        {
            "Threshold": [0, 125000, 5200000],
            "Rate": [0, 0.01, 0.01],
            "Label": ["Residential rent"] * 3,
        }
    )
    residential_purchase_main_first = pd.DataFrame(
        {
            "Threshold": [0, 300000, 500000, 925000, 1500000, 5200000],
            "Rate": [0, 0.05, 0.05, 0.1, 0.12, 0.12],
            "Label": ["Residential purchase main (first home)"] * 6,
        }
    )
    residential_purchase_main_standard = pd.DataFrame(
        {
            "Threshold": [0, 125000, 250000, 925000, 1500000, 5200000],
            "Rate": [0, 0.02, 0.05, 0.1, 0.12, 0.12],
            "Label": ["Residential purchase main standard"] * 6,
        }
    )
    residential_purchase_additional = pd.DataFrame(
        {
            "Threshold": [0, 40000, 125000, 250000, 925000, 1500000, 5200000],
            "Rate": [0, 0.03, 0.05, 0.08, 0.13, 0.15, 0.15],
            "Label": ["Residential purchase additional"] * 7,
        }
    )
    non_residential_rent = pd.DataFrame(
        {
            "Threshold": [0, 150000, 5000000, 5200000],
            "Rate": [0, 0.01, 0.02, 0.02],
            "Label": ["Non-residential rent"] * 4,
        }
    )
    non_residential_purchase = pd.DataFrame(
        {
            "Threshold": [0, 150000, 250000, 5200000],
            "Rate": [0, 0.02, 0.05, 0.05],
            "Label": ["Non-residential purchase"] * 4,
        }
    )
    df_list = [
        residential_rent,
        residential_purchase_main_first,
        residential_purchase_main_standard,
        residential_purchase_additional,
        non_residential_rent,
        non_residential_purchase,
    ]
    df = pd.concat(df_list)
    # plot
    fig = (
        px.line(
            df,
            x="Threshold",
            y="Rate",
            color="Label",
            title="Stamp duty land tax rates over property price thresholds",
        )
        .update_layout(
            yaxis_tickformat=",.0%",
            xaxis_tickprefix="£",
            legend=dict(
                orientation="h",
                yanchor="bottom",
                y=-0.3,
                xanchor="right",
                x=0.9,
                title="",
            ),
        )
        .update_traces(line_shape="hv")
    )
    fig = format_fig(fig)
    fig