CalEye.
Blog · science June 28, 2026 9 min read

Why Per-100g Is the Only Stable Macro Reference

Spreadsheet of nutritional values representing per-100g macro reference data

Per-100g is the only stable nutritional reference unit because it is serving-size-independent, label-regulation-independent, and database-harmonization-compatible — properties that per-serving figures categorically lack, which is why every serious food composition database (USDA FoodData Central SR-Legacy release 28, the UK PHE Nutrient Databank, EFSA’s FoodEx2, and the Indian IFCT 2017) stores and reports values per 100 g of edible portion as its canonical unit. A per-serving figure is only meaningful if you know exactly what “one serving” means under the specific regulatory framework that generated the label, and those frameworks differ enough across jurisdictions to make direct cross-border food comparison unreliable: the FDA defines a serving of peanut butter as 32 g (2 tablespoons) while Australian standards use 20 g, producing a per-serving calorie figure that differs by 60% for the same product.

Serving Size Definitions Are Regulatory Artifacts

The US FDA’s Reference Amounts Customarily Consumed (RACCs) define serving sizes for nutrition labeling based on consumption survey data from the 1970s–1980s, updated most recently in 2016 for select categories under the Nutrition Facts Label modernization rule. They do not represent what a typical modern person eats; they represent what people reported eating four decades ago, adjusted through a regulatory process that is as much political as scientific.

A 591 mL bottle of soda was declared “2.5 servings” under pre-2020 FDA rules, producing a per-serving calorie figure of approximately 100 kcal when the bottle contained 250 kcal. When the FDA reclassified single-serve bottles as single servings in 2020, the per-serving calorie figure doubled overnight — a labeling change that altered the nutrition panel without changing a single ingredient or molecule in the product. Per-100g of that soda remained constant throughout: approximately 42 kcal/100 mL, unchanged by any regulatory decision.1

The EU uses a mandatory 100 g reference column on nutrition labels in addition to a per-serving column, explicitly because the European Food Safety Authority (EFSA) recognized that per-serving figures are not comparable across products or jurisdictions. The 100 g column is the one that allows you to compare the sugar content of two different cereals without needing to know whether both manufacturers define “one serving” the same way. Most consumers focus on the per-serving column; nutritionists and food scientists use the per-100g column.

In India, the Food Safety and Standards Authority (FSSAI) specifies serving sizes for packaged foods but has historically used reference amounts that differ from both FDA and EU standards. A “biscuit serving” under FSSAI rules is 30 g; the same product sold in the UK might list a 25 g serving. The per-100g figures are identical because the food is the same food; the per-serving figures diverge because the serving definitions differ. Any app aggregating nutrition data from Indian and international product databases must reconcile these differences at the per-100g level or introduce systematic labeling errors.2

Cross-Database Harmonization Requires Per-100g

Modern nutrition tracking apps draw data from multiple heterogeneous sources: USDA SR-Legacy for commodity foods, Open Food Facts for packaged product data (crowdsourced from 200+ countries), regional government databases for local cuisines, and manufacturer-submitted data for specific branded products. Each source uses different units, different language standards, and different conventions for missing data.

USDA FoodData Central stores all nutrient values in per-100g as the canonical unit, with household measure conversions provided as secondary references (“1 cup,” “1 tablespoon,” “1 medium apple”). This is the right architecture: the per-100g value is stable regardless of what household measure is displayed to the user.3

Open Food Facts, the largest open-source packaged food database, requires contributing apps to submit per-100g or per-100mL values and stores these as the primary data. Per-serving values are stored separately as optional supplementary data, with the serving size in grams recorded alongside. When the serving size is missing — which is true for approximately 15–20% of Open Food Facts records — per-serving calorie data becomes unusable, but the per-100g values remain usable for any database application that correctly implements the per-100g retrieval.

A merger of USDA values with Australian NUTTAB values (the national nutrient database for Australia) requires no per-100g conversion because both databases use the same unit. A merger of FDA-labeled per-serving data with NUTTAB per-100g data requires knowing the serving size in grams for every FDA record — a field that is frequently missing, inconsistently entered, or defined by a now-obsolete RACC — before a conversion to per-100g can be applied. This is the fundamental reason why large-scale food database mergers produce systematic nutrient errors: serving-size data is inconsistent; per-100g data is not.

The practical consequence for app users: when a calorie tracking app shows different calorie values for the “same” food from two different database sources, the most common explanation is a serving-size reconciliation error — not a discrepancy in the underlying food composition data. If both sources report the per-100g value, the discrepancy disappears.

Density and Weight Conversion: Where Per-100ml Fails for Liquids

For solid foods, per-100g is unambiguous — 100 g is 100 g regardless of the food’s volume, density, or preparation state. For liquids, some databases store values per 100 mL rather than per 100 g, which introduces a density conversion requirement whenever solid and liquid foods are compared on a calorie-per-gram basis.

The density of common beverages:

  • Water: 1.000 g/mL (by definition)
  • Whole milk: 1.032 g/mL
  • Orange juice: 1.045 g/mL
  • Regular cola: 1.042 g/mL
  • Olive oil: 0.913 g/mL
  • Ethanol (pure): 0.789 g/mL

For most dairy and juice products, the density is close enough to 1.0 that the error from assuming density = 1.0 is under 5% — within typical measurement uncertainty. For high-sugar syrups (density approximately 1.3 g/mL), the error from the 1.0 assumption reaches 23%. For oils (density approximately 0.91–0.93), the error is approximately 7–9% in the direction of underestimating calories. For alcoholic spirits (approximately 40% alcohol by volume), the density is approximately 0.95 g/mL, producing a modest error, but alcohol’s caloric contribution of 7 kcal/g versus water’s 0 kcal/g makes the nutrient calculation more complex than density alone suggests.4

Well-engineered nutrition apps store all liquids in per-100g (not per-100mL), converting from manufacturer-submitted per-100mL data using the food’s known or measured density at ingest time. This prevents the downstream comparison errors that arise when a database query returns per-100mL for a juice and per-100g for a fruit and presents both as if they are on the same scale. USDA FoodData Central stores liquids in per-100g using measured density data — which is why it is the preferred reference database for apps that need internally consistent nutrient comparisons.

Recipe Scaling and Ingredient Aggregation

When a user logs a home-cooked recipe, the calorie and macro calculation follows a two-step process: aggregate total nutrient contributions from all ingredients, then normalize to the portion size consumed. This is algebraically equivalent to summing (ingredient mass in grams × ingredient’s per-100g nutrient value ÷ 100) across all ingredients, then multiplying by (portion grams ÷ total recipe weight in grams).

The per-100g representation is the natural unit for this computation. It eliminates a normalization step that would otherwise require knowing the serving size definition for every ingredient in the recipe — information that is not available for bulk ingredients (a 1 kg bag of flour has no per-serving declaration) and that varies between brands for packaged ingredients.

Consider a curry recipe using: 200 g chicken breast, 150 g canned tomatoes, 100 g onion, 30 g coconut cream, 15 g oil, 5 g spices. The calorie calculation requires the per-100g value for each ingredient, multiplied by the weight used, summed across all ingredients, and divided by the total recipe yield weight (serving weight). If any ingredient stored its nutrition data in per-serving rather than per-100g, you would need the serving size in grams for that ingredient to convert — an additional lookup that introduces a point of failure.

The per-100g architecture also handles recipe editing correctly: if you change the chicken breast quantity from 200 g to 250 g, the app needs only to recalculate (250 × chicken_per_100g ÷ 100) — one multiplication, no additional data lookup. Serving-size-based architectures require fetching the serving size for chicken breast, converting the 50 g increment to a fraction of a serving, and applying the per-serving value — three steps instead of one, with additional failure points. Recipe scaling and calorie scaling works correctly only when per-100g is the canonical unit throughout.3

Why Nutrient Density Rankings Work Per-100g

Nutrient density comparisons — “which food gives me the most protein per calorie?” or “which vegetable has the most potassium per serving?” — only produce consistent rankings when foods are compared on the same mass or energy basis.

Protein-per-100-kcal is the standard ranking metric in sports nutrition research because it normalizes for caloric density, allowing direct comparison between high-calorie and low-calorie sources. This metric derives cleanly from per-100g data: protein-per-100-kcal = (protein per 100g) ÷ (energy per 100g in kcal) × 100. Chicken breast: 31 g protein ÷ 165 kcal × 100 = 18.8 g protein per 100 kcal. Lentils: 9 g ÷ 116 kcal × 100 = 7.8 g protein per 100 kcal. The comparison is unambiguous. For anyone tracking protein targets for weight loss, this ranking approach is far more useful than per-serving comparisons.3

Per-serving protein comparisons using FDA RACC serving sizes produce a different ranking because serving sizes are not calibrated to caloric equivalence. The FDA RACC for cooked chicken is 85 g (28 g protein), while cooked lentils is 130 g (12 g protein). The ranking is consistent — chicken wins — but the difference (28 g vs 12 g) is partly a function of different portion sizes, not only food composition. A dieter asking “what should I eat to hit my protein target most efficiently?” gets a cleaner answer from per-100g or per-100-kcal rankings than from per-serving comparisons.

For glycaemic load comparisons — another CalEye use case — the per-100g basis is essential. GL = (GI × available carbohydrate per 100g) × (actual serving weight in grams) ÷ 100. This formula requires knowing the available carbohydrate per 100g. A per-serving carbohydrate figure would require an additional division by the serving size to recover the per-100g value before the GL calculation can be performed. The glycemic load explained in more depth shows how this matters most for high-starch foods.

Practical Implications for App Design

A well-engineered nutrition app stores all nutrient values per 100 g in its canonical database layer and performs serving-size multiplication only at the display and calculation layer. This separation ensures:

  • User corrections (“I ate 150 g, not 85 g”) require only a multiplier change on the front end, not a database lookup or schema change
  • Per-100g figures can be shown alongside per-serving figures in the UI without risk of the two representations drifting out of sync
  • Database merges from multiple sources are comparison-safe at the storage layer without per-source serving-size reconciliation
  • Recipe calculations are algebraically clean with no intermediate normalization steps

USDA FoodData Central’s API returns per-100g values in JSON for exactly this reason — it is the only representation that downstream apps can reliably consume without source-specific normalization.3 CalEye’s canonical database follows the same convention: every food’s macronutrient and energy values are stored per 100 g of edible portion (raw or cooked as labeled), with cooking state, preparation method, and water content recorded as metadata. Display-layer conversions to per-serving, per-meal, or per-recipe are computed on demand from the per-100g values, ensuring the underlying data is always internally consistent regardless of which display format the user selects.

References

  1. U.S. Food and Drug Administration. “Changes to the Nutrition Facts Label.” FDA.gov, 2020. https://www.fda.gov/food/food-labeling-nutrition/changes-nutrition-facts-label

  2. Food Safety and Standards Authority of India. Food Safety and Standards (Labelling and Display) Regulations, 2020. FSSAI, New Delhi.

  3. U.S. Department of Agriculture, Agricultural Research Service. FoodData Central. https://fdc.nal.usda.gov/ Accessed 2024.

  4. Atwater WO, Bryant AP. The Availability and Fuel Value of Food Materials. US Office of Experimental Stations, 1900. (Historical basis for 4-4-9 Atwater factors still used in nutrition labeling worldwide.)

  5. European Food Safety Authority. FoodEx2: A Food Classification and Description System. EFSA Technical Report, 2011. doi:10.2903/j.efsa.2011.2970

Frequently asked questions

Why do the same foods show different calorie values across nutrition apps?
The most common cause is a serving-size reconciliation error, not a difference in underlying food composition data. When apps merge databases that define servings differently — FDA uses 32 g for peanut butter, Australian standards use 20 g — per-serving figures diverge even though per-100g values for the same food are identical.
How do serving size definitions differ between the US, EU, and India?
The FDA defines serving sizes based on 1970s–80s consumption surveys updated in 2016; the EU mandates a per-100g column alongside per-serving precisely because cross-border serving sizes are incompatible; and India's FSSAI uses its own reference amounts that differ from both — making direct per-serving comparisons across jurisdictions unreliable.
What error does assuming liquid density equals water introduce when tracking beverages?
For most juices and dairy (density close to 1.0 g/mL) the error is under 5%. For high-sugar syrups (density about 1.3 g/mL) the error reaches 23%. Oils at roughly 0.92 g/mL introduce a 7–9% underestimation of calories. Well-engineered apps store liquids per 100 g using measured density data to avoid this.
Why is per-100g the right unit for recipe scaling and home cooking calculations?
Recipe scaling requires summing (ingredient mass × per-100g nutrient value ÷ 100) across all components and dividing by portion weight — a clean single multiplication per ingredient. Serving-size architectures require an additional lookup to convert ingredient amounts to fractions of a serving, adding multiple failure points for each ingredient.
How do nutrient density rankings like protein-per-calorie depend on per-100g data?
The calculation protein-per-100-kcal = (protein per 100g) ÷ (energy per 100g) × 100 derives directly from per-100g values and produces unambiguous food comparisons. Per-serving rankings skew results because serving sizes are not calibrated to caloric equivalence, mixing portion-size effects with genuine food composition differences.