Average power lies to you. A ride where you soft-pedal for 90 minutes and then sprint for 30 minutes reports the same average power as a steady 2-hour tempo effort — but it felt and taxed your body completely differently. Normalized Power (NP) accounts for the nonlinear physiological cost of variable efforts. It's the single most important number on a power file.
Why average power understates variable efforts
The physiological cost of exercise isn't linear with power output. Doubling your power output more than doubles the metabolic demand — because at high intensities you're burning through glycogen faster, your cardiovascular system is working harder, and the rate of muscle acidification is disproportionately higher.
The key paper (Coggan, 2003) quantified this as roughly a 4th-power relationship: the physiological cost of an effort is proportional to power raised to the 4th power. A 300-watt effort isn't twice as costly as a 150-watt effort — it's sixteen times as costly (2⁴ = 16).
Normalized Power leverages this relationship to compute the equivalent steady power that would produce the same physiological load as the variable effort.
The algorithm
The Coggan NP algorithm has four steps:
- Compute a 30-second rolling average of power at each second
- Raise each rolling average to the 4th power
- Take the mean of all the 4th-power values
- Take the 4th root of the mean
In TypeScript:
function normalizedPower(watts: number[]): number {
const WINDOW = 30;
const n = watts.length;
if (n < WINDOW) return 0;
// step 1: 30s rolling average
const rolling: number[] = [];
let windowSum = 0;
for (let i = 0; i < WINDOW; i++) {
windowSum += watts[i];
}
for (let i = WINDOW; i <= n; i++) {
rolling.push(windowSum / WINDOW);
if (i < n) {
windowSum += watts[i] - watts[i - WINDOW];
}
}
// steps 2-4: mean of 4th powers, then 4th root
const mean4th = rolling.reduce((sum, w) => sum + w ** 4, 0) / rolling.length;
return mean4th ** 0.25;
} That's it. The rolling average uses a sliding window sum to stay O(n) rather than recomputing each window from scratch.
Why the 30-second window
Heart rate lags actual effort by 20–60 seconds. The 30-second rolling average serves as a smoothing filter that removes second-to-second power spikes (standing up to accelerate, hitting a bump) that don't represent sustained metabolic demand. It also approximately matches the lag of the cardiovascular response.
Without the rolling average, a single 1-second sprint at 1000 watts would inflate NP dramatically. With the 30-second window, that sprint's contribution is spread across 30 samples before the 4th-power step — a more accurate representation of its actual physiological cost.
The 1Hz requirement
The algorithm assumes the input array is sampled at 1 Hz — one watt value per second. Most modern power meters record at 1 Hz natively. Some older meters or certain devices record at lower frequencies (1 sample per 2 seconds, or even less). pacelore resamples power data to 1 Hz before computing NP, using linear interpolation between samples.
Missing samples (gaps in recording, auto-pause during stops) are zero-filled. This is the Coggan recommendation: zeros during paused segments reflect that no metabolic demand was occurring. Some implementations use the last-known value instead of zero — this inflates NP during long pauses and is incorrect.
What NP unlocks
NP is the input to two other metrics:
- Intensity Factor (IF) = NP / FTP. An IF of 1.0 means you rode at threshold. Values above 1.0 are possible for short efforts but not sustainable for full races.
- TSS = (duration × NP × IF) / (FTP × 3600) × 100. The training load measurement. One hour at FTP (IF = 1.0, NP = FTP) gives TSS = 100 by definition.
A race simulation ride where you average 220W but NP is 265W tells you the effort was equivalent to a sustained 265W effort — which your 280W FTP can sustain, but not for much longer than the race duration. A perfectly paced steady effort would have NP ≈ average power. The ratio NP/average power is the Variability Index — a high VI (above 1.10) indicates a choppy, variable ride, which for a triathlete conserving energy for the run is suboptimal.
NP for running: Normalized Graded Pace
The same algorithm applies to running pace with grade adjustment substituted for power. Instead of watts, feed in Grade-Adjusted Pace values at 1 Hz, apply the same 30-second rolling average and 4th-power pipeline, and the output is Normalized Graded Pace (NGP). NGP feeds into rTSS the same way NP feeds into power TSS. The math is identical; only the input units change.