JustGains field manual
All guides
Deep dives

JustGains vs Gravl

I disassembled Gravl’s shipped app to find out what actually builds your workout, got the architecture wrong the first time, and went back. Here is the corrected picture, the exact constants behind its weight prescriptions, and how three different generators answer the same Tuesday.

Updated August 4, 202626 min read

Gravl builds your entire workout on your phone. Which exercises, in what order, grouped into which supersets, at how many sets: all of it decided by code sitting in the app bundle you already downloaded, with no server involved. I know that because I disassembled it. I also know it because I published the exact opposite a few weeks ago, was wrong, and had to go back and work out how I’d missed it.

Obvious disclosure before you read another word: I work on JustGains, which is one of the three apps in this comparison. Read my conclusions with that in mind, because you should. What I can offer instead of neutrality is checkable work. The Gravl and Fitbod numbers below are literal constants in shipped binaries, the function names are real, and if you have the packages you can go and read them yourself. Where a competitor beats us I’ve said so at length, in its own section, with the reason.

I got this wrong the first time, so let’s start there

The first version of this article said Gravl picked your exercises on a server you can’t see, and only worked out how heavy on your phone. It was a tidy story. Fitbod ships its whole generator inside the app; Gravl does the mirror image. I drew a diagram of it and everything. It was wrong, and the diagram has been deleted.

Here’s how I got there. Gravl’s bundle has an API client method that posts to /workout/generator. I found that early, found the load-prescription maths sitting right next to it, went looking for the obvious names a selection algorithm would use, came up with nothing, and concluded selection had to be remote. That reasoning has a hole in it you could drive a bus through. I searched for Fitbod’s vocabulary inside a codebase that doesn’t use it. Fitbod names things muscleUsageUtility and historyUtility. Gravl names them getRankedExercises and planExerciseReservations. Not finding the words I expected is not the same as the code not being there, and I should have known better than to treat one as evidence of the other.

What actually found it was walking the call graph outward from the workout settings screens instead of grepping for names I’d imagined. Function #74962 is 5,499 bytes of bytecode and it eats a single enormous input object that’s assembled entirely on the device: goal, level, muscle split, distribution, duration, focused and excluded muscles, equipment IDs, bodyweight-only flag, deload multiplier, warm-up and rest settings, plus your synced workouts and exercises. None of that is a request body. That’s the generator.

So, corrected: Gravl’s daily workout is generated locally, end to end. POST /api/workout/generator is real, but it’s a different feature. It takes a { text } body, which is the natural-language and voice path, the thing that runs when you type "45 minute push day, dumbbells only". It is not what runs when you open the app on a Tuesday morning and tap start.

I’m leading with the mistake rather than quietly patching it, because a teardown is only worth your time if the person writing it tells you when they were wrong. The load-prescription half of the original piece was right and survives below, unchanged, because it was always read straight out of the bytecode. The architecture half is now the opposite of what it said.

So where does your Tuesday workout actually come from?

Once you have the corrected picture, the interesting comparison isn’t two apps, it’s three. Fitbod, Gravl and JustGains all answer the same question, "what should you do today", and all three answer it with a genuinely different machine. Two of them run in your pocket. One runs in a data centre. And the two that run in your pocket are far less alike than you’d guess.

Three-column comparison of Fitbod, Gravl and JustGains workout generators. Each column lists where it runs, how it picks exercises, what makes it vary, whether running it twice on the same day gives an identical or different session, what happens with no signal, and what the design costs you. Fitbod is marked identical, Gravl and JustGains are marked different.
Same question, three machines. The row that surprised me most is the second one: two on-device generators that share almost no design ideas.

Fitbod ships an engine called Optim in Kotlin, inside the app. It scores every eligible exercise with six terms added together, unweighted, and the largest of those terms by a mile is muscle freshness, worth up to 4 points where a like or dislike is worth 0.5. Before it considers a single exercise it converts your session length into slots priced by position: 15 minutes for the first, then 12, 10 and 7, with core at 5. Sets and reps aren’t computed at all, they’re looked up from 21 hardcoded tables indexed by the day of the year. It is deterministic from top to bottom.

Gravl ships its generator in compiled JavaScript. getRankedExercises and useRecommendedExercises score the exercise catalog that’s already synced to your phone, against your settings, equipment, distribution and focused muscles. Then a placer runs (functions #30097 through #30106) that reserves slots per submuscle and fills them by score priority, getEffectiveSupersets groups what came out, and getRandomWeightedElements picks with weighted randomness. That last one calls Math.random. Nothing is seeded.

JustGains does it on a server, with a language model, in two passes. Pass one asks the model for candidate exercise slots given your prompt, equipment and history. Those slots drive an embedding search against the real JustGains exercise library, which returns ranked genuine exercises rather than plausible-sounding names. Pass two hands the model those ranked candidates and asks it to build the session: order, groups, sets, reps, targets. Then deterministic code cleans up after it.

Two footnotes so this stays honest in both directions. Fitbod isn’t purely local: when you tap generate, a source determiner normally reaches for one of three remote generators (algo_direct_client, algo_llamabod, foundational_model) and Optim is what runs when that call fails. And Gravl’s server generator isn’t vapour, it’s just a different product surface: the text and voice workout builder, not the daily one.

Deterministic, stochastic, or model-driven: pick your poison

This is the part I find genuinely interesting, and it’s the thing no marketing page on any of the three sites will tell you. Ask each app for the same Tuesday three times in a row and you get three different behaviours, for three different reasons.

Diagram showing four exercise slots regenerated three times for each of Fitbod, Gravl and JustGains. Fitbod’s three regenerations are identical. Gravl’s and JustGains’ regenerations each change several slots, highlighted in orange, with notes explaining that Gravl uses Math.random while JustGains uses a model followed by a cleanup pass that drops anything not in the exercise library.
Three regenerations of one day. Orange is what moved. None of these three behaviours is the obviously correct one.

Fitbod gives you the same answer every time, because the day of the year is doing the varying. Same date, same position in the session, same goal, same scheme row. That’s excellent for trust: nothing shifts under you, and the engine cannot invent an exercise or return an empty session. It’s also why some lifters describe Fitbod’s variety as mechanical. A rotation isn’t a progression, and if today’s roll of the calendar doesn’t suit you, tapping regenerate won’t save you.

Gravl rolls dice. Two regenerations of the same day differ, which feels alive and is genuinely nicer when you don’t fancy what came out first. The price is that nothing is reproducible. If Wednesday’s generated session was the best one you’d had in a month, there is no seed to write down, no way to ask for it again, and nobody (including Gravl) can reconstruct why you got it. Weighted randomness also makes the engine much harder to reason about from the outside than Fitbod’s plain sum of six numbers.

JustGains varies because a language model wrote it, which is the least predictable of the three and I’m not going to dress that up. What we do about it is put a deterministic wall behind the model: exercise codes get normalised and matched back against the search results, anything invented is dropped, duplicates are removed, group types are normalised, dumbbell weights are corrected, and non-dumbbell loads are rounded to real increments for your measurement system. If cleanup ends up with zero usable exercises, generation fails loudly rather than returning an empty workout, because an empty result flowing into an edit would wipe the workout you already had. And it costs a network round trip and several seconds where the other two cost milliseconds. That’s a real disadvantage, not a footnote.

FitbodGravlJustGains
Daily workout builtOn your phone (Optim), behind three remote generatorsOn your phone, no server in the daily pathOn our servers
RuntimeKotlin and Java, Dagger, RoomReact Native and Expo, Hermes bytecode.NET service calling a language model
What ranks exercisesSix unweighted score terms, freshness up to 4getRankedExercises over the synced catalogEmbedding search over the real exercise library
How slots get filledPosition tiers priced in minutes (15 / 12 / 10 / 7)Submuscle reservation, filled by score priorityModel drafts, search grounds, model assembles
Sets and reps from21 hardcoded tables, indexed by day of yearA scheme object emitted per exerciseGenerated per session, then fully editable
What makes it varyThe calendarMath.random, unseededThe model, then deterministic cleanup
Same day, generated twiceIdenticalDifferentDifferent
No connectionGenerates fine, that is what Optim is forGenerates fine from synced dataNo generation. Logging and suggestions still work

Gravl’s generator is not a copy of Fitbod’s

This is the bit that made the correction worth the embarrassment. "Both generate on-device" sounds like the story ends there. It doesn’t. The two engines solve the same problem with almost no shared ideas.

Fitbod decides the shape of your session with a clock. Slots are priced by position before any training logic runs, thresholds add slots one at a time, and the position tier then picks which of the 21 scheme tables you get. Gravl decides the shape with anatomy. getReservableSubmuscles and planExerciseReservations reserve slots for submuscles, getScorePriorityExercise and getNextExerciseMuscle fill them, compareSubmuscles and rearrangeSelectedExercises sort out the order, and applyUnplacedReservations mops up whatever didn’t fit. One engine is budgeting minutes. The other is budgeting muscle heads.

There’s a nice detail inside Gravl’s taxonomy, too. It knows about sixteen sub-muscles (three chest regions, three glute regions, two quad regions, obliques and rectus and transverse abs, and so on) but only Shoulders is in its distinct-submuscle list, meaning only the delts are treated as three separately-trending heads. Everything else rolls up. That’s a defensible simplification and it’s clearly deliberate, because the list is a single constant with one entry in it. It does mean upper and lower chest transfer strength to each other freely, which some lifters will consider a feature and some a bug.

Where Fitbod is deeper is selection sophistication: goal-specific position tiers, 21 scheme tables, equipment upranking, a rest ladder, circuits, mobility and warm-up generators. Gravl’s ranker is leaner. Where Gravl is deeper is what happens after selection, which is the next section and is the best material in this entire article.

How Gravl decides how heavy, which is where it’s genuinely good

None of the correction above touches this half. The load-prescription layer runs on your phone, I recovered it exactly, and in two places it is straightforwardly better than what the incumbent does. Worth walking through properly.

The 1RM estimate: Brzycki, capped at 15 reps

Gravl estimates your one-rep max with plain Brzycki: weight ÷ (1.0278 − 0.0278 × reps), reps clamped at 15. Lift 100 kg for 5 and it stores 112.5 kg. There’s no set-count term, so one set of 100 × 5 counts exactly the same as five sets of it. No smoothing, no outlier rejection, no interpolation across gaps. Fitbod, for contrast, adds a 1 + sets × 0.018 term and runs a whole time-series pipeline over your history. More on that in a moment, because it matters.

Alongside the formula sits a lookup table converting reps into a percentage of your 1RM. It follows Brzycki cleanly to 15 reps and then flattens into stair-steps, because Gravl deliberately stops resolving intensity past that point.

Reps% of 1RMNote
1100%The anchor.
588.9%The usual working range, Brzycki is reliable here.
1075.0%Still linear.
1561.1%The last honest value.
1661.1%Identical to 15 reps.
1858.3%Identical to 17 reps.
2055.6%Identical to 19 reps, and the end of the table.

Capping early is defensible, because Brzycki genuinely falls apart past about 12 reps and Gravl’s cap at 15 is arguably more honest than Fitbod extending the same formula to 20. Doing it with stair-steps is cruder: a 15-rep set and a 16-rep set produce an identical estimate, which is not true of your actual strength. Gravl also credits at most two reps in reserve, so it will never assume you had more than two left in the tank.

The order discount, which is Gravl’s best idea

Here’s the mechanic that most justifies Gravl’s marketing. Before prescribing a weight, getOneRepMaxPercentageAdjustment looks at where the exercise sits within its muscle group in today’s session and scales the target 1RM accordingly. The third chest movement of the day isn’t loaded like the first, because physiologically it can’t be.

Bar chart of Gravl’s intra-session order discount worked through on a 100 kg chest one-rep max. The first chest movement uses a multiplier of 1.00 for 100 kg, the second 0.93 for 93 kg, the third 0.88 for 88 kg, and the fourth and beyond 0.84 for 84 kg.
Four bars, one multiplier table, and the single mechanic that most separates Gravl from Fitbod.
Position in the muscle groupMultiplierOn a 100 kg 1RM
1st exercise1.00100.0 kg
2nd exercise0.9393.0 kg
3rd exercise0.8888.0 kg
4th and beyond0.8484.0 kg

The detail that makes this good rather than merely clever: Gravl divides the discount back out when it learns from the result. Train an exercise fourth today and beat the prescribed weight, and your stored 1RM goes up by the right amount instead of being permanently dragged down by the position. The app says so in plain English on the exercise screen. Fitbod has no equivalent at all: position changes your rep scheme and your rest time there, but not the load, so its fourth chest movement is prescribed as if it were the first. On this one, Gravl is right and Fitbod is wrong.

The fair criticism is that the ladder is fixed and muscle-agnostic. Taking 16% off your fourth set of calf raises and 16% off your fourth heavy squat variation are not the same physiological claim, and Gravl makes both with the same number.

Easy, Ideal, Hard: the progression ladder

After a set, Gravl asks how it felt. That rating multiplies your stored 1RM, and the multiplier depends on how heavy the lift already is, which is sensible: going from 2.5 kg to 5 kg on a lateral raise is a real jump, and the same percentage on a 150 kg deadlift is not.

Weight up toEasyIdeal
6 kg×2.00×1.25
12 kg×1.50×1.16
22.5 kg×1.25×1.11
50 kg×1.18×1.06
75 kg×1.10×1.03
100 kg×1.09(next band)
130 kg(above band)×1.02
180 kg(above band)×1.015
Heavier×1.06×1.01

Two things stand out. The Easy and Ideal ladders use different breakpoints above 75 kg, which looks unintentional rather than designed. More importantly, Hard returns exactly 1.00. There is no branch anywhere in getOneRepMaxMultiplier that returns a number below 1. Rating a set as brutal doesn’t lower anything, it just declines to raise it. Fitbod’s equivalent is a capability adjustment clamped to plus or minus 7%, which is far safer and much slower to respond. Gravl’s is coherent if you rate your sets honestly, and has no defence if you don’t.

Cold starts, staleness and detraining

The other genuinely good idea. When you meet an exercise Gravl has no history for, it doesn’t guess from nothing. It looks at sibling exercises in the same muscle group, keeps only those whose strength sits inside a 0.85 to 1.25 ratio of the target, takes the median, damps the observed muscle trend by half (90% for variants of the same lift), and clamps the whole inference to between −5% and +8%.

Two-panel diagram. The left panel plots Gravl’s detraining multiplier over 52 weeks: flat at 100% for a 14-day grace period, declining 0.75% per week, then flat forever on a floor of 92%. The right panel shows the cold-start inference clamp as a bar spanning −5% to +8% around no change, with notes on the 0.85 to 1.25 sibling ratio, the median, and the trend being damped by half.
The clamps are conservative by design. The detraining floor is the one constant that looks wrong: three months off and a year off are treated identically.

That targets the failure mode everyone recognises, where you try incline dumbbell press for the first time and the app suggests something absurd in either direction. Fitbod has nothing comparable: its history handling works per exercise, so a brand-new movement gets no credit for the fact that everything else in that muscle group went up 10% this month. Gravl’s conservatism is well judged too. Capping at +8% means a good month of chest training can’t run away with a movement you’ve never done.

Detraining is the weak link, and it’s the single most questionable constant in the app. After a 14-day grace period, Gravl bleeds 0.75% per week off your stored max and then floors at −8%. Do the arithmetic: it hits the floor about three months in and stays there forever. Come back after a full year away and Gravl still prescribes 92% of your old 1RM. Fitbod decays to a third off by day 180, which is much closer to reality. Combine Gravl’s floor with an effort ladder that has no downward branch and a Gravl 1RM estimate is close to monotonically non-decreasing: it goes up easily, and the only real way back down is editing the number yourself. The app ships screens for exactly that, which suggests the team already knows.

Recovery, on a clock

Gravl’s muscle recovery percentage is a three-band ramp driven by one input: hours since you last trained that muscle. It reaches 20% at 36 hours, 50% at 48 hours, and 100% at 72 hours. Slow for a day and a half, then a fast climb, then done.

The shape is defensible and the endpoint is not. Nothing about volume enters the calculation: one light set of triceps pushdowns and twelve punishing sets produce an identical recovery curve. There’s no personalisation by experience or goal. And 72 hours to full recovery is quick for heavy compound work by most reasonable readings of the literature. Fitbod’s model is clearly better here: a roughly six-day window tuned by experience level and goal, with per-set-group impact so the amount of work you did actually matters.

One small thing I noticed while reading it, offered as a curiosity rather than a gotcha: getRecoveryHoursLeft, the countdown telling you how long until a muscle is ready, branches on 30 and 50 while the curve it’s inverting has its first band ending at 20. Between 20% and 30% recovered the two disagree and the countdown under-reports by up to about fourteen hours. It’s cosmetic, it doesn’t feed the weight prescription, and it’s exactly the kind of thing that survives in any shipped codebase including ours.

JustGains: the same questions, different answers

I’ve just spent a few thousand words on somebody else’s code, so it’s only fair to be specific about ours. JustGains asks the same three questions Gravl does. How strong are you, how recovered are you, and what should you do today.

Estimating strength: RPE-adjusted Epley, not Brzycki

We use an RPE-adjusted Epley estimate. In plain terms it adds the reps you probably had left to the reps you actually did, then applies weight × (1 + effective reps ÷ 30). A set logged without RPE still gets an estimate using a baseline assumption of RPE 7, flagged internally so the app can nudge you to log the real thing. If the effective rep count lands outside the range where the formula is trustworthy, we stop estimating and fall back to the weight you actually lifted, on the grounds that a number you can defend beats a number you can’t.

GravlJustGains
FormulaBrzycki, weight ÷ (1.0278 − 0.0278 × reps)Epley, weight × (1 + effective reps ÷ 30)
Effort signalEasy / Ideal / Hard, rated after the setRPE 6 to 10, or an assumed 7 when not logged
What the rating doesMultiplies your stored 1RM upward for the next sessionRefines the estimate of the set you just did
Past ~15 effective repsClamps and keeps producing a number, so 15 and 16 reps matchStops estimating and uses the lifted weight as a floor
Can the estimate fall?Only via detraining, floored at −8%Yes, it follows the sets you log

The philosophical difference is worth naming. Gravl’s rating is a control input: you tell it a set was easy and it moves your prescription up. Ours is a measurement input: you tell it a set was RPE 8 and it sharpens the estimate of what that set proved. Gravl’s version is more responsive when you rate honestly and has no defence when you don’t. Ours is slower to celebrate and harder to fool. Full write-up here if you want it: what is an estimated 1RM.

Recovery: a clock versus a logbook

This is the sharpest contrast in the whole comparison, because both apps show you a coloured body diagram and they mean different things by it.

Two stacked charts on the same 0 to 96 hour axis. The top chart plots Gravl’s recovery percentage as a three-band ramp reaching 20% at 36 hours, 50% at 48 hours and 100% at 72 hours, annotated volume-blind and not personalised. The bottom chart shows the JustGains model as two bands split at 2.5 days: sets inside the window are counted at full weight and marked fatigued, and older sets count one third and are marked recovering.
Gravl asks how long it’s been. JustGains asks how much you did, how recently, and how it compares with everything else you trained this week.

We work from sets rather than from the clock alone. Sets inside a rolling 2.5-day window count at full weight and mark the muscle group fatigued. Once work falls outside that window it keeps counting, at one third weight, and the group is marked recovering. When there’s no work left in the window at all, the group is recovered. The intensity you see on the diagram is relative: we total the weighted sets across every muscle group and shade each one against the most loaded group in your current view.

So a shoulder session of three sets and a shoulder session of eighteen sets look different in JustGains and identical in Gravl. Neither app is measuring muscle damage, and ours is an estimate too, sitting between Gravl’s 72-hour clock and Fitbod’s six-day decay. But volume is the input most obviously connected to how wrecked you feel, and ignoring it is a real limitation. Full mechanics in how JustGains calculates muscle fatigue.

Who owns the plan

The structural difference matters more than any constant. In Gravl the workout is an answer the app produces for you. In JustGains it’s a document you own. Our AI builder drafts complete workouts and multi-week plans around your equipment, schedule and goals, and what it hands back is an ordinary editable workout: swap the exercises, change the sets, reorder it, save it as a routine, share it with a training partner, run it unchanged for six weeks, or throw it away and build one by hand.

JustGains workout editor listing exercises with target sets, reps and weight, plus a coaching note under Dumbbell Bench Press.JustGains set logging screen showing completed sets with weight and reps and the option to adjust targets mid-session.
Whatever produced the workout, generated or hand-built, you end up in the same editor with the same controls.

Alongside that sits a deterministic, rule-based suggestion engine that reads a rolling 7-day window of your completed sessions and proposes what to train next. It recognises push/pull/legs and upper/lower patterns, tracks which muscle buckets look neglected, and watches consecutive training days. It’s not an AI and I’m not going to pretend it is; it’s rules, and it runs on your phone, which is why it still works when the generator can’t. That write-up is here.

JustGains vs Gravl, head to head

GravlJustGains
Exercise selectionOn-device ranking plus a submuscle-reservation placerServer-side two-pass generation over your real exercise library
Variety modelStochastic, Math.random, not reproducibleModel-driven, then deterministic cleanup
Who owns the planThe app. You accept or swap within itYou. Everything generated is a normal editable workout
1RM modelBrzycki capped at 15 reps, no smoothingRPE-adjusted Epley, assumed RPE 7 when unlogged
Intra-session fatigueOrder discount of 1.00 / 0.93 / 0.88 / 0.84Not modelled in the load prescription
Recovery modelHours since last session, 100% at 72 hoursWeighted set buckets over a 2.5-day window
Generates offlineYes, the whole generator is on your phoneNo. Logging and rule-based suggestions run on-device
Beyond liftingCardio ratings, plus a separate companion app for foodGPS runs and walks, nutrition, goals, streaks, social feed
WatchesApple Watch, Wear OS, and Garmin effort captureApple Watch, plus Garmin and Strava activity sync
PriceSubscription after a trial (see below)Free for most features
Imports your historyHas its own importer for incoming historyReads Fitbod, Hevy, Strong, StrengthLog and Caliber exports

Scope is the other honest gap, in our favour. Gravl is a very good strength product with a separate companion app for nutrition. JustGains treats lifting, running, food, goals and friends as one training life: finish a run and it lands in the same feed as your squat session, your macros sit next to your volume trends, and squads and leaderboards do the nudging.

JustGains GPS activity screen tracking a run with live pace, distance and a map of the route so far.JustGains food search screen showing matched foods with calories and macros ready to add to a meal.
Runs and food live in the same app as the barbell work, which is the part a dedicated strength app can’t match.

The replies I’d expect, answered

If I posted this anywhere with a comment section, these are the four objections that would be at the top, so let me get to them first.

  • "You work for one of these apps, this is an ad." Half right. I do work on one of them, which is why the disclosure is in the third paragraph rather than a footer. The defence isn’t my good character, it’s that everything competitive here is falsifiable: the constants are in binaries you can pull yourself, and the two mechanics I say Gravl does better than the incumbent are mechanics we don’t have. An advert would not include the sentence "Gravl is right and Fitbod is wrong" about a thing neither of us built.
  • "You got the architecture wrong, why should I trust the rest?" Completely fair, and it’s the reason the mistake is at the top instead of buried. What I’d point at is the difference in evidence type. The architecture claim was an inference from absence, which is the weakest kind of reasoning and the kind that bit me. The load-prescription numbers are literal constants read out of named functions, which is the strongest kind available short of source code. Those two were never the same quality of claim, and I should have flagged that in the first version.
  • "Static analysis isn’t the running app." True and worth stating clearly. I read shipped binaries. I can tell you what code is in the package and what constants it holds; I cannot tell you which code path your specific install takes on a given day, whether a server flag is redirecting you, or what a remote model returns. Where an engine is remote, as Fitbod’s primary generator is, I’ve said the model isn’t recoverable rather than guessing at it.
  • "72-hour recovery is fine, actually." Maybe for you. The criticism isn’t the number in isolation, it’s that the number is the only input. One set and twelve sets producing an identical curve is the part that’s hard to defend, and it’s the same criticism I’d level at any purely time-based model including a simpler version of our own.

Price, plainly

Gravl is free to download and the training features sit behind a subscription. As of August 2026 the US App Store listing shows a monthly membership at around $14.99, a three-month option around $34.99, and yearly memberships listed between roughly $59.99 and $79.99. Multiple yearly prices on the same listing usually means regional or experimental pricing, so treat these as a guide and check the store or gravl.ai for what you’d actually be charged. I couldn’t confirm a permanent free tier: the marketing offers a free start, which in practice reads as a trial.

JustGains is free for most features on iOS, Android and the web, including AI workout generation, the full logger, GPS activities and nutrition tracking. The core logger and your data stay free. I’m not going to dress that up as charity: we’re newer, and a free tier is how a newer app earns a trial.

Where Gravl is the better pick

A comparison page that concedes nothing is an advert. Here’s where I’d genuinely point you at Gravl instead, and the first two got stronger once I found the real architecture.

  • You train somewhere with no signal. This is the concession my first draft got backwards. Gravl’s whole generator is on your phone, so a basement gym with no bars is fine. JustGains generation needs a connection. Logging works offline and syncs later, but generation does not.
  • You want the load prescription solved, not the app. The order discount is correct and we don’t have an equivalent. If most of your sessions run three or four movements deep into one muscle group, Gravl will prescribe those later exercises more sensibly than we will.
  • You rotate exercises constantly. Sibling-exercise transfer means new movements start at a plausible weight instead of a guess. If you rarely repeat a lift twice in a month, that’s worth a lot.
  • You want to be told why, every time. Gravl writes a per-exercise explanation for each weight change out of real internal state: the order adjustment, the trend multiplier, the detraining multiplier, how many sessions since you trained that muscle. It’s the best in-app explainability I’ve seen in this category and it’s a legitimate reason to choose it.
  • You train across two gyms with different kit. Per-gym equipment profiles with per-gym weight increments are more thoughtful than a single global rounding rule, and most apps get this wrong.
  • You want Wear OS, or Garmin effort capture from your wrist. Gravl ships both. Our watch story today is Apple Watch, with Garmin and Strava as activity sync rather than set logging.
  • Levels, XP and leaderboards keep you going. Gravl leans hard into Strength Score, badges and streaks. If gamification is what gets you through the door, it’s well built.
  • You just want to be told what to do, forever. Gravl’s whole product is a daily answer, refined over years. We give you a good answer plus a set of controls, and some people don’t want the controls.

Bringing your training history over

Honesty first: the JustGains importer does not read a Gravl export today. It reads Fitbod, Hevy, Strong, StrengthLog and Caliber CSVs, and an unrecognised file is rejected rather than guessed at. I also couldn’t find a user-facing export inside Gravl’s app, which is the harder problem, since an importer is not much use without something to import.

So the realistic options are less satisfying than I’d like:

  1. Ask Gravl for your data. Under GDPR in the EU and UK, and CCPA in California, you can request a copy of the personal data a company holds on you, and your workout log is personal data. Support inside the app is the place to start. If you get a machine-readable file back, send it to us and we’ll look at supporting it.
  2. Run both for a training block. Nothing stops you logging in both apps for a few weeks while you decide. It’s tedious, but it’s the only way to compare two prescription engines on your own body rather than on a comparison page.
  3. Start from your working numbers. In practice, most of what a new app needs is your current top sets. Enter your main lifts once, log two or three sessions, and the estimates catch up quickly. Your old history is precious, but it isn’t what determines Thursday’s squat.
  4. Bring in what you can. If you also used Fitbod, Hevy, Strong, StrengthLog or Caliber at any point, the free importer will pull that history in on the correct dates, and your PRs, estimated 1RM curves and volume charts rebuild from the raw sets.

What JustGains doesn’t do yet

In the same spirit. We don’t model intra-session order the way Gravl does, and after reading their implementation I think they’re right about it. We can’t generate a workout without a connection, and both of the apps in this article can. We’re newer, our community is smaller than the incumbents’, and parts of the app are visibly under active development. If you want the most battle-tested version of a single feature on this page, an established app may still edge us out. What you get in exchange is an app that improves weekly and a price of zero while we earn your trust.

The honest bottom line

Gravl turned out to be a more impressive piece of engineering than my first draft gave it credit for. A complete generator in compiled JavaScript, running on your phone, with a submuscle-reservation placer and a load layer whose two best ideas the market leader doesn’t have. I called that architecture the mirror image of Fitbod’s and it isn’t. It’s a sibling with different opinions, and correcting that made the comparison more interesting, not less.

The real difference between us isn’t on-device versus server. It’s what you’re handed at the end. Gravl gives you an answer, a very good one, produced by a roll of the dice you can’t repeat and can’t inspect. JustGains gives you a draft and then gets out of the way: reorder it, rewrite it, keep it for six weeks, share it, delete it. Add runs, food, goals and friends in the same app, at no cost, and you can run that comparison on your own body instead of taking anybody’s word for it. Including mine, which you shouldn’t, on account of the disclosure at the top.

FAQ

Keep learning

Still stuck?

Ping us for a spotter

support@justgains.com
Learn home · Train hard · Read the instructions