Skip to content
How it works

What a percentage in a programme is a percentage of

What a percentage in a programme is a percentage of, and where that number comes from.

By Kiptly ·

On this page

There are two percentages, and they are not the same

A percentage is always a percentage of something, and this app has two somethings. Which one you are looking at depends on where the row came from, and nothing on the screen currently tells you — which is most of the reason this page exists.

On a ready-made programme, the sets of a main lift are stored as a week number, a set number, a percentage, a rep target and an AMRAP flag. The percentage there is a share of your training max: a number you typed in yourself, once, when you started the programme.

On an ordinary template — one you built, or a trainer built for you — an exercise can carry a target percentage instead of a target weight. That percentage is a share of your estimated one-rep max, computed from your own logged sets with Epley, the formula the records page explains.

A training max is a number you type

Nothing derives it, nothing updates it, and nothing checks it against what you actually lift. It is stored per exercise, for the programme you are running, and the server accepts anything from zero up to the ceiling in the table below. Ids for exercises that are not in that programme are dropped without comment rather than rejected — you get back the maxes that were stored, and the ones that were not are simply absent.

There is an optional helper on the setup screen: type a one-rep max and it fills in nine tenths of it, the convention percentage programmes are usually written around. It runs only when you ask, on the phone, and it rounds to a tenth of a kilogram. The figure it writes is then an ordinary number in the field, exactly as if you had typed it.

The deliberate part is that a training max is deliberately not your best-ever lift. Programmes written around percentages assume a working number you can hit on a bad day, which is why the convention exists and why the helper defaults below your maximum rather than at it.

What the app does with it

Training max times the percentage, divided by a hundred, rounded to the nearest 2.5 kg. That is the whole calculation, it happens on the server, and the percentage travels with the set so you can see both.

A four-week cycle is stored as rows. In the one shipped with the app: week one at 65, 75 and 85 per cent for five reps; week two at 70, 80 and 90 for three; week three at 75, 85 and 95 for five, three and one. The last set of each of those weeks carries the AMRAP flag — as many reps as you can manage rather than a fixed number — and the flag is stored per set, not inferred.

The fourth week is 40, 50 and 60 per cent for five, with no AMRAP: a lighter week written into the programme’s own data. That makes it a third thing this product calls a deload, and the only one that is neither computed nor suggested — it is simply the next week of the cycle. The two the app works out for itself have their own page.

If you have not set a training max for that exercise, the sets still arrive: the percentage and the rep target are there and the weight is simply absent. That is deliberate. Inventing a weight from an estimate the programme was not written around would be a guess dressed as a prescription.

The numbers, and where they live

The numbers behind both paths, read out of the API and the app when the site was built. The Epley divisor is here because the second kind of percentage is resolved against a formula rather than against a number you typed — it is the same 30 the records page publishes.

What it isValueRead from
A programme weight is rounded to the NEAREST multiple of this — not down.2.5apps/api/src/template/program.service.ts
What the optional helper fills in: this share of a one-rep max you type yourself.0.9apps/flutter/lib/features/programs/presentation/training_max_setup_screen.dart
The largest training max the server will store for one exercise.1000apps/api/src/template/dto/set-training-maxes.dto.ts
The 30 in Epley: e1RM = weight × (1 + reps ÷ 30).30apps/api/src/smart/workout-plan.service.tsapps/api/src/workout/workout.service.ts
The smallest metric jump — a pair of 1.25 kg plates.2.5apps/api/src/smart/workout-plan.rules.tsapps/flutter/lib/features/workout/presentation/workout_provider.dart

The other path: a percentage of an estimate

A template exercise resolves its weight in a fixed order, and the first thing that answers wins: an explicit target weight, then the percentage times your estimated one-rep max, then — for exercises typed as bodyweight work — your body weight, and then nothing at all.

This one happens on your phone, as the session is built, and it rounds to a whole kilogram. It uses the best estimate from your own history for that exercise, so it moves when your lifting moves — the opposite of a training max, which sits still until you change it.

And if you have logged nothing on that exercise, there is no estimate, so there is no weight. The set still exists, with its reps and its percentage, waiting for you to put a number in.

Who can run one

Starting a ready-made programme is part of the paid tier, and so is reading a preset from the library. A programme you wrote yourself is free to read.

Setting the training maxes is slightly wider than that: a paying user can do it, and so can a client whose trainer assigned them the programme. That second case is not a loophole — it is the one that makes a coached client able to run their coach’s programme without buying anything.

Sources

Each source says how far we actually got into it. A citation list shows that a paper exists, not that anybody opened it — so this one is labelled.

  1. The code that resolves them

    apps/api/src/template/program.service.ts, apps/api/prisma/schema.prisma and apps/flutter/lib/features/workout/domain/template_seeding.dart. Every number above is read out of these files when this site is built, and the five ranges the prose explains are hashed.

    Read in full

  2. The training-max convention itself

    Working at a share of a number below your true maximum is a convention from percentage-based programming, not a finding we can cite, and the app treats it as a default in one optional helper rather than as a rule.

    Not read

General fitness information, not medical advice.