SSI#

The Supplemental Security Income (SSI) program is a federal program that provides cash benefits to low-income elderly people and people with disabilities. Some states also supplement the federal SSI with additional payments.

Examples#

A single eligible person—someone with a disability, blindness, or 65 years of age or older, and who holds $2,000 in assets or less–will receive the full $841 monthly benefit if they have no other income. Their benefit phases out with earned income until the person earns $1,770 per month, at which point they are no longer eligible.

If they have $500 per month in unearned income (for example, Social Security), they will receive $361 if they have no earned income, and will continue to receive some benefit until they earn $790 per month.

from policyengine_us import IndividualSim
import pandas as pd
import plotly.express as px

LIGHT_GRAY = "#F5F5F5"
GRAY = "#BDBDBD"
BLUE = "#5091cc"
LIGHT_BLUE = "lightblue"
DARK_BLUE = "darkblue"


def make_ssi(social_security=0, vary="employment_income"):
    sim = IndividualSim(year=2022)
    sim.add_person(
        name="head", is_ssi_disabled=True, social_security=social_security
    )
    sim.vary(vary, max=30_000, step=120)
    employment_income = sim.calc("employment_income")[0]
    ssi = sim.calc("ssi")[0]
    mtr = -sim.deriv("ssi", "employment_income", wrt_target="head")
    return pd.DataFrame(
        dict(
            employment_income=employment_income,
            ssi=ssi,
            mtr=mtr,
            social_security=social_security,
        )
    )


# Compute for different values of Social Security income.
l = []
for ss in [0, 500 * 12]:
    l.append(make_ssi(social_security=ss))

df = pd.concat(l)

# Make monthly.
df[["employment_income", "ssi", "social_security"]] /= 12
df.social_security = "$" + df.social_security.astype(int).astype(str)

LABELS = dict(
    employment_income="Monthly employment income",
    ssi="Monthly Supplemental Security Income",
    mtr="SSI marginal tax rate",
    social_security="Monthly Social Security",
)

COLOR_MAP = {"$0": DARK_BLUE, "$500": BLUE}

fig = px.line(
    df,
    "employment_income",
    "ssi",
    color="social_security",
    labels=LABELS,
    title="Supplemental Security Income for a single person",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat="$,",
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()

SSI phases out at 50% with respect to employment income, after exemptions.

fig = px.line(
    df,
    "employment_income",
    "mtr",
    color="social_security",
    labels=LABELS,
    title="SSI marginal tax rate for a single eligible person",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat=".0%",
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()

Single parent with two disabled children#

With no Social Security, the household will receive the maximum combined SSI payment of $1,682 until the parent’s income reaches $1,840, at which point it starts phasing out at 50 cents on the dollar until it’s fully phased out at $5,220 monthly income.

def make_ssi(social_security=0, vary="employment_income"):
    sim = IndividualSim(year=2022)
    sim.add_person(name="parent", social_security=social_security)
    sim.add_person(name="child1", age=10, is_ssi_disabled=True)
    sim.add_person(name="child2", age=8, is_ssi_disabled=True)
    sim.add_tax_unit(name="tax_unit", members=["parent", "child1", "child2"])
    sim.vary(vary, max=72_000, step=120)
    employment_income = sim.calc("employment_income")[0]
    ssi = sim.calc("tax_unit_ssi")[0]
    mtr = -sim.deriv("tax_unit_ssi", "employment_income", wrt_target="parent")
    return pd.DataFrame(
        dict(
            employment_income=employment_income,
            ssi=ssi,
            mtr=mtr,
            social_security=social_security,
        )
    )


# Compute for different values of Social Security income.
l = []
for ss in [0, 500 * 12]:
    l.append(make_ssi(social_security=ss))

df = pd.concat(l)

# Make monthly.
df[["employment_income", "ssi", "social_security"]] /= 12
df.social_security = "$" + df.social_security.astype(int).astype(str)

fig = px.line(
    df,
    "employment_income",
    "ssi",
    color="social_security",
    labels=LABELS,
    title="Supplemental Security Income for a single parent and two disabled children",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat="$,",
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()

The parent faces a 50% marginal tax rate over the phase-out range.

fig = px.line(
    df,
    "employment_income",
    "mtr",
    color="social_security",
    labels=LABELS,
    title="SSI marginal tax rate for a single parent of two disabled children",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat=".0%",
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()