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
| Species | Rate/yr | Repair | Ceiling |
|---|---|---|---|
| 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;i