Calculating Threshold Heart Rate

.thr-container { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; max-width: 800px; margin: 20px auto; padding: 25px; border: 1px solid #e1e1e1; border-radius: 12px; background-color: #ffffff; box-shadow: 0 4px 6px rgba(0,0,0,0.1); color: #333; } .thr-header { text-align: center; margin-bottom: 30px; } .thr-header h2 { color: #d32f2f; margin-bottom: 10px; } .thr-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 25px; } @media (max-width: 600px) { .thr-grid { grid-template-columns: 1fr; } } .thr-input-group { display: flex; flex-direction: column; } .thr-input-group label { font-weight: 600; margin-bottom: 8px; font-size: 14px; } .thr-input-group input { padding: 12px; border: 2px solid #ddd; border-radius: 6px; font-size: 16px; transition: border-color 0.3s; } .thr-input-group input:focus { border-color: #d32f2f; outline: none; } .thr-btn { width: 100%; padding: 15px; background-color: #d32f2f; color: white; border: none; border-radius: 6px; font-size: 18px; font-weight: bold; cursor: pointer; transition: background-color 0.3s; } .thr-btn:hover { background-color: #b71c1c; } .thr-result { margin-top: 30px; padding: 20px; background-color: #f9f9f9; border-radius: 8px; display: none; } .thr-result h3 { margin-top: 0; color: #333; border-bottom: 2px solid #d32f2f; padding-bottom: 10px; } .thr-table { width: 100%; border-collapse: collapse; margin-top: 15px; } .thr-table th, .thr-table td { padding: 12px; text-align: left; border-bottom: 1px solid #eee; } .thr-table th { background-color: #f2f2f2; font-weight: 600; } .thr-article { margin-top: 40px; line-height: 1.6; color: #444; } .thr-article h3 { color: #d32f2f; } .thr-article ul { padding-left: 20px; } .zone-1 { border-left: 5px solid #4caf50; } .zone-2 { border-left: 5px solid #8bc34a; } .zone-3 { border-left: 5px solid #ffeb3b; } .zone-4 { border-left: 5px solid #ff9800; } .zone-5 { border-left: 5px solid #f44336; }

Threshold Heart Rate Calculator

Determine your Lactate Threshold Heart Rate (LTHR) and training zones for optimized endurance performance.

Enter the average heart rate from the last 20 minutes of a 30-minute all-out effort.
If you don't have time trial data, we can estimate based on 90% of Max HR.

Your Calculated LTHR: 0 BPM

Based on your threshold, here are your personalized training zones (Joe Friel Method):

Zone Description BPM Range

Understanding Your Threshold Heart Rate (LTHR)

Lactate Threshold Heart Rate (LTHR) is the highest intensity at which an athlete can maintain a steady state of effort for approximately one hour. Unlike Maximum Heart Rate, which is largely determined by genetics and age, LTHR is a trainable metric that reflects your aerobic fitness and metabolic efficiency.

How to Perform the LTHR Test

The most accurate way to find your LTHR outside of a laboratory is the Joe Friel 30-minute time trial:

  • Warm-up: 15 minutes of easy jogging or cycling with a few short sprints.
  • The Test: Run or cycle at your maximum sustainable effort for 30 minutes. This should be a consistent, "all-out" effort.
  • Data Collection: Click "Lap" on your heart rate monitor at the 10-minute mark.
  • The Result: Your average heart rate for the final 20 minutes of the test is a highly accurate estimate of your LTHR.

The 5 Training Zones Explained

By identifying your LTHR, you can categorize your training into specific physiological adaptations:

  • Zone 1 (Recovery): Active recovery, very light intensity. Used for flushing out metabolic waste.
  • Zone 2 (Aerobic Base): The "all-day" pace. Builds mitochondrial density and fat-burning efficiency.
  • Zone 3 (Tempo): Moderate intensity. Improves glycogen storage and muscular endurance.
  • Zone 4 (Threshold): Working right at your limit. Increases the speed/power you can hold without "redlining."
  • Zone 5 (Anaerobic): Short bursts of maximal effort. Improves VO2 Max and sprinting capacity.

Example Calculation

If an athlete performs a 30-minute run and their average heart rate for the final 20 minutes is 170 BPM, their LTHR is 170. Their Zone 2 (81-89% of LTHR) would range from 138 to 151 BPM. This ensures they are training at the correct intensity to build an aerobic base without overtraining.

function calculateThreshold() { var avgHR = parseFloat(document.getElementById("avgHeartRate").value); var maxHR = parseFloat(document.getElementById("maxHeartRate").value); var resultDiv = document.getElementById("thrResult"); var lthrDisplay = document.getElementById("lthrValue"); var tableBody = document.getElementById("zoneTableBody"); var lthr = 0; // Logic: Prioritize Time Trial data, fallback to Max HR estimation if (!isNaN(avgHR) && avgHR > 0) { lthr = avgHR; } else if (!isNaN(maxHR) && maxHR > 0) { lthr = Math.round(maxHR * 0.90); // Common estimate LTHR is ~90% of Max HR for trained athletes } else { alert("Please enter either an Average Heart Rate from a test or your Maximum Heart Rate."); return; } lthrDisplay.innerHTML = Math.round(lthr); var zones = [ { name: "Zone 1", desc: "Recovery", min: 0, max: 0.81, cls: "zone-1" }, { name: "Zone 2", desc: "Aerobic / Base", min: 0.81, max: 0.89, cls: "zone-2" }, { name: "Zone 3", desc: "Tempo", min: 0.90, max: 0.93, cls: "zone-3" }, { name: "Zone 4", desc: "Sub-Threshold", min: 0.94, max: 0.99, cls: "zone-4" }, { name: "Zone 5a", desc: "Super-Threshold", min: 1.00, max: 1.02, cls: "zone-5" }, { name: "Zone 5b", desc: "Aerobic Capacity", min: 1.03, max: 1.06, cls: "zone-5" }, { name: "Zone 5c", desc: "Anaerobic Power", min: 1.07, max: 1.15, cls: "zone-5" } ]; var html = ""; for (var i = 0; i < zones.length; i++) { var z = zones[i]; var low = Math.round(lthr * z.min); var high = Math.round(lthr * z.max); // Formatting specific ranges var rangeText = ""; if (z.name === "Zone 1") { rangeText = "Below " + high; } else if (z.name === "Zone 5c") { rangeText = "Above " + low; } else { rangeText = low + " – " + high; } html += ""; html += "" + z.name + ""; html += "" + z.desc + ""; html += "" + rangeText + " BPM"; html += ""; } tableBody.innerHTML = html; resultDiv.style.display = "block"; resultDiv.scrollIntoView({ behavior: 'smooth' }); }

Leave a Comment