Retirement savings by age calculator
At 40 with an income of 80,000, the benchmark is three times pay, a target of 240,000; with 180,000 saved you are at 75% of it, 60,000 behind. Use it as an educational check, not personal advice. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Age
- 40
- Annual income
- 80,000
- Current savings
- 180,000
- Target multiple
- 3
- Target savings
- 240,000
- Savings multiple
- 2.25
- Gap
- 60,000
How much should you have saved for retirement at your age? Financial planners and large plan providers often answer with a simple rule of thumb: a multiple of current annual salary that grows with age—about one times pay by thirty, three times by forty, six times by fifty, and ten times near full retirement age. This retirement savings by age calculator takes your age, annual income, and current retirement balance, looks up the interpolated salary-multiple benchmark for that age, multiplies it by income to form a dollar target, and reports how far ahead or behind you are. Results are educational benchmarks, not personalized advice: they ignore risk tolerance, pensions, Social Security, housing equity, and future raises, and they assume today’s income is a reasonable scale for the nest-egg goal.
How the salary-multiple benchmark works
The calculator uses a fixed, public-style age-to-multiple table inspired by widely cited Fidelity-style guidance: zero times pay at age twenty-five, one times at thirty, two at thirty-five, three at forty, four at forty-five, six at fifty, seven at fifty-five, eight at sixty, and ten at sixty-seven. Ages between those anchors receive a linear interpolation of the multiple so a forty-two-year-old is not forced into either the forty or forty-five bucket. Below twenty-five the multiple stays at zero; above sixty-seven it caps at ten.
Target savings equal the interpolated multiple times your stated annual income. Current savings are whatever you report as retirement capital—typically 401(k) and IRA balances plus other accounts earmarked for retirement. The gap is target minus current: a positive gap means you sit below the rule-of-thumb target; a negative gap means you exceed it.
Percent of target is current divided by target times one hundred when the target is positive. Status is behind if you are more than five percent under target, ahead if more than five percent over, and on track inside that band. Age must fall between eighteen and one hundred; income must be strictly positive; current savings must be non-negative.
When a quick savings check by age helps
Employers and benefits portals embed a quick check so employees can see whether their 401(k) balance sits near a published multiple without waiting for a full financial plan. Content teams generate scenario tables for ages thirty through sixty-five at several income levels without hand-coding the interpolation. Failed validation does not consume balance.
Keep requests small, pin rounded fields in tests, and you get a reproducible benchmark for blogs, LMS modules, and edge workers without standing up a full retirement projection engine.
What you can do with it
Personal nest-egg check
Enter age, salary, and retirement balances to see whether you sit ahead, on track, or behind a salary-multiple target for your age.
Benefits and wellness portals
Embed a deterministic first-pass retirement check for employees before they open a full plan or talk to an advisor.
Content and scenario tables
Generate age-and-income benchmark grids for articles and calculators without hand-writing interpolation logic.
FAQ
How much should I have saved for retirement at my age?
This tool applies a Fidelity-style salary-multiple table (for example about 1× pay by 30, 3× by 40, 6× by 50, 10× by 67), multiplies the age-specific multiple by your annual income, and compares that target to your current savings.
Is this personalized financial advice?
No. It is a deterministic educational benchmark based only on age, income, and current savings. It ignores pensions, Social Security, housing, taxes, and investment risk. Use a qualified advisor for personal decisions.
How are ages between the benchmark points handled?
The multiple is interpolated in a straight line between the anchor ages, so between 40 and 50 you get a value between three and six times pay instead of a jump. Below 25 it stays at zero, and above 67 it is capped at ten.
What do behind, on track and ahead mean?
You are behind when your savings are more than 5% below the target, ahead when they are more than 5% above it, and on track anywhere inside that band.
Which savings and income should I enter?
Enter your current annual gross income and the money you hold for retirement: retirement accounts plus any other accounts earmarked for it. Use the same currency for both figures.
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/finance/retirement-savings-by-age \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"age":40,"annual_income":80000,"current_savings":180000}'const res = await fetch("https://api.kit.forhosting.com/finance/retirement-savings-by-age", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"age": 40,
"annual_income": 80000,
"current_savings": 180000
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/finance/retirement-savings-by-age",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"age": 40,
"annual_income": 80000,
"current_savings": 180000
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/finance/retirement-savings-by-age", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"age":40,"annual_income":80000,"current_savings":180000}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"age":40,"annual_income":80000,"current_savings":180000}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/finance/retirement-savings-by-age", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"age": 40,
"annual_income": 80000,
"current_savings": 180000
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "finance.retirement_savings_by_age",
"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
How the salary-multiple benchmark works
When the target is zero (young ages on the table), the endpoint treats any non-negative balance as on track and reports one hundred percent of a zero dollar goal so clients do not divide by zero. Invalid inputs fail with invalid_input and are not billed.
Input contract, response shape, and using the numbers
Numeric strings are accepted when they parse as finite decimals. Example: age forty, annual income eighty thousand, current savings one hundred eighty thousand yields a three-times multiple, a two hundred forty thousand target, a sixty thousand gap, seventy-five percent of target, and status behind. Currency is unitless—pass dollars, euros, or any other unit consistently for income and savings. POST a JSON body with three required finite numbers: age (eighteen through one hundred), annual_income (or aliases income, salary, annual_salary) greater than zero, and current_savings (or aliases savings, nest_egg, balance) greater than or equal to zero. On success the body echoes the rounded inputs and returns target_multiple, target_savings, savings_multiple (current savings divided by income), gap, percent_of_target, status (ahead, on_track, or behind), benchmark set to fidelity_style_salary_multiple, and a short formula string. Pair the response with your own charts or contribution planners; this endpoint only evaluates the static age-and-income benchmark and does not project future growth, recommended savings rates, or withdrawal strategies. Rounding uses four decimal places for stable goldens and reproducible API tests across runtimes.
Where a retirement savings by age API earns its keep
Advisors and robo-onboarding flows use the endpoint as a first screen before collecting risk questionnaires, because a large gap flags urgency while an ahead status can shift the conversation to asset allocation.
Technical questions
What inputs does the retirement savings by age calculator need?
Three finite numbers: age (18–100), annual_income greater than zero, and current_savings greater than or equal to zero. Aliases income/salary and savings/nest_egg/balance are accepted.
What do ahead, on_track, and behind mean?
Behind means current savings are more than 5% under the dollar target; ahead means more than 5% over; on_track is inside that band (or any non-negative balance when the age multiple is still zero).
What does the retirement savings by age calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.