Barbell plate loading calculator
For 100 kg on a 20 kg bar, load one 25 kg and one 15 kg plate on each side. Enter your target weight, plus your bar and plates if they differ from the standard set, and get the per-side stack. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Loading a barbell to an exact programmed weight is a small math problem that still wastes time on the gym floor when done by guesswork. This capability takes a target total in kilograms, an empty bar weight, and an optional list of available plate denominations, then returns the largest-first plate stack for one side of the bar so both ends stay symmetric. The algorithm is pure arithmetic: subtract the bar, halve the load, greedily assign whole plates from heaviest to lightest, and fail clearly when the target cannot be built.
How the per-side greedy algorithm works
The calculator subtracts the empty bar weight from the target total to obtain the load that must be hung as plates, then halves that load because a standard barbell is loaded symmetrically on both ends. With the remaining weight for one side, the routine de-duplicates the plate list, sorts denominations from heaviest to lightest, and for each size takes as many whole plates as still fit without exceeding the remaining weight. A tiny floating-point epsilon keeps values such as forty kilograms of twenty-kilogram plates counting cleanly across JavaScript runtimes.
The default plate set is twenty-five, twenty, fifteen, ten, five, two point five, and one point two five kilograms with a twenty-kilogram bar unless the caller overrides either field. The greedy largest-first strategy matches how most coaches teach loading and how commercial plate trees are stocked, so the printed list feels familiar on the gym floor and keeps collar stack height lower than mixed micro-plate piles.
What you can do with it
Program percentage-based session loads
Turn a target total from a percentage of 1RM into a clear per-side plate list so athletes load the bar the same way every session.
Gym floor and class boards
Display plates per side for each programmed weight so novices stop guessing combinations of 25s, 10s, and change plates.
FAQ
How does the barbell plate loading calculator work?
The same stack is used on both ends.
What happens if my target cannot be loaded exactly?
The calculator says so instead of loading the bar slightly light. With the default plates each side moves in steps of 1.25 kg, so a target that would need a smaller step cannot be built.
Can I use a 15 kg women's bar?
Yes. Change the bar weight to 15 and the plates are worked out from that. The default is 20 kg, the men's Olympic bar, so you only need to change it for a different bar.
Can I enter the plates my gym actually has?
Yes. List the plate sizes available to you and the calculator only uses those. Duplicates are ignored and the order does not matter, because it always loads from heaviest to lightest.
Does it work in pounds?
Yes, as long as every number uses the same unit. Enter the target, the bar and the plate sizes all in pounds and the per-side list comes back in pounds too.
Related tools
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/health/plate-loading \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"target_kg":100}'const res = await fetch("https://api.kit.forhosting.com/health/plate-loading", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"target_kg": 100
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/health/plate-loading",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"target_kg": 100
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/health/plate-loading", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"target_kg":100}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"target_kg":100}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/health/plate-loading", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"target_kg": 100
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "health.plate_loading",
"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. |
Technical notes
There is no network hop, model call, clock, or randomness, so every browser session and every edge isolate returns the same JSON for the same inputs. Coaches, lifters, and app builders use it to print a per-side list, program percentage-based sessions, or batch-score many targets through the API at $0.002 per successful item. Invalid input returns invalid_input and is not billed.
How the per-side greedy algorithm works
After the greedy pass, any leftover above a microgram-scale tolerance means the target cannot be built from the given set, so the call throws invalid_input rather than inventing a close-enough total that would underload the bar. Success echoes target_kg and bar_kg, reports load_kg and per_side_kg, lists each plate weight with its count for one end of the bar, returns plate_count_per_side, and confirms total_kg once both sides are mirrored. Olympic men's bars at twenty kilograms and women's bars at fifteen kilograms are both first-class inputs so the same endpoint serves powerlifting platforms and technique bars without a separate converter.
Inputs, reachability, and error behaviour
Reachability depends on the greatest common step of the plate set: with the defaults the step is one point two five kilograms, so odd per-side loads that are not multiples of that step correctly fail rather than silently underloading. Lifters who train in pounds can convert externally or pass pound-denominated numbers if every input shares the same unit, because the arithmetic is unit-agnostic as long as bar, plates, and target agree. There is no network hop, model call, clock read, or random source on the path, so latency stays in the pure edge-parse band and repeated calls never drift. Send a JSON object with target_kg as a required positive finite number for the programmed total. Optional bar_kg defaults to twenty and must be a non-negative finite number; optional plates is a non-empty array of positive finite denominations in kilograms. Non-positive targets, missing target_kg, empty or invalid plate lists, targets below the empty bar, and loads that leave a remainder after the greedy fill all fail immediately with invalid_input naming the problem; those failures are not charged against prepaid balance. Pair the result with your own percentage tables if you need working sets at seventy or eighty-five percent of a one-rep max; this endpoint stops at plate loading so product copy stays honest about what was computed.
Where a barbell plate loading calculator fits in real workflows
Strength coaches and personal trainers convert a percentage of estimated one-rep max into a concrete target, then hand athletes a per-side plate list so every session loads the same way without floor debate. Gym floor staff and class instructors display the stack on a whiteboard or phone so novices stop guessing which combination of twenty-fives and tens adds to the programmed load. Research and club logging pipelines batch-score many targets when designing progressive overload tables for a season of training or when exporting competition warm-up progressions. Always warm up, secure collars, and verify both sides before any attempt especially near maximal loads; this tool is planning arithmetic, not a substitute for safe gym practice. Content sites that rank for a barbell plate loading calculator benefit from a transparent free tool whose machine contract matches the API, which builds trust when readers later automate the same math. Developers wire the call into CRON jobs and webhooks so every microservice shares one definition of greedy loading rather than reimplementing float-sensitive floors that disagree on edge cases. The browser path is free for single interactive checks: enter one hundred for target_kg with defaults and confirm one twenty-five and one fifteen kilogram plate per side. The API path costs $0.002 per successful request and is billed per item, which keeps bulk programming cheap while still covering edge execution. Because results are deterministic, audit logs can store the full response and re-run it years later without drift, and continuous-integration goldens pin exact JSON for regressions whenever the library is touched.
Integration use cases
Batch warm-up and overload tables
Feed many targets through the API to print warm-up ladders or progressive overload sheets without hand-calculating stacks.
Technical questions
Which inputs are required?
target_kg (positive total in kg). Optional bar_kg defaults to 20; optional plates defaults to 25, 20, 15, 10, 5, 2.5, 1.25 kg.
What if the target cannot be loaded with my plates?
The task fails with invalid_input explaining that the weight is not reachable. Invalid input is not billed.
Can I use a 15 kg women's bar or custom plates?
Yes. Set bar_kg to 15 (or any non-negative bar) and pass your available plate denominations in plates.
What does the plate loading calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; failed validation is not charged.