Skip to content
DataForge

H-1B Salary Database: Where to Download the Real Data (and How to Use It)

Published 2026-08-04 · DataForge team

Search for any company name plus “H-1B salary” and you’ll find a dozen lookup sites — h1bdata.info, h1bgrader, levels.fyi’s H-1B section, and more. All of them are built on the same two free government sources. If you only need to check one employer’s median before a job negotiation, those sites are fine. If you want to analyze the data — build a salary benchmark, feed a compensation model, study visa-dependency by industry, or train anything on it — you need the underlying files. This guide covers where they live, what’s actually in them, the cleanup traps nobody warns you about, and working code to get to answers fast.

The two official sources behind every H-1B salary site

1. DOL LCA disclosure data. Before filing an H-1B petition, an employer must file a Labor Condition Application (LCA) with the US Department of Labor stating the job title, worksite and the wage it commits to pay. The DOL’s Office of Foreign Labor Certification publishes every LCA decision as quarterly Excel files on its performance data page. The same page hosts PERM (green-card labor certification) and H-2A/H-2B disclosure files. This is the source of every salary number you have ever seen on an H-1B lookup site.

2. USCIS H-1B Employer Data Hub. USCIS publishes petition-level approval and denial counts by employer and fiscal year — no salaries, but the authoritative answer to “how many H-1Bs did this company actually get?” (LCAs alone overstate this badly; more below). The Hub offers CSV export by year.

Both sources are public, free, and legal to use. So why does anyone pay for a cleaned version? Because the raw files are genuinely painful, in ways that quietly corrupt analyses.

What’s wrong with the raw files

The schema changes constantly. The FY2019 LCA file has different column names than FY2015, which differs from FY2024. EMPLOYER_NAME vs LCA_CASE_EMPLOYER_NAME vs Employer (Petitioner) Name; wage columns that switch between WAGE_RATE_OF_PAY_FROM and LCA_CASE_WAGE_RATE_FROM. If you want a time series back to FY2008, you are writing ~15 schema-mapping functions before your first query.

Wages come in five units. A wage of “35.50” is an hourly rate; “73,000” is annual; the files mix hourly, weekly, bi-weekly, monthly and annual in one column, with the unit in a second column. Every analysis that skips normalization produces medians that are visibly wrong (you’ll see “$74” engineers). You also need to handle wage ranges (WAGE_RATE_OF_PAY_FROM/_TO) and decide on a convention.

One filing ≠ one worker ≠ one job. An LCA can cover multiple workers (TOTAL_WORKER_POSITIONS), a company files LCAs it never uses, and certified LCAs vastly outnumber actual visa grants (there were ~780k certified LCA filings in FY2025 against an 85k annual H-1B cap — employers over-file for flexibility). If you count LCA rows as “H-1B hires”, your numbers are inflated several-fold. For actual grants you must join against the USCIS Hub — which uses different employer name spellings, so the join needs name normalization.

Employer names are a mess. “Google LLC”, “GOOGLE LLC”, “Google Inc.”, “GOOGLE, LLC” — all the same employer to a human, four groups to GROUP BY. Serious analysis needs normalized employer keys.

None of this is exotic — it’s a week of data engineering the first time, then quarterly maintenance forever. That’s precisely the work a cleaned dataset sells you back.

Download the raw files yourself

The current-year LCA file (Excel, quarterly cumulative) can be pulled directly:

import pandas as pd

# FY2025 Q4 cumulative LCA disclosure file (~780k rows, ~250MB in memory)
url = "https://www.dol.gov/sites/dolgov/files/ETA/oflc/pdfs/LCA_Disclosure_Data_FY2025_Q4.xlsx"
df = pd.read_excel(url)  # needs openpyxl; takes a few minutes

# Keep certified, full-time H-1B filings with annual wages
h1b = df[
    (df["CASE_STATUS"] == "Certified")
    & (df["VISA_CLASS"] == "H-1B")
    & (df["WAGE_UNIT_OF_PAY"] == "Year")
]

median_by_employer = (
    h1b.groupby(h1b["EMPLOYER_NAME"].str.upper().str.strip())["WAGE_RATE_OF_PAY_FROM"]
    .agg(["count", "median"])
    .query("count >= 25")
    .sort_values("median", ascending=False)
)
print(median_by_employer.head(20))

Note what this snippet doesn’t handle: non-annual wage units are dropped rather than converted (losing ~10% of rows, biased toward lower-wage jobs), employer names are only uppercased (Google LLC/Inc still split), and it covers one year of one program. That’s the honest gap between “I downloaded the file” and “I have a salary database.”

With a normalized table (like ours or your own after cleanup), the same question is one SQL statement over all years and programs:

SELECT employer_name_norm,
       COUNT(*)                                            AS filings,
       PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY wage_annual_usd) AS median_wage
FROM filings
WHERE program = 'lca'
  AND case_status_norm = 'certified'
  AND fiscal_year BETWEEN 2021 AND 2025
GROUP BY employer_name_norm
HAVING COUNT(*) >= 100
ORDER BY median_wage DESC;

What people actually build with this data

  • Compensation benchmarking. LCA wages are real committed salaries with job title, worksite city and SOC occupation code — better-grounded than self-reported survey data for tech roles. HR teams benchmark offers against the exact employer-title-city cell.
  • Negotiation prep. The classic use: look up the P25/median/P75 for your employer and role before the offer call. Our free H-1B Salary Explorer does this without any download.
  • Visa-dependency analysis. Journalists and researchers measure which employers and industries rely most on H-1B labor, and how policy changes shift filing behavior. This needs the longitudinal series (FY2008+) and the LCA↔USCIS join.
  • Lead generation. Immigration law firms and relocation services build prospect lists of employers that sponsor — with volume, growth and worksite geography as qualifiers.
  • Wage-level compliance studies. Combining filings with the DOL’s SOC×area prevailing-wage benchmarks shows how often employers pay at Level I vs Level IV — a recurring policy topic.

Free files vs. a cleaned dataset: honest comparison

Raw DOL/USCIS files DataForge cleaned dataset
Cost Free From $99
Coverage Everything, FY2008+ (as ~106 separate files) Same, one schema: 14.5M rows FY2008–FY2026
Schema Changes across years/programs One normalized 92-field schema across all years
Wages 5 units, ranges, no normalization wage_annual_usd computed on every row
Employers Free-text names Normalized names + stable employer_id
LCA vs reality LCA counts only USCIS Employer Data Hub joined (826k employer-year approval/denial rows) + per-employer visa-dependency profiles
Prevailing wage Separate OFLC library 95,888 SOC×state wage benchmark rows included
Updates You re-run your pipeline quarterly Subscription tiers re-deliver on update

If you’re doing a one-off look at one year, download the free file — genuinely. The paid dataset earns its price when you need multiple years, cross-program consistency, employer-level joins, or you’d rather not own a quarterly maintenance chore. Every number above comes from the dataset’s manifest, and the free 500-row sample lets you check field quality before paying.

A note on prevailing wage levels

Every LCA also states the DOL prevailing wage for the occupation and area, and its level (I–IV). This unlocks a second analysis axis most people miss: the gap between what an employer commits to pay and the local occupational baseline. A company consistently filing at Level I (entry) for “Senior Software Engineer” titles tells you something about either its titles or its pay philosophy; a company paying 40% above prevailing wage across the board is signaling in the other direction. The OFLC wage library publishes the SOC×area benchmarks separately (we include 95,888 of these rows pre-joined), so you can compute wage_annual_usd / pw_annual_usd ratios per employer, occupation and metro without a second data hunt.

The PERM files deserve a mention too: they are the green-card equivalent of LCAs, with education, experience requirements and (in older years) actual offered wages. Because PERM certification requires proving no qualified US worker applied, PERM data is the best public window into which specific roles companies fight hardest to retain. The same schema-drift and name-normalization caveats apply — doubly so, since PERM column layouts changed more often than LCA ones.

FAQ

Is this data legal to use commercially? Yes. LCA disclosure data and the USCIS Hub are US government works published explicitly for public use. (Our license covers the cleaning and packaging; the underlying facts are public.)

Are individual workers identifiable? The files contain employer names, not employee names. Wages are per-filing. We ship the data as published by DOL/USCIS.

Why do numbers differ from levels.fyi or Glassdoor? LCA wages are base-salary commitments — no equity or bonus. Expect LCA medians to sit below total-comp figures for big-tech employers, and to be more reliable for body-shop consultancies where survey data is thin.

What’s the difference between certified and approved? DOL certifies the LCA (wage commitment); USCIS approves the petition (actual visa). Certified ≫ approved. Any analysis of “who got H-1Bs” needs the USCIS side.

How fresh is the data? DOL publishes quarterly; USCIS updates the Hub annually. Our dataset snapshot includes filings received through 2026-03-31 (FY2026 Q2).

Want to explore before downloading anything? The H-1B Salary Explorer is free, covers 550,885 certified FY2025 filings, and needs no signup.