DNA Mutation Accumulation & Lifespan Simulator

Scrub a simulated lifetime and watch how somatic DNA mutations accumulate. Bend the curve with repair efficiency, compare species, and see why the theoretical human ceiling sits near 156 years

Human — Cumulative somatic mutations per cellHomo sapiens
Projected Lifespan
Year 0 / 156
Curve at 0 mutations
Cell mutation burden — 24 × 12 tissue sample Mid

The 156-year estimate

A 2026 study modeled human lifespan as the time required for cumulative somatic DNA mutations to reach a burden incompatible with cellular function. By extrapolating the observed per-cell mutation rate and the efficiency of DNA repair machinery, the researchers estimated a theoretical ceiling near 156 years — well beyond today's maximum verified lifespans (~122 years

How the model works

Each cell acquires a roughly constant number of mutations per year. Repair pathways correct most of this damage, but a small fraction persists. Lifespan ends when the average cell's mutation burden crosses a critical threshold (~6,200 mutations in this model) at which essential genes can no longer function reliably

Species comparison

SpeciesRate/yrRepairCeiling
Human~47~90%~156 yr
Mouse~800~60%~2.5 yr
Naked mole rat~90~85%~30 yr
Bowhead whale~40~95%~200+ yr

Note: The 6,200-mutation threshold is a model-derived burden, not an established clinical limit. Real aging involves many interacting mechanisms beyond somatic mutation accumulation

Loading required library…

If this persists, refresh the page'; return; } const state={ currentYear:0, mutationRate:47, repairEfficiency:90, species:'human', isPlaying:false, whatIfMode:false, threshold:6200, maxYear:200, animFrame:null }; const speciesData={ human:{rate:47,repair:90,color:'#48cae4',name:'Human',latin:'Homo sapiens',lifespan:156}, mouse:{rate:800,repair:60,color:'#f72585',name:'Mouse',latin:'Mus musculus',lifespan:2.5}, naked_mole_rat:{rate:90,repair:85,color:'#ffb703',name:'Naked Mole Rat',latin:'Heterocephalus glaber',lifespan:30}, bowhead_whale:{rate:40,repair:95,color:'#80ed99',name:'Bowhead Whale',latin:'Balaena mysticetus',lifespan:200} }; const RATE_MULTIPLIER=8.45; function getEffectiveRate(rate,repair){ return rate*(1-repair/100)*RATE_MULTIPLIER; } function getLifespan(rate,repair){ return state.threshold/getEffectiveRate(rate,repair); } function getCumulativeMutations(year,rate,repair){ return getEffectiveRate(rate,repair)*year; } const svg=d3.select('#chart'); const margin={top:20,right:30,bottom:42,left:62}; let width,height,innerWidth,innerHeight; let xScale,yScale; let chartG; function setupChart(){ const rect=svg.node().getBoundingClientRect(); width=rect.width||800; height=rect.height||380; innerWidth=width-margin.left-margin.right; innerHeight=height-margin.top-margin.bottom; svg.attr('viewBox',`0 0 ${width} ${height}`); svg.selectAll('*').remove(); chartG=svg.append('g').attr('transform',`translate(${margin.left},${margin.top})`); xScale=d3.scaleLinear().domain([0,state.maxYear]).range([0,innerWidth]); yScale=d3.scaleLinear().domain([0,7000]).range([innerHeight,0]); chartG.append('g').attr('class','grid').selectAll('line').data(yScale.ticks(7)).enter().append('line') .attr('class','grid-line').attr('x1',0).attr('x2',innerWidth) .attr('y1',d=>yScale(d)).attr('y2',d=>yScale(d)); chartG.append('g').attr('class','axis').attr('transform',`translate(0,${innerHeight})`) .call(d3.axisBottom(xScale).tickValues([0,25,50,75,100,125,150,175,200]).tickFormat(d=>d+'y').tickSizeOuter(0)); chartG.append('g').attr('class','axis') .call(d3.axisLeft(yScale).tickValues([0,2000,4000,6000]).tickFormat(d=>d).tickSizeOuter(0)); chartG.append('text').attr('transform','rotate(-90)') .attr('x',-innerHeight/2).attr('y',-48).attr('text-anchor','middle') .attr('fill','#a8bcd0').attr('font-size','11px').attr('font-family','Source Sans Pro, sans-serif') .text('Cumulative mutations / cell'); chartG.append('text').attr('x',innerWidth/2).attr('y',innerHeight+34) .attr('text-anchor','middle').attr('fill','#a8bcd0').attr('font-size','11px') .attr('font-family','Source Sans Pro, sans-serif').text('Simulated age (years)'); chartG.append('line').attr('class','threshold-line') .attr('x1',0).attr('x2',innerWidth) .attr('y1',yScale(state.threshold)).attr('y2',yScale(state.threshold)); chartG.append('text').attr('class','threshold-label') .attr('x',innerWidth-6).attr('y',yScale(state.threshold)-6).attr('text-anchor','end') .text('Death threshold ≈ 6,200 mutations'); chartG.append('path').attr('class','curve').attr('id','curvePath'); chartG.append('path').attr('class','curve').attr('id','whatifPath').style('opacity',0); chartG.append('line').attr('class','scrubber-line').attr('id','scrubberLine') .attr('y1',0).attr('y2',innerHeight); chartG.append('circle').attr('class','cursor-dot').attr('id','cursorDot').attr('r',7); chartG.append('text').attr('class','year-label').attr('id','yearLabel').attr('text-anchor','middle'); chartG.append('rect').attr('class','scrubber-area').attr('id','scrubberArea') .attr('width',innerWidth).attr('height',innerHeight) .on('mousedown',startScrub).on('touchstart',startScrub); } function updateChart(){ const sp=speciesData[state.species]; const rate=state.whatIfMode?speciesData.bowhead_whale.rate:state.mutationRate; const repair=state.whatIfMode?speciesData.bowhead_whale.repair:state.repairEfficiency; const color=state.whatIfMode?speciesData.bowhead_whale.color:sp.color; const effectiveRate=getEffectiveRate(rate,repair); const lifespan=getLifespan(rate,repair); const data=[]; for(let y=0;y<=state.maxYear;y+=1){ data.push({year:y,mutations:Math.min(effectiveRate*y,7000)}); } const line=d3.line().x(d=>xScale(d.year)).y(d=>yScale(d.mutations)).curve(d3.curveLinear); chartG.select('#curvePath').datum(data).attr('d',line).attr('stroke',color); if(state.whatIfMode){ const whaleRate=getEffectiveRate(speciesData.bowhead_whale.rate,speciesData.bowhead_whale.repair); const whaleData=[]; for(let y=0;y<=state.maxYear;y+=1){ whaleData.push({year:y,mutations:Math.min(whaleRate*y,7000)}); } chartG.select('#whatifPath').datum(whaleData).attr('d',line) .style('opacity',0.35).attr('stroke',speciesData.bowhead_whale.color) .attr('stroke-dasharray','6,4'); }else{ chartG.select('#whatifPath').style('opacity',0); } const cursorY=yScale(Math.min(effectiveRate*state.currentYear,7000)); chartG.select('#cursorDot') .attr('cx',xScale(state.currentYear)).attr('cy',cursorY); chartG.select('#scrubberLine') .attr('x1',xScale(state.currentYear)).attr('x2',xScale(state.currentYear)); chartG.select('#yearLabel') .attr('x',xScale(state.currentYear)) .attr('y',cursorY-14) .text('y'+Math.round(state.currentYear)); const lifespanYear=Math.round(lifespan); const ratio=Math.min(state.currentYear/lifespan,1); const readoutColor=ratio>0.85?'#c0392b':ratio>0.6?'#ffb703':'#f4f1ea'; document.getElementById('lifespanReadout').textContent=`Year ${Math.round(state.currentYear)} / ${lifespanYear}`; document.getElementById('lifespanReadout').style.color=readoutColor; const currentMuts=Math.round(effectiveRate*state.currentYear); document.getElementById('lifespanSub').textContent=state.currentYear>=lifespan? `⚠ Threshold crossed — cellular dysfunction`: `Curve at ${currentMuts.toLocaleString()} mutations`; const title=state.whatIfMode? 'Human + Bowhead Whale Repair — Theoretical trajectory': `${sp.name} — Cumulative somatic mutations per cell`; document.getElementById('chartTitle').textContent=title; document.getElementById('speciesBadge').textContent=state.whatIfMode? 'Homo sapiens + Balaena mysticetus repair':sp.latin; drawCellGrid(); } function startScrub(event){ event.preventDefault(); state.isPlaying=false; document.getElementById('playBtn').textContent='▶ Play'; if(state.animFrame)cancelAnimationFrame(state.animFrame); const moveHandler=(e)=>{ const rect=svg.node().getBoundingClientRect(); const clientX=e.clientX||(e.touches&&e.touches[0]?e.touches[0].clientX:0); const x=clientX-rect.left-margin.left; const year=Math.max(0,Math.min(state.maxYear,xScale.invert(x))); state.currentYear=year; document.getElementById('yearSlider').value=year; document.getElementById('yearDisplay').textContent=Math.round(year); updateChart(); }; const upHandler=()=>{ document.removeEventListener('mousemove',moveHandler); document.removeEventListener('mouseup',upHandler); document.removeEventListener('touchmove',moveHandler); document.removeEventListener('touchend',upHandler); }; document.addEventListener('mousemove',moveHandler); document.addEventListener('mouseup',upHandler); document.addEventListener('touchmove',moveHandler); document.addEventListener('touchend',upHandler); moveHandler(event); } const cellCanvas=document.getElementById('cellCanvas'); const cellCtx=cellCanvas.getContext('2d'); const CELL_COLS=24; const CELL_ROWS=12; const CELL_GAP=3; let cellSize=28; const cellData=[]; function setupCellCanvas(){ const container=cellCanvas.parentElement; const containerWidth=container.clientWidth-36; cellSize=Math.max(14,Math.floor((containerWidth-(CELL_COLS-1)*CELL_GAP)/CELL_COLS)); const cw=CELL_COLS*(cellSize+CELL_GAP)-CELL_GAP; const ch=CELL_ROWS*(cellSize+CELL_GAP)-CELL_GAP; cellCanvas.width=cw*2; cellCanvas.height=ch*2; cellCanvas.style.width=cw+'px'; cellCanvas.style.height=ch+'px'; cellCtx.scale(2,2); cellData.length=0; for(let i=0;i50){ const dotCount=Math.min(Math.floor(mutations/150),9); cellCtx.fillStyle='rgba(192,57,43,0.75)'; const dotRadius=Math.max(1.5,cellSize/14); const positions=[ [0.25,0.25],[0.5,0.25],[0.75,0.25], [0.25,0.5],[0.5,0.5],[0.75,0.5], [0.25,0.75],[0.5,0.75],[0.75,0.75] ]; for(let d=0;d=m){ const year=m/(effectiveRate*cd.rateFactor); cd.milestones.push({threshold:m,year:Math.round(year)}); } } } } cellCanvas.addEventListener('mousemove',(e)=>{ const rect=cellCanvas.getBoundingClientRect(); const x=e.clientX-rect.left; const y=e.clientY-rect.top; const col=Math.floor(x/(cellSize+CELL_GAP)); const row=Math.floor(y/(cellSize+CELL_GAP)); if(col>=0&&col=0&&row{ const rect=cellCanvas.getBoundingClientRect(); const x=e.clientX-rect.left; const y=e.clientY-rect.top; const col=Math.floor(x/(cellSize+CELL_GAP)); const row=Math.floor(y/(cellSize+CELL_GAP)); if(col>=0&&col=0&&rowCell #${idx+1`; html+=`

Mutations${mutations.toLocaleString()`; html+=`
Rate factor${cd.rateFactor.toFixed(2)}×`; if(cd.milestones.length>0){ html+=`
Milestones crossed
`; cd.milestones.forEach(m=>{ html+=`
${m.threshold.toLocaleString()} mutyear ${m.year`; }); }else{ html+=`
No milestones crossed yet
`; } html+=`
Dysfunction atyear ${dysfunctionYear`; tooltip.innerHTML=html; tooltip.style.display='block'; const tw=tooltip.offsetWidth; const th=tooltip.offsetHeight; let left=clientX-tw/2; let top=clientY-th-12; if(left<8)left=8; if(left+tw>window.innerWidth-8)left=window.innerWidth-tw-8; if(top<8)top=clientY+12; tooltip.style.left=left+'px'; tooltip.style.top=top+'px'; } function hideTooltip(){ document.getElementById('tooltip').style.display='none'; } function animate(){ if(!state.isPlaying)return; state.currentYear+=0.4; if(state.currentYear>state.maxYear){ state.currentYear=state.maxYear; state.isPlaying=false; document.getElementById('playBtn').textContent='▶ Play'; } document.getElementById('yearSlider').value=state.currentYear; document.getElementById('yearDisplay').textContent=Math.round(state.currentYear); updateChart(); if(state.isPlaying){ state.animFrame=requestAnimationFrame(animate); } } document.getElementById('playBtn').addEventListener('click',()=>{ state.isPlaying=!state.isPlaying; document.getElementById('playBtn').textContent=state.isPlaying?'⏸ Pause':'▶ Play'; if(state.isPlaying){ if(state.currentYear>=state.maxYear)state.currentYear=0; animate(); }else if(state.animFrame){ cancelAnimationFrame(state.animFrame); } }); document.getElementById('resetBtn').addEventListener('click',()=>{ state.isPlaying=false; if(state.animFrame)cancelAnimationFrame(state.animFrame); document.getElementById('playBtn').textContent='▶ Play'; state.currentYear=0; state.mutationRate=speciesData[state.species].rate; state.repairEfficiency=speciesData[state.species].repair; state.whatIfMode=false; document.getElementById('rateSlider').value=state.mutationRate; document.getElementById('repairSlider').value=state.repairEfficiency; document.getElementById('yearSlider').value=0; document.getElementById('yearDisplay').textContent='0'; document.getElementById('whatifToggle').checked=false; document.getElementById('rateValue').textContent=state.mutationRate; document.getElementById('repairValue').textContent=state.repairEfficiency; updateChart(); }); document.getElementById('rateSlider').addEventListener('input',(e)=>{ state.mutationRate=parseInt(e.target.value); document.getElementById('rateValue').textContent=state.mutationRate; updateChart(); }); document.getElementById('repairSlider').addEventListener('input',(e)=>{ state.repairEfficiency=parseInt(e.target.value); document.getElementById('repairValue').textContent=state.repairEfficiency; updateChart(); }); document.getElementById('yearSlider').addEventListener('input',(e)=>{ state.currentYear=parseFloat(e.target.value); document.getElementById('yearDisplay').textContent=Math.round(state.currentYear); updateChart(); }); document.querySelectorAll('.species-btn').forEach(btn=>{ btn.addEventListener('click',()=>{ const sp=btn.dataset.species; state.species=sp; state.mutationRate=speciesData[sp].rate; state.repairEfficiency=speciesData[sp].repair; document.getElementById('rateSlider').value=state.mutationRate; document.getElementById('repairSlider').value=state.repairEfficiency; document.getElementById('rateValue').textContent=state.mutationRate; document.getElementById('repairValue').textContent=state.repairEfficiency; document.querySelectorAll('.species-btn').forEach(b=>b.classList.remove('active')); btn.classList.add('active'); updateChart(); }); }); document.getElementById('whatifToggle').addEventListener('change',(e)=>{ state.whatIfMode=e.target.checked; updateChart(); }); const notesHeader=document.getElementById('notesHeader'); notesHeader.addEventListener('click',()=>{ const content=document.getElementById('notesContent'); const arrow=document.getElementById('notesArrow'); const isOpen=content.classList.toggle('open'); arrow.textContent=isOpen?'▲':'▼'; notesHeader.setAttribute('aria-expanded',isOpen); }); notesHeader.addEventListener('keydown',(e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); notesHeader.click(); } }); document.getElementById('exportBtn').addEventListener('click',exportCard); function exportCard(){ const canvas=document.createElement('canvas'); canvas.width=1200; canvas.height=630; const ctx=canvas.getContext('2d'); ctx.fillStyle='#0b1a2a'; ctx.fillRect(0,0,1200,630); ctx.fillStyle='#f4f1ea'; ctx.font='bold 44px "Source Sans Pro", sans-serif'; ctx.fillText('DNA Mutation Accumulation',60,90); ctx.fillText('& Lifespan Simulator',60,148); ctx.fillStyle='#8aa5c0'; ctx.font='20px "Source Sans Pro", sans-serif'; ctx.fillText('Somatic mutation burden crosses ~6,200 mutations at year 156',60,188); const chartX=60,chartY=220,chartW=780,chartH=340; ctx.fillStyle='#0f2238'; ctx.fillRect(chartX,chartY,chartW,chartH); ctx.strokeStyle='#1a3a5c'; ctx.lineWidth=1; ctx.strokeRect(chartX,chartY,chartW,chartH); ctx.strokeStyle='#2a4a6c'; ctx.beginPath(); ctx.moveTo(chartX,chartY+chartH); ctx.lineTo(chartX+chartW,chartY+chartH); ctx.moveTo(chartX,chartY); ctx.lineTo(chartX,chartY+chartH); ctx.stroke(); ctx.fillStyle='#a8bcd0'; ctx.font='13px "JetBrains Mono", monospace'; [0,2000,4000,6000].forEach(v=>{ const y=chartY+chartH-(v/7000)*chartH; ctx.fillText(v.toString(),chartX-52,y+5); ctx.strokeStyle='#1a3a5c'; ctx.beginPath(); ctx.moveTo(chartX,y); ctx.lineTo(chartX+chartW,y); ctx.stroke(); }); [0,50,100,150,200].forEach(v=>{ const x=chartX+(v/200)*chartW; ctx.fillText(v+'y',x-10,chartY+chartH+22); }); const thresholdY=chartY+chartH-(6200/7000)*chartH; ctx.strokeStyle='#f4f1ea'; ctx.setLineDash([7,4]); ctx.lineWidth=1.5; ctx.beginPath(); ctx.moveTo(chartX,thresholdY); ctx.lineTo(chartX+chartW,thresholdY); ctx.stroke(); ctx.setLineDash([]); ctx.fillStyle='#f4f1ea'; ctx.font='12px "JetBrains Mono", monospace'; ctx.fillText('Death threshold ≈ 6,200',chartX+chartW-180,thresholdY-8); const sp=speciesData[state.species]; const rate=state.whatIfMode?speciesData.bowhead_whale.rate:state.mutationRate; const repair=state.whatIfMode?speciesData.bowhead_whale.repair:state.repairEfficiency; const effectiveRate=getEffectiveRate(rate,repair); const color=state.whatIfMode?speciesData.bowhead_whale.color:sp.color; ctx.strokeStyle=color; ctx.lineWidth=3; ctx.beginPath(); for(let y=0;y<=200;y+=1){ const mutations=Math.min(effectiveRate*y,7000); const x=chartX+(y/200)*chartW; const cy=chartY+chartH-(mutations/7000)*chartH; if(y===0)ctx.moveTo(x,cy); else ctx.lineTo(x,cy); } ctx.stroke(); const cursorYear=Math.min(156,state.maxYear); const cursorX=chartX+(cursorYear/200)*chartW; const cursorY=chartY+chartH-(Math.min(effectiveRate*cursorYear,7000)/7000)*chartH; ctx.fillStyle='#fb8500'; ctx.beginPath(); ctx.arc(cursorX,cursorY,9,0,Math.PI*2); ctx.fill(); ctx.strokeStyle='#f4f1ea'; ctx.lineWidth=2; ctx.stroke(); ctx.fillStyle='#fb8500'; ctx.font='bold 13px "JetBrains Mono", monospace'; ctx.fillText('y'+cursorYear,cursorX-12,cursorY-14); const readoutX=880,readoutY=220,readoutW=260,readoutH=140; ctx.fillStyle='#0f2238'; ctx.fillRect(readoutX,readoutY,readoutW,readoutH); ctx.strokeStyle='#48cae4'; ctx.lineWidth=2; ctx.strokeRect(readoutX,readoutY,readoutW,readoutH); ctx.fillStyle='#8aa5c0'; ctx.font='bold 12px "Source Sans Pro", sans-serif'; ctx.fillText('PROJECTED LIFESPAN',readoutX+20,readoutY+32); ctx.fillStyle='#f4f1ea'; ctx.font='bold 38px "JetBrains Mono", monospace'; ctx.fillText('Year 156',readoutX+20,readoutY+82); ctx.fillStyle='#48cae4'; ctx.font='15px "Source Sans Pro", sans-serif'; ctx.fillText('Human baseline',readoutX+20,readoutY+110); ctx.fillStyle='#a8bcd0'; ctx.font='13px "JetBrains Mono", monospace'; ctx.fillText('47 mut/yr · 90% repair',readoutX+20,readoutY+128); ctx.fillStyle='#8aa5c0'; ctx.font='16px "Source Sans Pro", sans-serif'; ctx.fillText('app.getsupers.com/sites/dna-mutation-lifespan/',60,600); ctx.fillStyle='#5a7a9a'; ctx.font='12px "Source Sans Pro", sans-serif'; ctx.fillText('Model-derived estimate · 2026 somatic mutation study',60,618); canvas.toBlob(blob=>{ if(!blob){return;} const url=URL.createObjectURL(blob); const a=document.createElement('a'); a.href=url; a.download='dna-mutation-lifespan-card.png'; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(()=>URL.revokeObjectURL(url),1000); },'image/png'); } function init(){ setupChart(); setupCellCanvas(); updateChart(); setTimeout(()=>{ state.isPlaying=true; document.getElementById('playBtn').textContent='⏸ Pause'; animate(); },900); let resizeTimer; window.addEventListener('resize',()=>{ clearTimeout(resizeTimer); resizeTimer=setTimeout(()=>{ setupChart(); setupCellCanvas(); updateChart(); },150); }); } if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded',init); }else{ init(); } })();