Investment fees calculator
On 10,000 earning 7% a year for 30 years, a 1% annual fee costs 18,687.64: you end with 57,434.91 instead of 76,122.55. See what an expense ratio really takes from a lump sum before you choose a fund. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Principal amount
- 10,000
- Annual return
- 7
- Fee percent
- 1
- Years
- 30
- Net return
- 6
- Future value without fees
- 76,122.55
- Future value with fees
- 57,434.91
- Fee cost
- 18,687.64
Investment fees look tiny on a factsheet and enormous after decades of compounding. A one percent annual expense ratio does not merely shave one percent off the ending balance: it reduces the growth rate every year, so the missed return never compounds. This investment fees calculator accepts four numbers—principal, expected annual return as a percent, annual fee as a percent, and years—and returns the future value without fees, the future value with fees, and the dollar cost of that drag. It does not pick a fund, convert currencies, layer a separate advisor wrap on top of a fund TER, or schedule extra deposits.
What investment fees cost and how the closed form works
An annual investment fee, whether it is labelled an expense ratio, a total expense ratio, or a management fee, is subtracted from the gross return each year before the remaining balance compounds. That is why a one percent fee is not a one percent haircut on the final nest egg. If the portfolio is expected to earn seven percent before fees, a one percent fee leaves a six percent net return, and the gap between seven and six compounds for every year of the horizon.
The identity used here is the textbook annual model: future value without fees equals principal times one plus the gross return, raised to the number of years; future value with fees equals principal times one plus the gross return minus the fee, raised to the same years; the cost of fees is the difference of those two future values. Percents arrive as percents: seven means seven percent per year, not zero point zero seven, and one means a one percent annual fee.
Zero years leaves the principal unchanged with a zero fee cost. A zero fee makes the two future values identical, which is the right check when you want a no-fee baseline. Negative fees are rejected rather than treated as a bonus return, because a rebate is not an expense ratio.
This capability does not add regular contributions, switch to monthly fee accrual, or model performance fees with a high-water mark; those are different identities and different search intents.
What you can do with it
Expense-ratio comparisons for a lump sum
Project how a 0.05% index fund versus a 1% active fund changes the same principal over ten, twenty, or thirty years at a stated gross return.
Advice and coaching sessions
Show a client the dollar cost of an annual wrap or TER on a retirement lump sum without building a custom spreadsheet for each meeting.
FAQ
How is the cost of investment fees calculated?
Future value without fees is P × (1 + r)^t and future value with fees is P × (1 + r − f)^t, where r and f are the annual return and fee as decimals (percent divided by 100) and t is years. The fee cost is the difference of those two future values.
Does this include extra deposits or a separate advisor wrap?
No. It compounds a single lump sum once per year.
Why doesn't a 1% fee just cost 1% of my final balance?
Because the fee is taken from the return every year, so the growth you lose never gets to compound. Over 30 years at 7%, a 1% fee takes about a quarter of the no-fee ending balance.
Should I enter a 7% return as 7 or as 0.07?
Enter 7. Returns and fees are typed as percents, so 7 means seven percent a year and 1 means a one percent fee. Typing 0.07 would mean seven hundredths of a percent.
How do I compare an index fund with an active fund?
Run the same principal, return and years twice, once with each fund's annual fee, for example 0.05% and 1%. A fee of zero gives you the no-fee baseline to compare both against.
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/investment-fees \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"principal":10000,"annual_return":7,"fee_percent":1,"years":30}'const res = await fetch("https://api.kit.forhosting.com/fin/investment-fees", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"principal": 10000,
"annual_return": 7,
"fee_percent": 1,
"years": 30
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fin/investment-fees",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"principal": 10000,
"annual_return": 7,
"fee_percent": 1,
"years": 30
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fin/investment-fees", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"principal":10000,"annual_return":7,"fee_percent":1,"years":30}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"principal":10000,"annual_return":7,"fee_percent":1,"years":30}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fin/investment-fees", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"principal": 10000,
"annual_return": 7,
"fee_percent": 1,
"years": 30
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fin.investment_fees",
"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.
Limits
max_principal | 1000000000000 |
max_years | 120 |
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
It evaluates the annual identity in pure arithmetic so a worksheet, a coaching session, and an API client never disagree.
Input contract, response shape, and error behaviour
A fee of zero is valid. Example: ten thousand principal, seven percent gross, one percent fee, and thirty years yields a no-fee future value of seventy-six thousand one hundred twenty-two point fifty-five, a with-fee future value of fifty-seven thousand four hundred thirty-four point ninety-one, and a fee cost of eighteen thousand six hundred eighty-seven point sixty-four. Failed validation does not consume balance. POST a JSON body with four required finite numbers. principal is the starting lump sum in one currency; aliases amount, p, starting_balance, and investment are accepted so spreadsheets can keep familiar column names, and the value must sit between zero and one trillion inclusive. annual_return is the expected gross annual percent—seven means seven percent per year—not a decimal zero point zero seven unless you truly intend seven hundredths of a percent; aliases rate, return_rate, annual_rate, and return map to the same field. fee_percent is the annual fee as a percent of assets, with aliases fee, expense_ratio, ter, and annual_fee; the contracted error is a negative fee, which fails with invalid_input naming fee_percent and is not billed. Fees above one hundred percent are rejected as outside the declared range. years is t, a finite number from zero through one hundred twenty; fractional years such as twelve point five are allowed, and aliases t, time, and horizon are accepted. Each field may arrive as a JSON number or a numeric string. On success the body echoes principal, annual_return, fee_percent, and years, reports net_return as the gross percent minus the fee percent, and returns future_value_without_fees, future_value_with_fees, and fee_cost rounded half-up to two decimal places so the identity fee_cost equals the difference of the two rounded future values, plus a formula string restating the two powers.
Where an investment fees calculator earns its keep
Households and savers use an investment fees calculator when a fund factsheet, a robo-advisor quote, or a brokerage wrap asks what a seemingly small annual percent will cost over a decade or a working life. Fee-only planners and index-fund coaches need a deterministic oracle that rejects a negative fee instead of silently treating a minus sign as a rebate that a buggy form might treat as success. When you later need regular deposits, switch to a future-value-of-annuity identity rather than stretching this four-field lump-sum contract. Product teams wire the same contract into onboarding demos so a user who types a principal, a gross return, an expense ratio, and a horizon sees the identical future_value_with_fees the API will later return in production tests. Keep requests small, pin the rounded future values and fee_cost in tests, and you get reproducible fee-drag figures for worksheets, LMS plugins, and edge workers without standing up a spreadsheet service of your own.
Integration use cases
Product demos and CI fixtures
Seed investing apps and automated tests with deterministic future_value_with_fees and fee_cost values that match the free browser widget byte-for-byte.
Technical questions
Are annual_return and fee_percent percents or decimals?
Percents. Send 7 for a seven percent gross return and 1 for a one percent annual fee. Sending 0.07 would be treated as seven hundredths of a percent, not seven percent.
What happens if the fee is negative?
The task fails with invalid_input. A negative fee_percent is rejected and is not billed, because a rebate is not an expense ratio.
What does the investment fees calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.