Glucose Variability Detection Model
What This Model Does
Infers Glycemic Variability and Metabolic Flexibility patterns from CGM data in non-diabetic adults for Vitals coaching purposes. This is a metabolic phenotyping tool, not a diagnostic instrument.
Input Requirements
- CGM data: glucose readings (mg/dL) with timestamps
- Minimum wear duration: 14 days (7 days minimum, 14 preferred)
- Minimum 3 days of data for CV/SD calculation
- Meal event tagging (optional but improves postprandial analysis)
Core Detection Logic
Metric Calculation
def glucose_variability_detection(cgm_readings):
"""
cgm_readings: list of {'glucose': float, 'timestamp': datetime}
Returns: dict of computed metrics and flag status
"""
import statistics
glucose_vals = [r['glucose'] for r in cgm_readings]
n = len(glucose_vals)
mean_glucose = statistics.mean(glucose_vals)
sd = statistics.stdev(glucose_vals)
cv = (sd / mean_glucose) * 100 # Coefficient of Variation
# TIR: time in 70–140 mg/dL
tir = sum(70 <= g <= 140 for g in glucose_vals) / n * 100
# TAR: time above 140 and 180 mg/dL
tar_140 = sum(g > 140 for g in glucose_vals) / n * 100
tar_180 = sum(g > 180 for g in glucose_vals) / n * 100
# TBR: time below 70 mg/dL
tbr = sum(g < 70 for g in glucose_vals) / n * 100
# MAGE: mean amplitude of glycemic excursions
# (requires meal-tagging to compute accurately; simplified proxy below)
mage_approx = sd # SD is a proxy for MAGE in the absence of meal tagging
return {
'mean_glucose': round(mean_glucose, 1),
'sd': round(sd, 1),
'cv': round(cv, 1),
'tir': round(tir, 1),
'tar_140': round(tar_140, 1),
'tar_180': round(tar_180, 1),
'tbr': round(tbr, 1),
'mage_proxy': round(mage_approx, 1)
}Metabolic Concern Flags
| Flag | Threshold | Action |
|---|---|---|
| CV elevated | >20% | Pattern coaching — dietary/activity intervention |
| TIR low | <85% | Metabolic concern — investigate causes |
| TAR >180 elevated | >5% of time | Clinical referral |
| TBR <70 sustained | Any sustained period | Clinical referral — hypoglycemia risk |
| Fasting >126 mg/dL | Consistent across days | Clinical referral — possible diabetes |
| Random >200 mg/dL | Consistent across days | Clinical referral — possible diabetes |
Metabolic Flexibility Detection
Postprandial Recovery (Meal Response)
def postprandial_recovery(cgm_data, meal_timestamps):
"""
Estimate metabolic flexibility via post-meal glucose recovery.
Recovery time: minutes for glucose to return to ±10% of pre-meal baseline.
Slower recovery → potentially impaired metabolic flexibility / insulin resistance.
Note: PREDICT study (PMID 34241823) shows ~30–50% day-to-day reproducibility
of individual meal responses. Treat individual meal scores as hypothesis-generating,
not validated.
"""
results = []
for meal_ts in meal_timestamps:
# Get pre-meal baseline (30 min window before meal)
pre_meal = [r for r in cgm_data
if meal_ts - 1800 <= r['timestamp'] <= meal_ts - 300]
# Get post-meal readings (up to 3 hours)
post_meal = [r for r in cgm_data
if meal_ts <= r['timestamp'] <= meal_ts + 10800]
if not pre_meal or not post_meal:
continue
baseline = statistics.mean([r['glucose'] for r in pre_meal])
threshold = baseline * 1.10 # 10% above baseline
recovery_readings = [r for r in post_meal if r['glucose'] <= threshold]
if recovery_readings:
recovery_time_min = (
recovery_readings[0]['timestamp'] - meal_ts
).total_seconds() / 60
else:
recovery_time_min = None # Did not recover within 3h window
results.append({
'meal_time': meal_ts,
'baseline': round(baseline, 1),
'peak': round(max(r['glucose'] for r in post_meal), 1),
'recovery_min': round(recovery_time_min, 0) if recovery_time_min else None,
'flag': recovery_time_min is None or recovery_time_min > 120 # >2h = slow
})
return resultsEvidence-Based Confidence
| Signal | Confidence | Source |
|---|---|---|
| CV >20% as metabolic concern | Moderate | HR ~1.3–1.8 per SD; PMID 36099500 |
| TIR <85% as metabolic concern | Moderate | Metabolic dysfunction markers; PMID 35111000 |
| Individual meal response score | Low | Reproducibility 30–50%; PMID 34241823 |
| Postprandial recovery time | Low–Moderate | Mechanistically plausible; not independently validated |
What This Model Cannot Detect
- Type 2 diabetes diagnosis (requires clinical glucose criteria, not CGM patterns)
- Specific nutrient responses (meal reproducibility too low)
- Optimal dietary recommendations from CGM alone
- Causally that “glucose spikes cause damage” in non-diabetics
Confounds and Limitations
- Day-to-day variability: Individual CGM metrics have significant day-to-day variability; do not act on single-day readings
- Meal tagging accuracy: Postprandial analysis requires accurate meal timestamps — self-reported meals are error-prone
- Reproducibility ceiling: Even identical meals produce different glucose responses 30–50% of the time (PREDICT; PMID 34241823)
- No non-diabetic TIR targets: Diabetic TIR targets do not apply; non-diabetic “normal” ranges are not clinically validated
- Stress/sleep effects: Acute stress, poor sleep, illness, and medications affect glucose patterns independently of diet
Evidence Boundary Label
⚠️ EVIDENCE BOUNDARY This model applies CGM data to metabolic phenotyping in non-diabetic adults. It does not constitute clinical glucose monitoring, diabetes screening, or medical advice. All coaching must be framed as pattern discovery rather than clinical assessment. Clients with abnormal glucose values must be referred to a licensed healthcare provider for clinical evaluation.
Related Notes
- CGM Glucose Patterns Non-Diabetic — hub note with full protocol
- Glycemic Variability — mechanism note
- Metabolic Flexibility — phenotyping concept
- Postprandial Glucose Response — meal response patterns
Sources
- PMID 36099500 — Glycemic variability as independent T2D predictor
- PMID 35111000 — TIR and metabolic dysfunction association
- PMID 33410452 — Glycemic variability and cardiovascular risk
- PMID 34241823 — PREDICT meal response reproducibility study
Last updated: 2026-04-21 (BATCH74 vault conversion)