Where every Atlas number comes from
This page lists every dataset and its vintage, the model constants and the reasoning behind them, and (just as load-bearing) what the numbers deliberately are not. The tables below render from the same code the tools run on, so nothing here can drift from what the app actually computes.
Sources
The Atlas fetches two datasets live and caches them on disk. The rest are curated tables in the repo, each with its edition stated. When a fetch fails, the Atlas serves the last good cache rather than an empty page.
| Dataset | Vintage | Refresh | What it feeds |
|---|---|---|---|
Unicode Consortium | cldr-json main branch (latest published CLDR) | Fetched, 7-day cache | Population, literacy, long-run GDP, and per-territory L1+L2 language shares: the base layer of every Atlas view. src/lib/cldr.ts loads it from the cldr-json main branch. The disk cache expires after 7 days, with stale-cache fallback on network error. |
World Bank Open Data | Most recent reported year per country (varies by country, year stored per record) | Fetched, 30-day cache | Indicator IT.NET.USER.ZS. Converts population into online population: the addressable-market number the reach calculator and planner quote. Both the share and the derived online population render in the country-page At-a-glance panel. src/lib/worldbank.ts loads it with mrnev=1 (most recent non-empty value). 30-day disk cache. |
World Bank Open Data | Most recent reported year per country (varies by country) | Fetched, 30-day cache | Indicator NY.GDP.PCAP.CD. Renders in the country-page At-a-glance panel beside CLDR's long-run GDP estimate (different vintages, labeled separately, never blended), in the compare table, and as the GDP-per-capita metric in the explorer, coverage map, and opportunity matrix. A CLDR-derived figure fills in where the World Bank has none. src/lib/worldbank.ts loads it. 30-day disk cache. |
World Bank Open Data | Most recent reported year per country (varies by country) | Fetched, 30-day cache | Indicator IT.CEL.SETS.P2. Renders in the country-page At-a-glance panel as subscriptions per 100 people. Values above 100 mean multi-SIM, not full coverage. src/lib/worldbank.ts loads it. 30-day disk cache. |
World Bank Global Findex | Most recent survey wave per country (the Findex runs every ~3 years, wave year stored per record) | Fetched, 30-day cache | Indicator FX.OWN.TOTL.ZS: adults with an account at a financial institution or a mobile-money provider. A payment-readiness signal: it bounds how many users can pay you in-market. It renders in the country-page At-a-glance panel and becomes a briefing risk when it is low. The API rejects mrnev for this sparse indicator, so src/lib/worldbank.ts pulls the wave range and keeps the newest non-empty value per country. 30-day disk cache. Never enters planner scoring. |
Ethnologue (SIL International) | 2023 edition, rounded published estimates | Static, updated by hand | De-duplicated global speaker totals for 33 major languages: the cross-border 'how many people speak this' figure that CLDR's per-territory shares cannot give. Curated in src/lib/language-reach-data.ts. Good for ordering, not citation. |
W3Techs | Content-language survey, 2024 | Static, updated by hand | Share of surveyed websites per content language: the supply side paired against Ethnologue's audience side. Curated in src/lib/language-reach-data.ts. |
EF Education First (Signum International AG) | 2025 edition (released November 2025, EF SET test data from 2024). 116 of 123 published countries, cross-checked against two sources | Static, updated by hand | English-proficiency score and band per country, curated in src/lib/english-proficiency.ts. Display-only context. It never enters planner scoring. The curation drops countries whose score differs between the official PDF and the Wikipedia table of the same edition. |
CSA Research | 2020 survey of 8,709 consumers across 29 countries | Static, updated by hand | The why-localize citation: 76% of respondents preferred products with information in their own language, and 40% said they will not buy in other languages. Quoted in the executive briefing's intro and listed in the memo's printed sources appendix. |
Curated (industry-typical defaults) | 2025 defaults, every figure editable in the UI | Static, updated by hand | The five-tier rate table in src/lib/budget-estimator.ts: raw MT through premium transcreation. A starting point for a budget conversation, not a vendor quote. The launch-cost model in src/lib/launch-costs.ts prices from the same table. |
Natural Earth | 1:110m admin-0 countries (177 features), bundled as a static file | Static, updated by hand | public/ne_110m_admin_0_countries.geojson: the polygons behind both world maps. ISO codes resolve via resolveIsoA2() in src/lib/geo.ts because Natural Earth marks France, Norway, and Kosovo as "-99" and Taiwan as "CN-TW". Geometry only. The Atlas reads no statistics from it. |
The EF EPI table ships 116 of the 123 countries in the 2025 edition. The table includes a country only when the official report PDF and an independent transcription of the same edition agree on its score. It omits the seven countries where the two disagreed rather than guess.
The launch score
The launch planner scores each candidate market as a weighted blend of three components: incremental reach, GDP, and engineering ease. The planner normalizes each component to 0–100. The weights come from the product profile you pick:
| Profile | Reach | GDP | Ease | Rationale |
|---|---|---|---|---|
| B2C | 55% | 15% | 30% | Weights people reached highest: consumer products monetize breadth. |
| B2B | 20% | 55% | 25% | Weights GDP highest: deal size tracks purchasing power more than headcount. |
| SaaS | 35% | 40% | 25% | Splits revenue and reach: self-serve products need both an audience and buyers in it. |
| Balanced | 34% | 33% | 33% | A flat prior for when the product profile is undecided. |
Reach (0–100)
Net-new speakers gained worldwide when you add the market's primary language, computed under the overlap model in the next section. A market you already half-cover earns only half credit. The raw speaker count maps to the score linearly: 200,000,000 net-new speakers scores 100, and anything above saturates. The 200M figure is a chosen scale anchor, nothing more. It makes the largest realistic language additions fill the scale, but no market fact says 200M rather than 250M. The "% of world" figure beside it divides by a fixed 8.0 billion world-population constant.
GDP (0–100)
The country's CLDR long-run nominal GDP, normalized so the largest economy in the dataset scores 100. A relative ordering rather than a revenue forecast. The same country list always contains the normalizing maximum, so scores are comparable within a run but not across datasets.
Engineering ease (0–100)
A checklist score for the candidate language: start at 70, then apply each adder that fires. The adder sizes are judgment, chosen to order markets by integration effort rather than measured from project data. The model clamps the result to 0–100.
| Check | Adder | Why it moves the score |
|---|---|---|
| Script already shipped | +12 | Fonts, fallback stacks, and rendering QA for the script already exist. |
| Left-to-right layout | +8 | No mirroring work. The counterpart below is the expensive case. |
| Right-to-left layout | −10 | Mirrored layout, bidirectional text handling (UAX #9), and icon review. |
| No custom webfont needed | +6 | OS-bundled fonts cover the glyphs. No font licensing or payload cost. |
| Custom webfont needed | −4 | Font selection, subsetting, and load-performance work. |
| 2 or fewer plural categories | +4 | Every count-bearing string needs at most two message variants. |
| 5 or more plural categories | −6 | Arabic-class plural systems multiply message variants and test cases. |
Plural-category counts come from CLDR plural rules as reported by Intl.PluralRules. The model attributes a candidate language only to countries where it holds at least a 30% L1+L2 share. Spanish therefore surfaces against Mexico and Spain rather than against the US.
The overlap model
CLDR reports each language's share of a territory as L1 plus L2 speakers. A bilingual person therefore counts once per language, and the shares of one country routinely sum past 100%. Every Atlas aggregate handles this the same way. Within each country, the model sums the selected-language shares and caps them at 100% of the population. No market ever contributes more people than live in it, and no coverage figure exceeds 100%. Incremental reach applies the same cap before and after: adding a minority language to a saturated bilingual market contributes only the uncovered remainder.
The cap bounds the error. It does not resolve it. Within the capped total, the model may still credit a trilingual speaker to whichever of their languages you selected first. The model knows share totals. It does not know which individuals overlap.
The cost model
Costs start from per-word rates times word counts. The rates are industry-typical 2025 defaults (a starting point for a budget conversation rather than a vendor quote). Three adjustments then move each estimate toward a real quote: a per-language-pair rate index, a translation-memory leverage discount, and a separate one-time engineering-setup line. The model prices one LQA round at 20% of the tier's per-word rate. It charges LQA on every word, regardless of leverage.
| Tier | $/word | Words/day | Appropriate for |
|---|---|---|---|
| Raw machine translation | $0.0001 | 250,000 | Internal tooling, search indexes, low-stakes content where 'gist' is enough. |
| MT + light post-edit | $0.04 | 5,000 | Support content, docs, FAQ: content read once and discarded. |
| MT + full post-edit | $0.08 | 3,500 | Marketing pages, onboarding flows, anything the user reads carefully. |
| Standard human translation | $0.15 | 2,500 | UI copy, legal text, brand-facing surfaces, contracts. |
| Premium / creative | $0.25 | 1,500 | Hero copy, taglines, ad campaigns: anywhere the literal translation reads as flat. |
Per-language-pair rate index
A word into Japanese, Icelandic, or a Nordic language costs more than the same word into Spanish. The cause is translator scarcity and source-market cost of living rather than script difficulty. The estimator multiplies each locale's per-word rate by an index (a mainstream pair = 1.0). Anything not listed prices at 1.0. These are planning indices rather than sourced rates.
Translation-memory leverage
Words already in the translation memory bill below the new-word rate. Repetitions and exact matches pay 25% of the rate. Fuzzy 75–99% matches pay 60%. New words pay full price. A first launch has no memory (0% leverage). A mature product reuses a large share of prior wording. The estimate applies leverage to translation and to the schedule, never to LQA.
Engineering setup
The work a per-word rate never captures. The estimator prices it once as its own line, so it does not quote an RTL or new-script launch like a Latin one. Planning figures, derived from the locale set:
| i18n framework | $6,000 | One-time: externalize strings, wire ICU, pseudoloc CI gate, TMS hookup. Skipped if already internationalized. |
| RTL enablement | $4,000 | One-time, charged once if any target locale is RTL: bidi isolation, logical-property CSS, icon mirroring. |
| Webfont (per script) | $1,200 | Per distinct non-Latin script that needs a bundled font: subsetting and glyph QA. |
| Per-locale integration | $500 | Per locale: file wiring and an in-context sign-off pass. |
The launch planner prices three launch depths by assigning each content bucket (UI strings, docs, support content) one of the tiers above. The cheapest depth still uses a light human review pass rather than raw machine output. Unreviewed MT on buttons and error messages is below the floor for anything called a launch.
| Depth | What ships | Buckets priced | LQA rounds |
|---|---|---|---|
| MT-first pilot | Ships UI strings only, machine-translated with a light human review pass. Docs and support stay in the source language. | ui · MT + light post-edit | 0 |
| UI at publication quality | Ships UI strings edited to publication quality with one LQA round. Docs and support stay in the source language. | ui · MT + full post-edit | 1 |
| Full launch | Ships UI at human-translation quality, docs at full post-edit, and support content at light post-edit, with one LQA round. | ui · Standard human translation; docs · MT + full post-edit; support · MT + light post-edit | 1 |
The figures above price a one-time launch. The model estimates ongoing upkeep separately. It assumes 40% of the source word corpus is retranslated each year (new features, edited strings, refreshed docs) and prices that through the same depth machinery. Upkeep therefore carries the same tier rates, LQA rounds, and PM overhead as the launch. The churn rate is a planning assumption rather than a measured figure. Replace it with your own when you have one.
The briefing's derived numbers
The executive briefing combines the models above into a few numbers of its own. Each has a fixed convention:
The budget ask
The decision block's budget ask auto-fills from the recommended market's launch cost (the first row of the cost appendix) plus that locale's one-time engineering setup. The appendix itemizes the setup. Setup credits what the portfolio already has: a second RTL language does not pay for RTL enablement again, and an already-shipped script does not re-buy its webfont. The model assumes a portfolio with more than one language has an i18n framework. The ask does not quote the all-markets total. The requested decision approves one launch, and the later markets in the proposed sequence are separate future decisions. The appendix prints the all-markets total on its own row, labeled as such. A typed budget-ask override always replaces the auto-filled figure. When the cost appendix is off or unpriced, the drafted ask carries no dollar amount.
The proposed sequence
The ranking table scores every candidate against the same fixed portfolio, so you must not sum its reach numbers. Two overlapping languages would double-count their shared markets. The briefing's Now / Next / Later tiles are the one surface that orders launches in time. The briefing therefore recomputes each tile's net-new count as if the earlier tiles had shipped, with the same exported overlap model. You can sum those three numbers, and the briefing says so next to them.
The payback scenario
The payback card combines four terms of different provenance, and labels each in its own footer ("headroom: estimate · ARPU: your data · capture: your assumption · upkeep: 40% annual string churn, an assumption"). Online headroom is an estimate: the anchor market's online population minus your reported MAU there. ARPU comes from your uploaded data: that market's revenue divided by its MAU. The capture percentage and the churn rate are assumptions, labeled as such. Users = headroom × capture. Monthly revenue = users × ARPU. Months to recover = launch cost ÷ monthly revenue net of upkeep, rounded up. The card renders only when all terms exist: a priced cost appendix plus an uploaded row for the anchor market that carries both revenue and an online-population estimate. If any term is missing, the briefing omits the card and never prints a zero. The card is a scenario rather than a forecast.
Custom weights
The launch planner's Custom profile exposes three sliders. On every change, they renormalize to integers that sum to 100. The briefing accepts the same override as a URL parameter: weights=R-G-E, three non-negative integers, normalized by their sum. For example, weights=55-15-30 weighs reach 55%, GDP 15%, and ease 30%. The briefing ignores a malformed value and applies the selected profile preset. While the override is active, the memo header shows "custom weights" and the methodology footer prints the exact split and its source parameter. Picking any profile button clears the override.
Snapshot deltas
When you compare two uploads of the same product, per-market penetration deltas divide both snapshots' MAU by the same online-population estimate (the current one). The percentage-point delta therefore isolates MAU movement and excludes drift between two vintages of the population estimate. The diff lists markets present in only one snapshot as added or removed. It never renders them as ±100% changes, and the totals cover only markets present in both. The diff reports what moved. It does not say what caused the movement.
What the numbers are not
- Double-counting is capped but not resolved. L1+L2 shares still overlap inside the 100% cap. The model can credit a multilingual person to the wrong one of your selected languages.
- Two GDP figures coexist. CLDR's long-run GDP estimate drives the launch score and the nominal-GDP metric. World Bank GDP per capita (current US$, most recent year) appears on country pages and drives the per-capita lenses. CLDR long-run GDP ÷ population fills in where the World Bank has no figure. The two are different vintages, so expect them to disagree. Any single number comes from one source, never an average of the two.
- No revenue estimates. The Atlas sizes audiences and costs. It never projects revenue. The only usage numbers it shows are the ones you bring yourself (Your data). Those stay display-only and never enter scoring.
- The ease model has a coverage edge. Its metadata table covers 79 languages. Outside it, the model defaults to the flattering shape (Latin script, LTR, 2 plural categories, no webfont). The planner therefore flags those rows as "No engineering metadata" instead of presenting defaults as findings.
- EF EPI is context, not an input. The index samples self-selected online test takers, skewed young and toward people already learning English. The Atlas shows it for discussion, and it never enters planner scoring.