The Roth IRA is the rare financial product that sounds too good and basically is that good: you put in money you’ve already paid tax on, it grows for decades, and you withdraw every dollar — contributions and all that growth — completely tax-free in retirement. No tax on the gains, ever, if you follow the rules.
Investment Growth
What will your investments grow to?
$
$
%
yrs
Estimated value in 15 years
$0
Invested $0Est. gains $0
Year-by-year growth
Illustration only. Market returns are not guaranteed and do not arrive in a straight line. Start investing →
+(n/1e6).toFixed(2).replace(/.?0+$/,'')+'M';
if(n>=1e3)return '≈ $'+(n/1e3).toFixed(0)+'K';
return '';
}
function num(id){return parseFloat($('#lzp-'+id+'-n').value.replace(/[^0-9.]/g,''))||0;}
function clamp(v,a,b){return Math.min(b,Math.max(a,v));}
function setPair(id,v){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
v=clamp(v,+r.min,+r.max); r.value=v;
var grouped=(id==='amt'||id==='target'); n.value=grouped?Math.round(v).toLocaleString('en-US'):v;
r.style.setProperty('--p',((v-r.min)/(r.max-r.min)*100)+'%');
}
// seeded RNG for stable realistic paths
function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;var t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
function gauss(rng){var u=0,v=0;while(u===0)u=rng();while(v===0)v=rng();return Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*v);}
// smooth SIP corpus per year (optionally stepping the monthly amount up annually)
function smoothSeries(P,rate,Y,stepPct){
var i=rate/1200, out=[], corpus=0, monthly=P, invested=0;
for(var y=1;y<=Y;y++){
for(var m=0;m<12;m++){corpus=(corpus+monthly)*(1+i);invested+=monthly;}
out.push({inv:invested,val:corpus});
monthly=monthly*(1+stepPct/100);
}
return out;
}
// realistic dispersion: S simulated paths, return p10/p50/p90 per year
function realisticBand(P,rate,Y,stepPct){
var mean=rate/100, vol=0.18, S=60, perYear=[];
for(var y=0;y=0;i--)bot+=' L'+X(i).toFixed(1)+' '+Yc(band[i].p10).toFixed(1);
svg+='';
svg+='';
}
// invested area
var invArea='M0 '+Yc(series[0].inv).toFixed(1);for(i=1;i';
// projection line
svg+='';
if(stepSeries){svg+='';}
$('#lzp-chart').innerHTML=svg;
var axis='',step=Math.max(1,Math.round(n/6));
for(var y=1;y<=n;y+=step)axis+=''+y+'y';
$('#lzp-axis').innerHTML=axis;
}
function donut(invPct){
var C=2*Math.PI*50;
var arc=$('#lzp-arc'),arc2=$('#lzp-arc2');
arc.style.strokeDasharray=C;arc2.style.strokeDasharray=C;
arc.style.strokeDashoffset=C*(invPct/100); // gain shown = remainder
arc2.style.strokeDashoffset=C*(1-invPct/100); // invested portion
arc2.setAttribute('transform','rotate('+(-90+(1-invPct/100)*360)+' 60 60)');
}
function key(){
var k='';
if(realistic)k+='Likely range ';
k+='Projection';
if(stepUp)k+='With step-up';
$('#lzp-ckey').innerHTML=k;
}
function calc(){
var rate=num('rate'), Y=Math.round(num('yrs'));
$('#lzp-yo').textContent=Y;
var P;
if(mode==='goal'){
var target=num('target');
P=solveGoal(target,rate,Y);
$('#lzp-rlabel').innerHTML='Invest about';
$('#lzp-big').textContent=fmt(P)+' /mo';
$('#lzp-words').textContent='to reach '+fmt(target)+' '+(words(target)||'')+' in '+Y+' years';
} else {
P=num('amt');
}
var series=smoothSeries(P,rate,Y,stepUp?10:0);
var last=series[series.length-1]||{inv:0,val:0};
var invested=last.inv, total=last.val, gains=total-invested;
if(mode==='project'){
$('#lzp-rlabel').innerHTML='Estimated value in '+Y+' years';
$('#lzp-big').textContent=fmt(total);
$('#lzp-words').textContent=words(total);
}
$('#lzp-inv').textContent=fmt(invested);
$('#lzp-gain').textContent=fmt(gains);
donut(total>0?invested/total*100:100);
var band=realistic?realisticBand(P,rate,Y,stepUp?10:0):null;
var stepSeries=null; // step-up already folded into series when on
draw(series,band,null); key();
$('#lzp-ctitle').textContent=realistic?'Growth — projection vs realistic range':'Year-by-year growth';
// extra notes
var ex='';
if(realistic&&band){
var b=band[band.length-1];
ex+='Real returns are lumpy, not a straight line. With typical equity swings, the same '+rate+'% average most often lands between '+fmt(b.p10)+' and '+fmt(b.p90)+' — median '+fmt(b.p50)+'. The order good and bad years arrive in matters as much as the average.';
}
if(inflation){
var f=6, real=total/Math.pow(1+f/100,Y);
if(ex)ex+='
';
ex+='In today\u2019s money that\u2019s about '+fmt(real)+' '+(words(real)||'')+' (after '+f+'% inflation).';
}
if(stepUp){
var flat=smoothSeries(P,rate,Y,0);
var diff=last.val-flat[flat.length-1].val;
if(ex)ex+='
';
ex+='Stepping your investment up 10% a year adds about '+fmt(diff)+' versus keeping it flat.';
}
$('#lzp-extra').hidden=!ex; $('#lzp-extra').innerHTML=ex;
}
// wire inputs
['amt','target','rate','yrs'].forEach(function(id){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
r.addEventListener('input',function(){setPair(id,+r.value);calc();});
n.addEventListener('input',function(){var v=num(id);if(v)setPair(id,v);calc();});
n.addEventListener('blur',function(){setPair(id,num(id));calc();});
var p=(r.value-r.min)/(r.max-r.min)*100; r.style.setProperty('--p',p+'%');
});
root.querySelectorAll('.lzp-seg-btn').forEach(function(btn){
btn.addEventListener('click',function(){
root.querySelectorAll('.lzp-seg-btn').forEach(function(b){b.classList.remove('is-on');});
btn.classList.add('is-on'); mode=btn.getAttribute('data-mode');
$('.lzp-proj').hidden=(mode!=='project'); $('.lzp-goal').hidden=(mode!=='goal');
$('#lzp-h').textContent=(mode==='goal')?'How much do you need to invest?':'What will your investments grow to?';
calc();
});
});
function pill(id,setter){var el=$('#'+id);el.addEventListener('click',function(){var on=el.getAttribute('aria-pressed')!=='true';el.setAttribute('aria-pressed',on);setter(on);calc();});}
pill('lzp-step',function(v){stepUp=v;});
pill('lzp-real',function(v){realistic=v;});
pill('lzp-infl',function(v){inflation=v;});
$('.lzp-goal').hidden=true;
calc();
})();
+(n/1e3).toFixed(0)+'K';
return '';
}
function num(id){return parseFloat($('#lzp-'+id+'-n').value.replace(/[^0-9.]/g,''))||0;}
function clamp(v,a,b){return Math.min(b,Math.max(a,v));}
function setPair(id,v){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
v=clamp(v,+r.min,+r.max); r.value=v;
var grouped=(id==='amt'||id==='target'); n.value=grouped?Math.round(v).toLocaleString('en-US'):v;
r.style.setProperty('--p',((v-r.min)/(r.max-r.min)*100)+'%');
}
// seeded RNG for stable realistic paths
function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;var t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
function gauss(rng){var u=0,v=0;while(u===0)u=rng();while(v===0)v=rng();return Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*v);}
// smooth SIP corpus per year (optionally stepping the monthly amount up annually)
function smoothSeries(P,rate,Y,stepPct){
var i=rate/1200, out=[], corpus=0, monthly=P, invested=0;
for(var y=1;y<=Y;y++){
for(var m=0;m<12;m++){corpus=(corpus+monthly)*(1+i);invested+=monthly;}
out.push({inv:invested,val:corpus});
monthly=monthly*(1+stepPct/100);
}
return out;
}
// realistic dispersion: S simulated paths, return p10/p50/p90 per year
function realisticBand(P,rate,Y,stepPct){
var mean=rate/100, vol=0.18, S=60, perYear=[];
for(var y=0;y=0;i--)bot+=' L'+X(i).toFixed(1)+' '+Yc(band[i].p10).toFixed(1);
svg+='';
svg+='';
}
// invested area
var invArea='M0 '+Yc(series[0].inv).toFixed(1);for(i=1;i';
// projection line
svg+='';
if(stepSeries){svg+='';}
$('#lzp-chart').innerHTML=svg;
var axis='',step=Math.max(1,Math.round(n/6));
for(var y=1;y<=n;y+=step)axis+=''+y+'y';
$('#lzp-axis').innerHTML=axis;
}
function donut(invPct){
var C=2*Math.PI*50;
var arc=$('#lzp-arc'),arc2=$('#lzp-arc2');
arc.style.strokeDasharray=C;arc2.style.strokeDasharray=C;
arc.style.strokeDashoffset=C*(invPct/100); // gain shown = remainder
arc2.style.strokeDashoffset=C*(1-invPct/100); // invested portion
arc2.setAttribute('transform','rotate('+(-90+(1-invPct/100)*360)+' 60 60)');
}
function key(){
var k='';
if(realistic)k+='Likely range ';
k+='Projection';
if(stepUp)k+='With step-up';
$('#lzp-ckey').innerHTML=k;
}
function calc(){
var rate=num('rate'), Y=Math.round(num('yrs'));
$('#lzp-yo').textContent=Y;
var P;
if(mode==='goal'){
var target=num('target');
P=solveGoal(target,rate,Y);
$('#lzp-rlabel').innerHTML='Invest about';
$('#lzp-big').textContent=fmt(P)+' /mo';
$('#lzp-words').textContent='to reach '+fmt(target)+' '+(words(target)||'')+' in '+Y+' years';
} else {
P=num('amt');
}
var series=smoothSeries(P,rate,Y,stepUp?10:0);
var last=series[series.length-1]||{inv:0,val:0};
var invested=last.inv, total=last.val, gains=total-invested;
if(mode==='project'){
$('#lzp-rlabel').innerHTML='Estimated value in '+Y+' years';
$('#lzp-big').textContent=fmt(total);
$('#lzp-words').textContent=words(total);
}
$('#lzp-inv').textContent=fmt(invested);
$('#lzp-gain').textContent=fmt(gains);
donut(total>0?invested/total*100:100);
var band=realistic?realisticBand(P,rate,Y,stepUp?10:0):null;
var stepSeries=null; // step-up already folded into series when on
draw(series,band,null); key();
$('#lzp-ctitle').textContent=realistic?'Growth — projection vs realistic range':'Year-by-year growth';
// extra notes
var ex='';
if(realistic&&band){
var b=band[band.length-1];
ex+='Real returns are lumpy, not a straight line. With typical equity swings, the same '+rate+'% average most often lands between '+fmt(b.p10)+' and '+fmt(b.p90)+' — median '+fmt(b.p50)+'. The order good and bad years arrive in matters as much as the average.';
}
if(inflation){
var f=6, real=total/Math.pow(1+f/100,Y);
if(ex)ex+='
';
ex+='In today\u2019s money that\u2019s about '+fmt(real)+' '+(words(real)||'')+' (after '+f+'% inflation).';
}
if(stepUp){
var flat=smoothSeries(P,rate,Y,0);
var diff=last.val-flat[flat.length-1].val;
if(ex)ex+='
';
ex+='Stepping your investment up 10% a year adds about '+fmt(diff)+' versus keeping it flat.';
}
$('#lzp-extra').hidden=!ex; $('#lzp-extra').innerHTML=ex;
}
// wire inputs
['amt','target','rate','yrs'].forEach(function(id){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
r.addEventListener('input',function(){setPair(id,+r.value);calc();});
n.addEventListener('input',function(){var v=num(id);if(v)setPair(id,v);calc();});
n.addEventListener('blur',function(){setPair(id,num(id));calc();});
var p=(r.value-r.min)/(r.max-r.min)*100; r.style.setProperty('--p',p+'%');
});
root.querySelectorAll('.lzp-seg-btn').forEach(function(btn){
btn.addEventListener('click',function(){
root.querySelectorAll('.lzp-seg-btn').forEach(function(b){b.classList.remove('is-on');});
btn.classList.add('is-on'); mode=btn.getAttribute('data-mode');
$('.lzp-proj').hidden=(mode!=='project'); $('.lzp-goal').hidden=(mode!=='goal');
$('#lzp-h').textContent=(mode==='goal')?'How much do you need to invest?':'What will your investments grow to?';
calc();
});
});
function pill(id,setter){var el=$('#'+id);el.addEventListener('click',function(){var on=el.getAttribute('aria-pressed')!=='true';el.setAttribute('aria-pressed',on);setter(on);calc();});}
pill('lzp-step',function(v){stepUp=v;});
pill('lzp-real',function(v){realistic=v;});
pill('lzp-infl',function(v){inflation=v;});
$('.lzp-goal').hidden=true;
calc();
})();
+(n/1e6).toFixed(2).replace(/.?0+$/,'')+'M';
if(n>=1e3)return '≈ $'+(n/1e3).toFixed(0)+'K';
return '';
}
function num(id){return parseFloat($('#lzp-'+id+'-n').value.replace(/[^0-9.]/g,''))||0;}
function clamp(v,a,b){return Math.min(b,Math.max(a,v));}
function setPair(id,v){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
v=clamp(v,+r.min,+r.max); r.value=v;
var grouped=(id==='amt'||id==='target'); n.value=grouped?Math.round(v).toLocaleString('en-US'):v;
r.style.setProperty('--p',((v-r.min)/(r.max-r.min)*100)+'%');
}
// seeded RNG for stable realistic paths
function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;var t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
function gauss(rng){var u=0,v=0;while(u===0)u=rng();while(v===0)v=rng();return Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*v);}
// smooth SIP corpus per year (optionally stepping the monthly amount up annually)
function smoothSeries(P,rate,Y,stepPct){
var i=rate/1200, out=[], corpus=0, monthly=P, invested=0;
for(var y=1;y<=Y;y++){
for(var m=0;m<12;m++){corpus=(corpus+monthly)*(1+i);invested+=monthly;}
out.push({inv:invested,val:corpus});
monthly=monthly*(1+stepPct/100);
}
return out;
}
// realistic dispersion: S simulated paths, return p10/p50/p90 per year
function realisticBand(P,rate,Y,stepPct){
var mean=rate/100, vol=0.18, S=60, perYear=[];
for(var y=0;y=0;i--)bot+=' L'+X(i).toFixed(1)+' '+Yc(band[i].p10).toFixed(1);
svg+='';
svg+='';
}
// invested area
var invArea='M0 '+Yc(series[0].inv).toFixed(1);for(i=1;i';
// projection line
svg+='';
if(stepSeries){svg+='';}
$('#lzp-chart').innerHTML=svg;
var axis='',step=Math.max(1,Math.round(n/6));
for(var y=1;y<=n;y+=step)axis+=''+y+'y';
$('#lzp-axis').innerHTML=axis;
}
function donut(invPct){
var C=2*Math.PI*50;
var arc=$('#lzp-arc'),arc2=$('#lzp-arc2');
arc.style.strokeDasharray=C;arc2.style.strokeDasharray=C;
arc.style.strokeDashoffset=C*(invPct/100); // gain shown = remainder
arc2.style.strokeDashoffset=C*(1-invPct/100); // invested portion
arc2.setAttribute('transform','rotate('+(-90+(1-invPct/100)*360)+' 60 60)');
}
function key(){
var k='';
if(realistic)k+='Likely range ';
k+='Projection';
if(stepUp)k+='With step-up';
$('#lzp-ckey').innerHTML=k;
}
function calc(){
var rate=num('rate'), Y=Math.round(num('yrs'));
$('#lzp-yo').textContent=Y;
var P;
if(mode==='goal'){
var target=num('target');
P=solveGoal(target,rate,Y);
$('#lzp-rlabel').innerHTML='Invest about';
$('#lzp-big').textContent=fmt(P)+' /mo';
$('#lzp-words').textContent='to reach '+fmt(target)+' '+(words(target)||'')+' in '+Y+' years';
} else {
P=num('amt');
}
var series=smoothSeries(P,rate,Y,stepUp?10:0);
var last=series[series.length-1]||{inv:0,val:0};
var invested=last.inv, total=last.val, gains=total-invested;
if(mode==='project'){
$('#lzp-rlabel').innerHTML='Estimated value in '+Y+' years';
$('#lzp-big').textContent=fmt(total);
$('#lzp-words').textContent=words(total);
}
$('#lzp-inv').textContent=fmt(invested);
$('#lzp-gain').textContent=fmt(gains);
donut(total>0?invested/total*100:100);
var band=realistic?realisticBand(P,rate,Y,stepUp?10:0):null;
var stepSeries=null; // step-up already folded into series when on
draw(series,band,null); key();
$('#lzp-ctitle').textContent=realistic?'Growth — projection vs realistic range':'Year-by-year growth';
// extra notes
var ex='';
if(realistic&&band){
var b=band[band.length-1];
ex+='Real returns are lumpy, not a straight line. With typical equity swings, the same '+rate+'% average most often lands between '+fmt(b.p10)+' and '+fmt(b.p90)+' — median '+fmt(b.p50)+'. The order good and bad years arrive in matters as much as the average.';
}
if(inflation){
var f=6, real=total/Math.pow(1+f/100,Y);
if(ex)ex+='
';
ex+='In today\u2019s money that\u2019s about '+fmt(real)+' '+(words(real)||'')+' (after '+f+'% inflation).';
}
if(stepUp){
var flat=smoothSeries(P,rate,Y,0);
var diff=last.val-flat[flat.length-1].val;
if(ex)ex+='
';
ex+='Stepping your investment up 10% a year adds about '+fmt(diff)+' versus keeping it flat.';
}
$('#lzp-extra').hidden=!ex; $('#lzp-extra').innerHTML=ex;
}
// wire inputs
['amt','target','rate','yrs'].forEach(function(id){
var r=$('#lzp-'+id),n=$('#lzp-'+id+'-n'); if(!r)return;
r.addEventListener('input',function(){setPair(id,+r.value);calc();});
n.addEventListener('input',function(){var v=num(id);if(v)setPair(id,v);calc();});
n.addEventListener('blur',function(){setPair(id,num(id));calc();});
var p=(r.value-r.min)/(r.max-r.min)*100; r.style.setProperty('--p',p+'%');
});
root.querySelectorAll('.lzp-seg-btn').forEach(function(btn){
btn.addEventListener('click',function(){
root.querySelectorAll('.lzp-seg-btn').forEach(function(b){b.classList.remove('is-on');});
btn.classList.add('is-on'); mode=btn.getAttribute('data-mode');
$('.lzp-proj').hidden=(mode!=='project'); $('.lzp-goal').hidden=(mode!=='goal');
$('#lzp-h').textContent=(mode==='goal')?'How much do you need to invest?':'What will your investments grow to?';
calc();
});
});
function pill(id,setter){var el=$('#'+id);el.addEventListener('click',function(){var on=el.getAttribute('aria-pressed')!=='true';el.setAttribute('aria-pressed',on);setter(on);calc();});}
pill('lzp-step',function(v){stepUp=v;});
pill('lzp-real',function(v){realistic=v;});
pill('lzp-infl',function(v){inflation=v;});
$('.lzp-goal').hidden=true;
calc();
})();
For 2026 you can contribute up to $7,500 (or $8,600 if you’re 50 or older), as long as your income is under the limits — the ability to contribute starts phasing out around $153,000 for single filers and $242,000 for married couples filing jointly. The calculator above shows what those yearly contributions can become; the magic is that the entire ending balance is yours, untaxed.
Why does this matter so much? Because you’re betting that tax-free growth beats a deduction today — which is usually true if you’re young or in a lower bracket now than you’ll be later. A 25-year-old funding a Roth is locking in today’s low tax rate on money that might grow tenfold by retirement, all of it tax-free. That’s an extraordinary deal.
A few things worth knowing. You can withdraw your contributions (not the earnings) anytime without penalty, which makes a Roth a surprisingly flexible backstop — though raiding it sabotages the whole point. If you earn too much to contribute directly, the “backdoor Roth” is a legal workaround worth researching. And a Roth has no required withdrawals in your lifetime, so it’s also a powerful way to leave money to heirs.
The order of operations most people should follow: grab the full 401(k) match first, then max a Roth IRA, then circle back to the 401(k). Open one even if you can only put in a little — what matters most is starting the tax-free clock early. Few accounts reward youth this generously.
General information, not financial advice. Limits and phase-outs are for 2026 and change.
Vaibhav
Engineer by profession, curious soul , trying to find my place in the world