Determining your Maximum Heart Rate (MHR) is the cornerstone of effective heart rate-based cycling training. While power meters are the gold standard in modern cycling, heart rate remains a vital metric for understanding your body's physiological response to effort.
Why a Cycling-Specific Calculator?
Your maximum heart rate is not the same across all sports. Generally, a person's max heart rate for running is slightly higher than for cycling. This is because running engages more muscle mass and supports the body's weight, leading to a higher cardiovascular demand.
This calculator offers the Fairbarne formula, which is derived specifically for cyclists to provide a more accurate estimation than the generic formulas used for general population health.
Tanaka: Often more accurate for healthy, active adults than the standard formula.
Formula: 208 – (0.7 × Age)
Fox: The classic standard found on most gym equipment, though often considered less precise for trained athletes.
Formula: 220 – Age
Gulati: Designed specifically for women, as the standard 220-age often overestimates female MHR.
Formula: 206 – (0.88 × Age)
Cycling Training Zones Breakdown
Once your MHR is established, your training is divided into five specific zones:
Zone 1 (Active Recovery): Very light spinning. Used between intervals or on rest days to flush out lactate.
Zone 2 (Endurance): The "all day" pace. This builds mitochondrial density and fat-burning efficiency. This is where most base miles should be ridden.
Zone 3 (Tempo): A spirited rhythm. Harder than endurance but sustainable for 1-2 hours. Improves aerobic capacity.
Zone 4 (Threshold): The intensity you can hold for a 20-60 minute time trial. This raises your Functional Threshold Power (FTP).
Zone 5 (VO2 Max): Maximum effort sustainable for 3-8 minutes. Painful but necessary for top-end speed and punching up short climbs.
Limitations
Remember that formulas are statistical averages. Your actual individual max heart rate can vary by +/- 10-15 beats per minute due to genetics, fitness level, and fatigue. For the most accurate data, a field test (like a ramp test) or a lab-based VO2 Max test is recommended.
function calculateCyclingZones() {
// 1. Get Input Values
var ageInput = document.getElementById('cyclistAge').value;
var gender = document.getElementById('cyclistGender').value;
var formula = document.getElementById('calcFormula').value;
var restingHRInput = document.getElementById('restingHR').value;
// 2. Validation
var age = parseFloat(ageInput);
if (isNaN(age) || age 120) {
alert("Please enter a valid age between 10 and 120.");
return;
}
// 3. Calculate MHR based on formula
var mhr = 0;
var formulaName = "";
if (formula === "fairbarne") {
// Fairbarne Cycling Specific
if (gender === "female") {
mhr = 201 – (0.63 * age);
} else {
mhr = 202 – (0.55 * age);
}
formulaName = "Fairbarne (Cycling Specific)";
} else if (formula === "tanaka") {
// Tanaka Formula
mhr = 208 – (0.7 * age);
formulaName = "Tanaka (Active Adult)";
} else if (formula === "gulati") {
// Gulati Formula (Women specific, fallback to Tanaka for men if selected by accident, or strict logic)
// Usually Gulati is strictly for women. If male selected, we warn or swap, but let's just run logic.
// Gulati: 206 – (0.88 * age)
mhr = 206 – (0.88 * age);
formulaName = "Gulati (Women's Specific)";
if (gender === 'male') {
formulaName += " – Note: Designed for females";
}
} else {
// Fox Formula (Default Standard)
mhr = 220 – age;
formulaName = "Fox (Standard 220 – Age)";
}
mhr = Math.round(mhr);
// 4. Calculate Zones
// We will use standard percentage of MHR unless RHR is provided for Karvonen,
// but for simplicity and standard cycling zones, simple % of MHR is most common for general calculators.
// Let's implement standard cycling percentages.
// Zone Definitions (Standard Cycling)
// Z1: 50-60%
// Z2: 60-70%
// Z3: 70-80%
// Z4: 80-90%
// Z5: 90-100%
var z1_low = Math.round(mhr * 0.50);
var z1_high = Math.round(mhr * 0.60);
var z2_low = Math.round(mhr * 0.60) + 1; // avoid overlap
var z2_high = Math.round(mhr * 0.70);
var z3_low = Math.round(mhr * 0.70) + 1;
var z3_high = Math.round(mhr * 0.80);
var z4_low = Math.round(mhr * 0.80) + 1;
var z4_high = Math.round(mhr * 0.90);
var z5_low = Math.round(mhr * 0.90) + 1;
var z5_high = mhr;
// Check if RHR is used (Karvonen Method) – Optional Enhancement
// To keep it strictly aligned with standard MHR calc requests, usually %MHR is expected.
// However, if RHR is present, Heart Rate Reserve (HRR) is better.
// Let's check if valid RHR is entered.
var rhr = parseFloat(restingHRInput);
var isKarvonen = !isNaN(rhr) && rhr > 30 && rhr < mhr;
if (isKarvonen) {
var hrr = mhr – rhr;
// Karvonen: TargetHR = ((MHR − RHR) × %Intensity) + RHR
// Adjusted zones for Karvonen are usually lower percentages (e.g. Z1 is 50% of HRR)
// Standard Karvonen Zones:
// Z1: 50-60%
// Z2: 60-70%
// Z3: 70-80%
// Z4: 80-90%
// Z5: 90-100%
z1_low = Math.round((hrr * 0.50) + rhr);
z1_high = Math.round((hrr * 0.60) + rhr);
z2_low = Math.round((hrr * 0.60) + rhr) + 1;
z2_high = Math.round((hrr * 0.70) + rhr);
z3_low = Math.round((hrr * 0.70) + rhr) + 1;
z3_high = Math.round((hrr * 0.80) + rhr);
z4_low = Math.round((hrr * 0.80) + rhr) + 1;
z4_high = Math.round((hrr * 0.90) + rhr);
z5_low = Math.round((hrr * 0.90) + rhr) + 1;
z5_high = mhr;
formulaName += " + Karvonen (HR Reserve)";
}
// 5. Update UI
document.getElementById('maxHeartRateDisplay').innerHTML = mhr + " BPM";
document.getElementById('formulaUsedText').innerText = "Based on: " + formulaName;
var tableBody = document.getElementById('zonesTableBody');
tableBody.innerHTML = "";
// Function to create row
function createRow(zone, name, intensity, low, high, cssClass) {
return `