Calculating your heart rate zones is essential for maximizing the efficiency of your cardio workouts. Whether you are training for a marathon or simply trying to burn fat, understanding your Maximum Heart Rate (MHR) and your specific training zones ensures you are working at the right intensity.
1. The Formula: Maximum Heart Rate (MHR)
The most common method to estimate your Maximum Heart Rate is the simple age-based formula:
MHR = 220 – Age
For example, if you are 40 years old, your estimated MHR is 180 beats per minute (bpm).
2. The Karvonen Method (Why Resting Heart Rate Matters)
This calculator uses the Karvonen Formula, which is widely considered more accurate for athletes and fitness enthusiasts because it accounts for your Resting Heart Rate (RHR). This method calculates your Heart Rate Reserve (HRR).
By factoring in your resting heart rate, the Karvonen method tailors the zones to your specific fitness level. A lower resting heart rate indicates better cardiovascular fitness, which this formula respects.
3. Understanding Heart Rate Zones
Zone 1 (50-60%): Very Light. Good for warm-ups, cool-downs, and recovery.
Zone 2 (60-70%): Light. Often called the "Fat Burning Zone". You should be able to hold a conversation easily.
Zone 3 (70-80%): Moderate. Improves aerobic fitness and endurance. Breathing becomes rhythmic.
Zone 4 (80-90%): Hard. Increases maximum performance capacity. Breathing is heavy; conversation is difficult.
Zone 5 (90-100%): Maximum. Develops maximum speed and power. Sustainable only for short bursts (intervals).
How to Measure Resting Heart Rate
To get the most accurate result from this calculator, measure your pulse immediately after waking up in the morning, before getting out of bed. Count the beats for 60 seconds, or count for 15 seconds and multiply by 4.
function calculateHeartZones() {
// 1. Get Inputs
var ageInput = document.getElementById('calc-age');
var rhrInput = document.getElementById('calc-rhr');
var resultSection = document.getElementById('hr-results');
var age = parseFloat(ageInput.value);
var rhr = parseFloat(rhrInput.value);
// 2. Validation
if (isNaN(age) || age 120) {
alert("Please enter a valid age between 1 and 120.");
return;
}
// If RHR is empty or invalid, we default to 0 for calculation flow,
// but ideally we ask for it. If not provided, we fall back to simple % of Max.
// For this specific tool logic, let's enforce RHR for accuracy or default to average (70).
if (isNaN(rhr) || rhr = 200) {
alert("Please enter a valid Resting Heart Rate (typically between 40 and 100 bpm).");
return;
}
// 3. Logic Calculation
// Max Heart Rate
var maxHeartRate = 220 – age;
// Heart Rate Reserve (Karvonen)
var hrReserve = maxHeartRate – rhr;
// Check if RHR > MHR (impossible physically unless ill/error)
if (hrReserve <= 0) {
alert("Your Resting Heart Rate cannot be higher than your Maximum Heart Rate. Please check your inputs.");
return;
}
// Function to calc specific intensity
function getZone(pct) {
return Math.round((hrReserve * pct) + rhr);
}
// 4. Update Header Results
document.getElementById('res-mhr').innerHTML = maxHeartRate + " bpm";
document.getElementById('res-hrr').innerHTML = hrReserve + " bpm";
// 5. Build Zone Table Rows
var zones = [
{ id: 1, name: "Very Light (Recovery)", range: "50% – 60%", low: 0.50, high: 0.60, color: "#9e9e9e" },
{ id: 2, name: "Light (Fat Burn)", range: "60% – 70%", low: 0.60, high: 0.70, color: "#4caf50" },
{ id: 3, name: "Moderate (Aerobic)", range: "70% – 80%", low: 0.70, high: 0.80, color: "#ff9800" },
{ id: 4, name: "Hard (Anaerobic)", range: "80% – 90%", low: 0.80, high: 0.90, color: "#ff5722" },
{ id: 5, name: "Maximum (VO2 Max)", range: "90% – 100%", low: 0.90, high: 1.00, color: "#d32f2f" }
];
var tableHtml = "";
for (var i = 0; i < zones.length; i++) {
var z = zones[i];
var valLow = getZone(z.low);
var valHigh = getZone(z.high);
tableHtml += "
";
tableHtml += "
Zone " + z.id + ": " + z.name + "
";
tableHtml += "
" + z.range + "
";
tableHtml += "
" + valLow + " – " + valHigh + " bpm
";
tableHtml += "
";
}
document.getElementById('hr-zone-body').innerHTML = tableHtml;
// 6. Show Results
resultSection.style.display = "block";
// Scroll to results
resultSection.scrollIntoView({behavior: 'smooth'});
}