Acute:chronic workload ratio calculator and risk zones
This acute:chronic workload ratio calculator compares the training load accumulated in the current week with the average weekly load from the previous four weeks.
Run — free
It returns the ratio and places it in a commonly cited workload zone, making sudden changes easy to spot. Use any load measure—session RPE load, distance, minutes, tonnage, or another consistent metric—as long as both values use the same unit. The result is a screening aid, not a diagnosis or a prediction that an injury will or will not happen.
Enter comparable acute and chronic loads
The acute value is the total training load for the week you want to assess. The chronic value is the average weekly load across the four completed weeks immediately before it. Both values must represent the same activity population, measurement method, and unit. For example, compare session-RPE load with session-RPE load, kilometres with kilometres, or lifted tonnage with lifted tonnage. Do not compare the current week in minutes with a prior average in distance, because the quotient would have no useful meaning. The calculator divides acute load by chronic load and rounds the displayed ratio to three decimal places. A current load of 520 and a prior four-week average of 400 produces 1.3. The chronic average must be greater than zero; without a nonzero baseline, a finite ratio cannot be calculated. Zero acute load is accepted and produces a ratio of zero, which can represent a rest week, interruption, or incomplete data. Before interpreting that result, verify that the recorded loads cover the same athletes, sessions, and time boundaries. Consistency matters more than the particular load metric chosen.
Read the workload zones carefully
The output applies a practical set of commonly used boundaries. Ratios up to and including 0.8 are labelled low load or undertraining because the current week is well below the recent baseline. Values above 0.8 and up to 1.3 fall in the commonly cited sweet spot and receive a lower-risk label. Values above 1.3 and up to 1.5 enter the caution zone, indicating an elevated spike relative to recent work. Anything above 1.5 is marked high risk because acute demand substantially exceeds the chronic average. Boundaries are evaluated against the ratio after it is rounded to three decimals, so the displayed number and its classification always agree. These labels describe relative workload, not the athlete's health. A low ratio is not automatically desirable: it may reflect detraining, tapering, illness, or planned recovery. Likewise, a sweet-spot ratio does not guarantee safety. Injury depends on exposure, tissue, sport, history, sleep, recovery, and many other factors. Treat the zone as a prompt for discussion and review rather than a stand-alone clearance decision.
Use the ratio as one signal in load management
The most useful application is repeated, consistent monitoring. Calculate the ratio at the same point each week, inspect changes alongside absolute load, and document why a spike or drop occurred. Coaches can use a caution or high-risk flag to review session density, competition demands, travel, recovery, and the athlete's reported condition before deciding whether to adjust training. Analysts can place the deterministic output in a dashboard or data pipeline; API access costs $0.002 per request, while the browser tool can run the same calculation locally. Keep the limitations visible. The acute:chronic ratio has been debated in sports science, and simple thresholds should not be presented as universal causal injury predictors. Different sports, positions, ages, and load measures may need locally validated ranges. The four-week rolling average can also hide rapid changes inside that window, and early-season baselines may be unstable. Pair the result with athlete feedback, medical judgment, workload history, and sport-specific evidence. If pain, unusual fatigue, or functional loss is present, seek assessment from a qualified health or sports professional instead of relying on this number.
What you can do with it
Review a weekly training spike
Compare the latest week's load with the preceding four-week average before planning the next microcycle.
Add a flag to a coaching dashboard
Turn two existing workload measures into a stable ratio, named zone, and risk label for routine review.
Check return-to-training progression
Spot when a returning athlete's current workload rises sharply relative to their recent recorded baseline.
FAQ
What is acute load?
It is the total training load accumulated during the current week being assessed.
What is chronic load here?
It is the arithmetic average of the four weekly loads immediately before the current week. Supply that average, not all four individual values.
Which training-load unit should I use?
Any consistent nonnegative measure can work, including session-RPE load, distance, duration, or tonnage. Acute and chronic values must use the same measure and unit.
Why is a zero chronic average an error?
The ratio divides acute load by chronic load. Division by zero cannot produce a finite, meaningful workload ratio.
Does a high-risk flag predict an injury?
No. It identifies a large relative workload spike under common thresholds. It does not diagnose injury or account for every athlete, recovery, and exposure factor.
How much does the API calculation cost?
The API price is $0.002 per request. The same deterministic calculation can also run in the browser.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/fitness2/training-load-acute-chronic \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"acute_load":520,"chronic_load":400}'const res = await fetch("https://api.kit.forhosting.com/fitness2/training-load-acute-chronic", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"acute_load": 520,
"chronic_load": 400
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/fitness2/training-load-acute-chronic",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"acute_load": 520,
"chronic_load": 400
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/fitness2/training-load-acute-chronic", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"acute_load":520,"chronic_load":400}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"acute_load":520,"chronic_load":400}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/fitness2/training-load-acute-chronic", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"acute_load": 520,
"chronic_load": 400
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "fitness2.training_load_acute_chronic",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |