FIRE calculator
Spending 40,000 a year at a 4% withdrawal rate needs a portfolio of 1,000,000. With 100,000 saved, 30,000 added each year and a 7% return, you reach it in 14.6951 years. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Annual expenses
- 40,000
- Withdrawal rate
- 4
- Current savings
- 100,000
- Annual savings
- 30,000
- Annual return
- 7
- Withdrawal decimal
- 0.04
- Expense multiple
- 25
- Target portfolio
- 1,000,000
- Shortfall
- 900,000
The FIRE movement — Financial Independence, Retire Early — is a two-part arithmetic problem: first size the portfolio that can fund yearly spending from withdrawals alone, then count how many years of saving it takes to accumulate that portfolio. This FIRE calculator returns both figures from one deterministic contract. The independence target is annual expenses divided by the safe withdrawal rate expressed as a percent over one hundred, the Trinity-study identity behind the four percent rule. Years to that target come from compounding current savings at an expected annual return and adding an annual savings contribution at the end of each year.
The FIRE number and the safe withdrawal rate
The FIRE number is the invested portfolio that can cover a chosen lifestyle from withdrawals, without a paycheck. Equivalently, the target is annual expenses times the expense multiple one hundred over the withdrawal rate. A four percent rate is the familiar twenty-five-times rule; three percent is about thirty-three times; five percent is twenty times.
Those multiples are not magic constants. They encode a judgment about sequence-of-returns risk, inflation, longevity, and how much earned income or later pension you still expect. A more conservative plan lowers the withdrawal rate and therefore raises the target; a plan that keeps some work or a state pension can raise the rate and shrink the number.
This calculator does not pick the rate for you and does not default it to four.
Years to independence from savings and expected return
Sizing the target is only half of a FIRE plan. The other half is the calendar: given what you have saved, what you add each year, and the return you expect, how many years until the portfolio hits the target. Annual savings are modeled as an ordinary annuity credited at the end of each year, the conservative convention for an annual FIRE sketch.
Solving for n yields n equals the natural log of (target plus contribution over r) divided by (current plus contribution over r), all over the natural log of (one plus r). Years are rounded half-up to four decimal places so goldens compare byte-for-byte. The model is a constant-return sketch, not a Monte Carlo: it does not simulate sequence-of-returns risk, inflation indexing, taxes, or variable contributions, and it does not pick a market forecast for you.
What you can do with it
Headline FIRE number and countdown
Turn yearly spending, a chosen safe withdrawal rate, current savings, and a savings rate into the independence portfolio and the years left to reach it.
Coaching dashboards and independence widgets
Embed a deterministic FIRE target and timeline in advice tools and personal-finance lessons without a Monte Carlo engine or a planning vendor.
FAQ
How are years to FIRE calculated?
The closed-form n is returned as years. If you are already at or above the target, years is 0.
Why is a zero withdrawal rate rejected?
A rate of zero would require an infinite portfolio. Send a percent greater than zero, for example 4 for 4%.
What if I am already financially independent?
The target is still returned so you can compare it with the nest egg you hold.
Which withdrawal rate should I use?
The calculator does not pick one for you. A 4% rate means 25 times your yearly spending; a lower rate raises the target and a higher one shrinks it. The choice reflects market risk, inflation, longevity and any income you still expect.
Does it account for inflation, taxes or market swings?
No. It assumes one constant yearly return and fixed contributions, without simulating the order of returns, inflation, taxes or changing savings. Treat the years as a sketch and try other returns to see how they move.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fin/fire \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"annual_expenses":40000,"withdrawal_rate":4,"current_savings":100000,"annual_savings":30000,"annual_return":7}'const res = await fetch("https://api.kit.forhosting.com/fin/fire", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"annual_expenses": 40000,
"withdrawal_rate": 4,
"current_savings": 100000,
"annual_savings": 30000,
"annual_return": 7
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/fire",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"annual_expenses": 40000,
"withdrawal_rate": 4,
"current_savings": 100000,
"annual_savings": 30000,
"annual_return": 7
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/fire", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"annual_expenses":40000,"withdrawal_rate":4,"current_savings":100000,"annual_savings":30000,"annual_return":7}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"annual_expenses":40000,"withdrawal_rate":4,"current_savings":100000,"annual_savings":30000,"annual_return":7}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/fire", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"annual_expenses": 40000,
"withdrawal_rate": 4,
"current_savings": 100000,
"annual_savings": 30000,
"annual_return": 7
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.fire",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
A withdrawal rate of zero cannot size a portfolio and fails with invalid_input.
The FIRE number and the safe withdrawal rate
The identity used by the Trinity study and by most writing about a safe withdrawal rate is one division: target_portfolio equals annual_expenses divided by (withdrawal_rate over one hundred). You send annual_expenses and withdrawal_rate explicitly so the result is a function of your assumptions, not a hidden rule of thumb. The response echoes both inputs, reports withdrawal_decimal (the rate divided by one hundred), reports expense_multiple, and returns target_portfolio rounded half-up to two decimal places so currency displays stay stable across runtimes. A rate of zero would imply an infinite portfolio; that request is rejected rather than returning Infinity, and it is the required invalid_input path for this capability. Pair the static target with a sustainability simulator if you need a path through sequence-of-returns risk; this first half of the payload is the Trinity-style headline number only.
Years to independence from savings and expected return
This endpoint solves that in closed form. Current savings compound at annual_return percent per year. When the return is zero, years equals the remaining shortfall divided by annual_savings. When the return is not zero, the identity is target equals current times (one plus r) to the n plus contribution times ((one plus r) to the n minus one) over r, with r equal to annual_return over one hundred. If current savings already meet or exceed the target, years is zero and already_independent is true. If contributions and return cannot close the gap — for example a zero return with no savings, or a negative return whose equilibrium sits below the target — the task fails with invalid_input instead of emitting Infinity.
Input contract, errors, and where a FIRE API earns its keep
Negative expenses or savings balances are rejected. The required error path is a withdrawal rate that is not greater than zero: zero cannot size a FIRE portfolio and is not billed. Example: forty thousand of expenses at four percent with one hundred thousand saved, thirty thousand of annual savings, and a seven percent return yields a one million target and a finite years figure from the annuity identity. Keep the withdrawal rate positive, pin the rounded target and years in tests, and you get a reproducible independence number and timeline for widgets, course modules, and edge workers. POST a JSON body with five required finite numbers. annual_expenses is planned yearly spending in currency units, greater than or equal to zero; aliases expenses, spending, yearly_expenses, and annual_spend are accepted. withdrawal_rate is the safe withdrawal rate as a percent, not a fraction: send four for four percent, not 0.04. Aliases swr, swr_percent, and safe_withdrawal_rate are accepted. current_savings is the invested nest egg today; aliases current, nest_egg, portfolio, and principal are accepted. annual_savings is the amount added at the end of each year; aliases contribution, savings, and yearly_savings are accepted. annual_return is the expected percent return per year, which may be zero (no real growth) but must stay above negative one hundred so that one plus r stays positive; aliases return_percent, growth_rate, and expected_return are accepted. Each field may arrive as a JSON number or as a numeric string. Missing fields, empty strings, booleans, and non-finite values fail with invalid_input naming the field. On success the body includes the echoed inputs, withdrawal_decimal, expense_multiple, target_portfolio, shortfall, years, already_independent, and a short formula string.
Integration use cases
Rate and savings scenario tables
Sweep withdrawal_rate, annual_savings, or annual_return on the same expenses to show how conservative assumptions move both the target and the calendar.
Technical questions
How is the FIRE number calculated?
target_portfolio equals annual_expenses divided by (withdrawal_rate/100). At a 4% rate, $40,000 of yearly spending returns $1,000,000, which is the 25× expense multiple.
What does the FIRE calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.