The usual preamble. Everything described here is highly experimental. It uses insulin in an off-label fashion, it isn’t in the current, supported version of AndroidAPS or Trio, and nothing here is medical advice. It’s an n=1 that’s grown into a slightly-larger-than-n=1, shared in the open-source, #WeAreNotWaiting spirit so the learning is useful to others. Take the ideas, not the dose settings!
I’ve written about Boost here a few times: when it was a possibility, when I ran it as an n=1 experiment and reported back on four months of it, and when I wrote about bringing step counts into the loop. If that’s where you last left it, quite a lot has changed since, and the version I run now doesn’t much resemble the one in those pieces.
So this is an update, and a slightly different sort of one. At some point I stopped adding things to Boost and started measuring the things already in it, which is a different activity and tends to retire more than it confirms. What follows is what Boost was for, how it got from there to here, what’s in it now, where the machine learning sits, and which parts of it have earned their place.
What Boost was for
Boost has always had one job: reduce the burden of diabetes management; first by removing the need for mealtime management, and subsequently by integrating other capabilities.
That’s a harder ask than it sounds, and the reason is insulin, not software. Injected under the skin, insulin takes the best part of an hour to do most of its work. A meal is largely absorbed inside that window. So if you wait until the rise is obvious before you dose, which is what a conservative loop does, quite sensibly, you’re always behind it, and no amount of cleverness afterwards gets that time back. The introduction of Lyumjev made that substantially less of a problem.
The original Boost kept the whole AndroidAPS engine and replaced one thing: the decision about how big the next micro-bolus should be. Basal, dynamic sensitivity, the predictions and every safety gate stayed exactly as they were. That constraint was deliberate, it’s still there, and it’s the main reason I’ve been willing to run this on myself for as long as I have. The parts that stop you coming to harm are the parts that have been stopping people coming to harm for years.
What went in place of that one decision, first time round, was a ladder of eight tiers, each licensing a bit more aggression than the last. No machine learning, no models: a set of rules about glucose, its rate of change and its acceleration, and a decision each cycle about which rung to stand on. Be braver into a rise than a stock loop dares to be, and rely on the safety gates underneath to catch anything that went too far.
It worked, in the sense that it produced a usable fully closed loop: I quoted 81.2% time in range and 5.6% below over four months. It also produced post-meal highs I wasn’t thrilled about and lines noticeably wider than my hybrid setup, and I said so at the time.
How did we get here?
We’ve gone through multiple versions numbers to get where we are, however the version numbers matter a lot less than what changed underneath them.
The eight tiers were discrete dosing modes and the algorithm picked one each cycle. That has an obvious problem, which is that the world isn’t eight states and a tier that’s right at minute zero of a meal is wrong by minute forty. It has a less obvious one too, and that’s the one I couldn’t tune my way out of: how hard to push and how much to hold back were decided together, inside the same rung. Every time I made Boost braver at chasing a meal I made it more dangerous two hours later, and I spent a long time trading one against the other without ever getting both.
The current version stopped asking which tier it was in. It now carries a meal hypothesis across cycles and scales what it does to how confident it is. Idle, when nothing’s happening and the underlying loop just gets on with its job. Observing, when something might be starting, where it leans in gently rather than committing. Confirmed, when the evidence is good enough. Committed, while the meal is clearly running. And recovering, as the insulin takes hold.
Recovering is the state that did the most for me. Before it existed, a loop watching glucose come down from a meal peak would look at a number that was still high, conclude it was still high, and dose again, having no representation at all of the fact that it had already dealt with this. Recovering winds down on purpose instead, which made a positive change to post meal results.
The deeper change is that confidence and restraint are now decided in different places. I can make Boost keener at recognising a meal without simultaneously making it more aggressive about acting, because the brakes sit outside the component that forms the hypothesis. That was never possible with the tiers, and it’s why the last year has been a matter of adding and testing components rather than endlessly retuning one knob against another.
The machine learning came later and separately. It went in as a plugin of its own partway through this year, purely as a hypo-risk score whose only power was to shrink a dose the rules had already chosen, and was retrofitted into the earlier engines once it had shown it did no harm. It has never been the thing that decides to dose.
The other significant change is that the settings stopped being mine. Early Boost had knobs, the knobs had defaults, and the defaults were whatever suited me, which is fine for an n=1 and less helpful for anyone else. The group running it now spans a wide range of total daily doses. The current version derives each person’s settings from their own history, tightens for anyone whose time below range says it should, and re-derives periodically rather than once at setup. Anything that adds insulin only switches itself on for someone whose glucose is already sitting comfortably.
Across the group, a fully closed loop with no meal announcement currently runs around 87% time in range give or take 6%, with time below 54mg/dl averaging 0.9% and a median of 0.7%, though about a quarter of people sit above 1%. As far as it goes, that’s a decent set of results with no mealtime announcement, and without additional therapies, a consistent regime or diet changes, is probably heading to the top end of what’s possible with the oref algorithm as it stands.
What’s actually running in Boost?
The meal state machine is the core. Around it:
- A composed brake: restraints that compound rather than override each other, and which audit at about 90% correct when they fire.
- Absolute floors under everything. Time-below-range limits that can only ever tighten, and which no statistical argument is allowed to loosen. That rule has saved me from myself more than once.
- Caps on how much insulin can go to a single meal, and on cumulative micro-bolus volume in a rolling window.
- A sleep detector built from heart rate and step activity rather than a clock, which learns your usual sleep and wake times and suppresses the aggressive tiers overnight. Overnight is where a fully closed loop can hurt you, because nobody’s watching and a meal-shaped rise at 2am is almost never a meal.
- Steps as a live input, blended across phone and watch, withdrawing insulin when you’re active.
- Heart rate, which is wired in and off by default.
Heart rate deserves a note, because it’s the one part of this I’ve built out properly and then left switched off for most people. When it’s on, a Garmin or Wear watch feeds heart rate in, and Boost classifies it into Karvonen zones and an exercise state: vigorous aerobic, moderate, light, resistance, stress, resting. Vigorous aerobic pulls the profile back a further 10% and raises the target; resistance and stress raise the target without touching the profile, because those raise glucose rather than lowering it. The reference points for all of that are learned from you rather than assumed, with resting heart rate taken as the median of the tenth percentile during sleep and the daytime figure the same statistic while awake, neither available until you’ve accumulated about a week of nights.
There’s one branch of it I’d keep even if I switched off everything else. Boost has an inactivity behaviour that raises insulin when you’ve been sitting still, and a heart rate at or above moderate suppresses that entirely. Sitting still with a heart rate of 130 is not the same as sitting still, and steps alone can’t tell you which one you’re in. Cycling, rowing and lifting all look sedentary to a pedometer.
The reason it’s off by default is boring rather than principled: it needs a watch that reports reliably, and overnight heart rate collection on Wear has died on me repeatedly through the OS killing the listener. If you’re wearing something that behaves, it’s worth turning on. If you’re not, the steps path covers most of it.
There is also a tuning guide, a simulator and an analyser. The latter two allow you to plug your nightscout in and help you to understand where boost might help or what boost might already be doing.
And underneath all of it, the bit I’d most want anyone else building this sort of thing to copy: nothing reaches the dose path without running as a shadow first. A shadow computes what it would have done, writes it to the log, and delivers nothing. It runs like that across everyone for as long as it takes to build up evidence, and only then does anyone argue about it.
That last part is where most of this year’s work has gone, so it’s worth going into.
Which of the shadow tests work?
Thirteen components run in shadow at the moment. Scoring them against the outcome each one isnsupposed to predict is how they get promoted, and it’s also how things get dropped.
The clear success is the accelerating-meal detector. It fires on 8.8% of cycles, and 40.6% of those are followed by a rise of at least 1.7 mmol/L within 45 minutes, against a background rate of 19.6%. That’s measured on 154,000 cycles across eleven people. Roughly double the base rate, at a firing rate low enough to act on, is exactly what you want from something whose job is to notice a meal starting when nobody has announced it. It’s the strongest detection result anywhere in the system, and it’s the one I’m likely to build next.
The physiological forecaster took a second look to understand the results. It’s a proper ensemble Kalman model of glucose and insulin, and when I first scored its thirty-minute prediction against “assume glucose stays where it is” it won by about 0.06 mmol/L. Real, consistent across nearly everyone, and small enough to be nothing of any value.
That average was hiding a lot more. Glucose is near enough flat for a quarter of all cycles, so those cycles drag any average towards zero. Split by how fast glucose is actually moving and the picture changes: on cycles flat to within 1 mg/dL per 5 minutes the model is marginally worse than doing nothing, and on cycles falling faster than 3 it’s better by 0.2 mmol/L, which is three times the headline number and sits where you’d actually want a forecast. At an hour ahead it holds that lead, and it leaves simple extrapolation far behind, because projecting a five-minute trend out sixty minutes doesn’t tend to turn out so well.
Then the part that decides what it’s good for. I’d assumed the use for a forecaster here was anticipating lows, so I scored it on the cycles that ended below 4.0 mmol/L. The result? It predicts a softer landing than what actually happens. Tested head-on as a hypo warning it can’t separate anything that the current glucose reading doesn’t separate just as well, at any alarm rate. The model damps falls, and identifying falls is the job I wanted it for.
When trying to work out whether it had any utility , I found something I wasn’t expecting. The engine already writes down glucose, three trend averages, insulin on board and announced carbs on every cycle. Fit a model on four of those columns, glucose and its trends, and test it on people it never saw during training, and it forecasts thirty minutes ahead better than the twin does. Hand that model all nine of the twin’s outputs on top and it gets no better. Same story on the hypo question: a classifier on the existing columns separates the next forty-five minutes well, and adding the twin moves it by nothing at all.
That’s not the answer I expected. Whilst the twin had an edge over what was already there, the information behind it is already sitting in the deltas, and a cheap fit pulls more of it out than a physiological model does. It’s a more expensive way of saying what the trend already says. So it’s being retired rather than combined, and the interesting thing it leaves behind is the four-column fit, which cost almost nothing and is the strongest short-horizon predictor I’ve measured.

Three are being dropped. A component estimating whether a rise will end somewhere that matters scores 0.730, where the current glucose reading on its own scores 0.785. An anticipatory backout barely separates the cycles it arms on from the ones it doesn’t. And a plateau detector, which looks for a high that’s stuck and proposes a small nudge, turns out to flag highs that come down slightly better than the ones it ignores, so it’s finding highs that are already resolving rather than stuck ones. Which was the opposite of my intention.
Two more had faults. One returned a null on every rejection, so a model that failed to load and a genuinely quiet day looked identical to a failure. The other asked for the day’s insulin total through a function that refuses the whole window if any moment in it lacks a profile, and then gave up silently. Both are fixed and both are now running properly for the first time, which means they get scored on the next review.
Where Boost uses machine learning
Let’s be very clear about what we mean by machine learning here. Boost’s algorithm contains no learning in the process by which it makes dosing decisions. It also contains no links to large language models for anything. Instead, it uses models that have been built on large amounts of historic data, using traditional learning techniques. Claude Code has been very helpful in the generation of these models (indeed, as a quant I used to know said to me, “It’s worth identifying the data and the decisions you want, then getting an LLM to help with the creation of the LGBM model.”). It has also been useful in creating the python scripts that allow backtesting against historic data when new models are built (by typically using a cohort that has been left out of the training data) before anything makes i into the shadow form we’ve already discussed.
Two models are on the dose path. Both are gradient-boosted trees, trained offline, exported as JSON and walked on the phone by about fifty lines of Kotlin in a few milliseconds. Nothing trains, learns or adapts inside the loop. That’s a rule, not an implementation detail. A system that learns while it doses can learn something wrong while it doses.
One estimates the probability of a sustained hypo and can only ever reduce a dose. The other estimates the probability that an unannounced meal is starting, and it’s the only learned thing allowed to add insulin, which is why it gets the harder look.
I refitted the hypo model on 183 people from the OpenAPS Data Commons, about eleven million decision cycles, against the 32 it was originally trained on. On 1.7 million rows where both old and new are out of sample, the refit scores 0.861 against 0.847, which is a real, but small, improvement.
Except it isn’t small where it counts. The model is only consulted on cycles that get past the low-glucose guard, which is about half of them, and the half it never sees carries most of the hypos. Judged on the population where it actually acts, the refit’s advantage roughly triples. It also explains why the shipped model scores 0.85 on the Commons and somewhere between 0.52 and 0.72 on the people running it: it’s being marked on the hard half.

It became rapidly apparent that the only way to really calibrate the new model is to run it against user’s data for a week while maintaining the old model, then flipping when that process is complete, if it proves to be the right answer.

Two more models are in the pipeline. One asks whether a fall that’s already twenty minutes old is going to end below 3.9, and it scores 0.780 on the sixteen people who contributed no training data at all, against 0.746 for glucose plus the time of day, and it’s better for every one of those sixteen. The other isn’t a model, it’s a feature: a person’s own hypo rate by hour of day turns out to be worth more than tripling the size of the training set was. The population’s hour-of-day rate is worth nothing at all.
That last one is the result that’s perhaps the most unexpected. Scaling the training data stops delivering additional benefits somewhere around 112 people. Whatever’s left in this system looks like it’s in each person’s own history rather than in bigger models, which changes how we approach delivering this to people.
What’s next?
Getting the new models either into shadow or running alongside the existing one to prove them out, and assuming it works okay, adding the fall model as a restraint in the safety gates. That’s number one. Then investigate the personal hour-of-day hypo feature.Alongside that, there’s the pre-meal exercise mode. Exercise near a meal is where these systems fail people most often, the published guidance is fairly specific about what to do, and almost all the machinery it asks for already exists in Boost but is wired to something else. What’s missing is any way to tell the loop that exercise is coming and what it is likely to be.
It’ll be a declaration rather than a detector, and that’s settled by existing research. Tagougui and colleagues put 37 adults through announced exercise with a reduced meal bolus, announced with a full bolus, and unannounced, and got 2.0%, 7.0% and 13.0% time below 3.9 respectively. Nothing in the detection literature separates two approaches by anything like that much. When Jacobs and colleagues compared detecting exercise automatically from wearable data against simply prompting the person to confirm, across 27 participants, the two couldn’t be told apart: 1.3% against 2.5% time below 3.9, well inside the noise. Asking is cheap and it works, so that’s what it will do.
None of which is where I expected to be when I started building this. But it seems to be working for me and others. It has come a long way since I first thought of it back during the COVID era, but as the title says, and the last section highlights, while we can come a long way towards Fully Closed Loop, exercise detection only makes a differences with regular timing, or magic. Or an additional hormone (glucagon, I’m looking at you). Right now in the insulin only world, it still needs some help.
Boost Readme is available at: https://github.com/tim2000s/Boost-in-AAPS_3.4/blob/master/README.md
Discover more from Diabettech - Diabetes and Technology
Subscribe to get the latest posts sent to your email.
Leave a Reply