Skip to content
🛠️ToolsShed

Vesting Schedule Calculator

Calculate your equity vesting schedule with cliff, monthly, quarterly, or annual vesting.

About this tool

A vesting schedule calculator helps employees and option holders understand how their equity compensation becomes available over time. Equity vesting is a common component of compensation packages, especially at startups and tech companies, but the mechanics can be complex with cliffs, vesting periods, and different acceleration schedules. This tool lets you model your specific vesting scenario—whether it's a cliff followed by monthly vesting, quarterly milestones, or annual grants—so you can see exactly when your shares or options become yours to keep or sell.

To use the calculator, enter your total equity amount, the vesting cliff period (often one year before any shares vest), and your preferred vesting interval—monthly, quarterly, or annual. The tool will display a timeline showing how much equity vests at each interval, cumulative vesting progress, and the remaining unvested amount. This is especially useful when evaluating job offers, planning your financial strategy, or checking your eligibility to exercise options before a company event.

Frequently Asked Questions

Code Implementation

from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

def generate_vesting_schedule(
    total_shares, grant_date, vesting_years=4,
    cliff_months=12, frequency="monthly"
):
    freq_map = {"monthly": 1, "quarterly": 3, "annually": 12}
    period_months = freq_map[frequency]
    total_months = vesting_years * 12
    schedule = []
    cumulative = 0

    month = period_months
    while month <= total_months:
        vest_date = grant_date + relativedelta(months=month)
        is_cliff = cliff_months > 0 and month == max(
            (cliff_months // period_months) * period_months, period_months
        ) and month >= cliff_months

        if cliff_months > 0 and month < cliff_months:
            month += period_months
            continue

        if is_cliff:
            cliff_shares = round(cliff_months / total_months * total_shares)
            period_shares = cliff_shares
        elif month + period_months > total_months:
            period_shares = total_shares - cumulative
        else:
            period_shares = round(period_months / total_months * total_shares)

        cumulative += period_shares
        schedule.append({
            "date": vest_date, "period_shares": period_shares,
            "cumulative": cumulative, "pct": cumulative / total_shares * 100,
            "is_cliff": is_cliff
        })
        month += period_months

    return schedule

# 10,000 shares, 4 years, 1-year cliff, monthly vesting
schedule = generate_vesting_schedule(10000, date.today())
for row in schedule[:6]:
    cliff = " (CLIFF)" if row["is_cliff"] else ""
    print(f"{row['date']}: +{row['period_shares']} shares | {row['cumulative']:,} total | {row['pct']:.1f}%{cliff}")

Comments & Feedback

Comments are powered by Giscus. Sign in with GitHub to leave a comment.