Salary Data Methodology
SalaryScope derives salary figures from a multi-factor mathematical model — not from self-reported surveys. Every number is reproducible from public government data and the formulas below.
This page explains each step in full so you can verify any figure yourself.
Why most salary sites get international figures wrong
Most competing sites calculate international city salaries as:US salary × cost-of-living indexThis is mathematically wrong. A German software engineer does not earn "US salary × Germany cost-of-living." They earn a salary set by German labor market conditions.
SalaryScope uses each country's actual average wage from OECD/ILO data, then applies how much a particular occupation earns above the national average in that country's labor market. This produces results that match what employers actually pay.
The Master Formula
For US cities, Steps 2–5 are collapsed: the BLS national median is used directly, then multiplied by the BLS metro-area premium for that city (also from BLS OES).
Country Average Wages — Three Tiers
Every country has a baseline annual average wage in PPP-adjusted USD. We use the most authoritative source available for each country, in priority order:
| Tier | Source | Countries | Badge |
|---|---|---|---|
| Tier 1 | OECD Average Wages (AV_AN_WAGE) PPP-adjusted USD, employer-reported, 2023 actuals | 38 OECD members (US, Germany, Japan, UK…) | OECD verified |
| Tier 2 | ILO ILOSTAT Mean wages by country, PPP-converted, 2023/2024 | Singapore, India, Brazil, UAE, China… | ILO estimate |
| Tier 3 | World Bank GNI per capita (PPP) GNI/cap × labor income share (0.40–0.60 by tier), 2024 | Nigeria, Bangladesh, Ethiopia, Ghana… | GDP estimate |
The badge shown on each salary page tells you which tier was used. Data is refreshed every 30 days by calling the OECD SDMX-JSON API and the World Bank REST API automatically.
Occupation Premium Ratio (OPR)
The OPR answers: "How much more does this job pay than the average of all jobs?"It is derived entirely from U.S. BLS Occupational Employment and Wage Statistics (OEWS) — the most rigorous employer-survey wage dataset published by any government.
Every job in our database is mapped to a BLS SOC code. Each SOC code has its own OPR. For emerging roles without their own SOC code (AI engineer, blockchain developer), we use the category-average OPR from closely related occupations.
Skill Elasticity
In lower-income countries, skilled workers earn a disproportionately larger premium above the national average. A software engineer in India earns roughly 5–8× the national average — far above the 1.62× ratio in the US — because of international demand and talent scarcity. This effect is captured by the Skill Elasticity multiplier:
Income Tier Compression
In Western Europe and Japan, the gap between skilled and unskilled workers is compressed by strong unions, higher minimum wages, and social wage norms. A software engineer in Germany earns roughly 1.7× the national average — not the 1.62× US OPR. This compression is applied per income tier:
| Income Tier | GDP/cap (PPP) | Examples | OPR Multiplier |
|---|---|---|---|
| High income | > $35k | Germany, Japan, UK, France | × 0.82 (compressed) |
| Upper middle | $13–35k | Poland, Brazil, China, Mexico | × 0.92 |
| Middle | $5–13k | Indonesia, South Africa, Colombia | × 1.00 (neutral) |
| Lower middle | $2–5k | India, Vietnam, Philippines, Nigeria | × 1.18 (amplified) |
| Low income | < $2k | Ethiopia, Tanzania, Rwanda | × 1.42 (amplified) |
Log-Normal Percentile Bands
Salary distributions within an occupation follow a log-normal distribution — validated in research by BLS, NBER, and the Federal Reserve. Given a median salary M and a spread parameter σ (calibrated per job category), percentiles are computed as:
City Metro Premium
Each city has a metro premium — how much more employers pay compared to the national average in that country. For US cities, this uses BLS metro-area OEWS data directly. For international cities, premiums are derived from labor economics research on agglomeration effects.
Deterministic Jitter
A ±3% variation is applied per job×city pair using an FNV-1a hash of the slugs. This ensures two different jobs in the same city show slightly different numbers (as in reality), but the same job×city pair always produces the same value across page loads, deployments, and servers. The jitter does not change the median — it reflects natural inter-firm pay variation within a market.
Auto-Update Schedule
| Data | Source | Frequency |
|---|---|---|
| US job salaries (all 207) | BLS OEWS API | Every 24 hours |
| City cost-of-living indexes | World Bank PPP | Every 24 hours |
| H-1B company wages | BLS OEWS + USCIS | Every 7 days |
| International country wages | OECD API + World Bank GNI | Every 30 days |
All updates run on the production server's internal scheduler. No external cron services or GitHub Actions are used.
Questions about methodology? data@salaryscope.co · See also: About & Data Sources