A supplement label can hide how much of an ingredient is in the tub. It lists a "proprietary blend" with one total weight and a column of names under it, and no amount next to any of them. I run a label checker for pre-workout powders. The easy thing for a checker to do is mark every one of those lines "hidden" and move on. That's accurate, but not very useful.
It turns out the US labelling rule gives you more than nothing. With the blend's total weight and the order of the names, you can put hard limits on each ingredient. This post is the arithmetic, about 30 lines of Python, and what the limits can and can't tell you.
What the label rule gives you
The rule is 21 CFR 101.36, the federal regulation for the Supplement Facts panel. Two parts of paragraph (c) matter here (full text at Cornell LII).
Paragraph (c)(2) says the dietary ingredients in the blend "shall be declared in descending order of predominance by weight". Heaviest first.
Paragraph (c)(3) says the amount printed next to the blend's name "shall be the total weight of all other dietary ingredients contained in the proprietary blend".
So for every blend you get two facts: the total, and the order. That's enough for two inequalities.
Two inequalities
Say a blend has k ingredients and a total weight T, listed heaviest first.
The first ingredient is at least T / k. It weighs at least as much as each of the others, so k copies of it weigh at least T. If it weighed less than T / k, the whole blend would weigh less than T.
The ingredient in position n is at most T / n. The n ingredients from the top down to it each weigh at least as much as it does. Together they can't weigh more than T, so n copies of it can't either.
Everything after position 1 has a lower limit of zero. The label allows the first ingredient to take almost all the weight.
The code
UNITS_TO_MG = {"mg": 1.0, "g": 1000.0, "mcg": 0.001, "µg": 0.001, "ug": 0.001}
def to_mg(amount, unit):
"""Convert a label amount to milligrams."""
return amount * UNITS_TO_MG[unit.strip().lower()]
def blend_bounds(total_mg, k):
"""Bounds for each position in a blend of k ingredients listed heaviest
first, when the label only gives the blend's total weight."""
bounds = []
for n in range(1, k + 1):
low = total_mg / k if n == 1 else 0.0
high = total_mg / n
bounds.append((n, low, high))
return bounds
def compare(low_mg, high_mg, studied_mg):
"""What the bound can and can't say against a research dose."""
if high_mg < studied_mg:
return "below the studied dose, even at the most the label allows"
if low_mg >= studied_mg:
return "at or above the studied dose, even at the least the label allows"
return "can't tell from the label"
to_mg exists because labels mix units. A blend total in grams and a research dose in milligrams is the easiest way to be wrong by a factor of 1,000.
compare has three answers, not two. That's the important part. A range is not an amount, so most of the time the honest answer is the third one.
Running it on a real label
One best-selling pre-workout lists a 6,603 mg blend of eight ingredients, with beta-alanine first. Studies on beta-alanine used 3.2 to 6.4 g a day, so the low end is 3,200 mg.
total = to_mg(6603, "mg")
n, low, high = blend_bounds(total, 8)[0]
print(f"position {n}: {low:.0f} mg to {high:.0f} mg ->",
compare(low, high, to_mg(3.2, "g")))
position 1: 825 mg to 6603 mg -> can't tell from the label
Beta-alanine is somewhere between 825 mg and the whole 6,603 mg. The studied dose sits inside that range, so the label can't say which side of it the product is on. The checker leaves that line as "hidden in a blend" rather than guessing.
When the limit does decide
The upper limit becomes useful further down the list. Here is a made-up label to show it: a 2 g blend of five ingredients, with citrulline third. Studies on citrulline used about 4 g.
total = to_mg(2, "g")
n, low, high = blend_bounds(total, 5)[2]
print(f"position {n}: {low:.0f} mg to {high:.0f} mg ->",
compare(low, high, to_mg(4, "g")))
for n, low, high in blend_bounds(total, 5):
print(f" #{n}: {low:7.1f} to {high:7.1f} mg")
position 3: 0 mg to 667 mg -> below the studied dose, even at the most the label allows
#1: 400.0 to 2000.0 mg
#2: 0.0 to 1000.0 mg
#3: 0.0 to 666.7 mg
#4: 0.0 to 500.0 mg
#5: 0.0 to 400.0 mg
Third in a 2 g blend means at most 667 mg. That's below 4 g whatever the real number is, so here the label settles it without disclosing anything.
The further down the list and the smaller the blend, the lower that ceiling gets: position n can never hold more than T / n.
How often this comes up
For the checker I read Amazon's pre-workout best-seller list, ranks 1 to 100, and checked the 52 that were multi-ingredient powders with a label I could confirm. 16 of the 52 (31%) put at least one ingredient in a blend without its amount. Across all 670 ingredient lines on those labels, 164 (24.5%) sat inside a blend with no amount.
So about a quarter of the lines on a best-selling pre-workout label are lines where these two inequalities are the only arithmetic available.
What the limits don't tell you
They're limits, not amounts. "825 mg to 6,603 mg" is the honest output. Showing the midpoint, or the maximum, as if it were the amount would be inventing a number. The checker only uses the ceiling: when even the maximum is below the studied dose, it says so, and everything else stays "hidden in a blend".
They assume the listed names make up the whole total. That's what (c)(3) says the number is: the weight of the dietary ingredients in the blend. If a label prints a total that doesn't match its list, the limits inherit the error.
They describe the label, not the powder. Every number here is what the manufacturer printed. Whether the tub matches is a lab question. When NOW Foods tested 12 brands of creatine gummies in 2024, 6 failed their label claim (Nutritional Outlook's report), and no amount of label arithmetic would have caught that.
Servings multiply everything. If the directions say two scoops, the blend total, the limits and every other ingredient double together. The checker computes per serving as printed and lets you change the number of scoops.
Nested blends need care. Some labels put a blend inside a blend. The inner blend's total is itself bounded by its position in the outer list, so the limits stack, and a parser that treats every indented line the same way gets them wrong.
The short version
Heaviest first plus a total gives you T / k as a floor for the first ingredient and T / n as a ceiling for the one in position n. Most of the time that still isn't enough to know the dose, and the right output is "can't tell". Sometimes, especially for small blends with long lists, the ceiling alone shows the dose can't reach what studies used. That case is worth computing, because the label has already answered the question without meaning to.
Written with AI assistance from my own notes and test results. I checked every fact and command before publishing.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.