Where Public Salary Data Actually Lives in North Carolina
The largest dataset for public sector pay in the state sits behind the NC Salary Search portal run by the State Port Commission and linked through the Executive Compensation Database. It covers about 85,000 state employees, with annual updates that arrive somewhere between January and March for the prior fiscal year. The data is downloadable as a CSV, but the interface itself is not friendly. You will spend time wrestling with date filters and export limits if you try to use the front end for anything beyond a single search. Most people land on this topic because they want a number fast. A better approach is to understand what the numbers actually measure before you pull them. State salary data reports base pay, step increases, and sometimes stipends. It does not reliably include bonuses, longevity pay, or the value of benefits. When you see a figure like $72,500 for a state position, that is usually total cash compensation for the fiscal year, not an annualized rate. A part-time employee reported at $36,000 may actually earn roughly $72,000 annualized depending on FTE. Here is the practical workflow I use now. I start with the NC Salary Search query page and pull the full department-level export rather than doing single-name searches. Single-name queries are fine for confirming one person's record, but they return inconsistent column ordering and often omit legacy department codes. The full export gives you every row in a consistent schema: employee ID, department, job classification, base salary, step, hire date, and FTE. Once you have the file, I open it in a spreadsheet tool and do the filtering myself. I use a pivot table to summarize by job title and FTE, which collapses the duplicate rows that appear when someone changes position mid-year.
If you are looking at local government salaries, the path is different. The NC Local Government Commission does not publish a single searchable database. Counties maintain their own portals with wildly varying formats. Some counties provide CSV downloads. Many provide only PDF salary schedules that you have to parse manually. I have spent too many afternoons converting scanned PDF pay grids into workable data, and I still recommend against that route unless you need a very specific county that does not offer electronic exports.
Common Pitfalls That Wreck the Analysis
The biggest error beginners make is treating every salary figure as a straight annual amount. That assumption breaks down fast. The data includes summer-only positions, temporary appointments, and shared-FTE roles. If you average raw base salaries without adjusting for FTE, your results will be skewed upward by a small number of overloaded supervisors and downward by the large pool of hourly staff. Always multiply by the inverse of FTE before aggregating. Another trap is not accounting for step progression. State corrections and education employees move up steps based on years of service. Two people in the same classification can have very different base pay because one has ten years of tenure and the other has two. If you want to compare compensation by role, group by classification code and step separately. Otherwise the distribution will look wider than it really is. There is also the issue of classification drift. The state renumbers and retitles job classifications periodically. A "Management Analyst II" from fiscal year 2019 may map to a different code than the same title in fiscal year 2024. If you are tracking trends across multiple years, you need a mapping table. I built one by matching titles to department handbooks and verifying the mappings against the official reclassification memos published on the Office of State Human Services website. It took about six hours the first time. After that, the mapping script handles the conversion automatically.
Get the Full Details

A Specific Edge Case I Faced
Last fall I was trying to reconstruct compensation for a cluster of regional health department positions across several counties. The state portal returned no records for those roles because local health departments are funded jointly and sometimes appear under multiple agency codes. I hit a wall where the classification existed in the pay schedule but the employee IDs were missing from the export. The workaround was to pull the county-level financial reports from the NC Department of Health and Human Services annual budget documents. Those PDFs list position counts and salary ranges by funding source. I cross-referenced the position titles with the state classification list and used the budget ranges to estimate the missing individual salaries. It was not precise. The estimate carried a margin of roughly ±8 percent, but it was better than nothing for a market comparison project. Be blunt with yourself about the gaps. The public salary datasets do not include performance ratings, promotion timelines, or turnover rates. They also do not capture non-cash compensation like tuition reimbursement, deferred compensation contributions, or the actuarial value of pensions. Two jobs with identical base pay can have very different total reward packages depending on the employer's retirement formula and benefit design. Private sector data in North Carolina is even harder to find. Companies are not required to disclose salaries publicly. The closest thing to a reliable source is the Bureau of Labor Statistics Occupational Employment and Wage Statistics program, which publishes metropolitan and state-level estimates for hundreds of occupations. Those numbers are medians with confidence intervals, not individual records. They are useful for broad benchmarks but useless for negotiating a specific offer.
If you need private-sector salary intelligence, the practical options are Glassdoor, Payscale, and LinkedIn Salary. None of them are authoritative. Glassdoor reports tend to overrepresent tech and professional services roles. Payscale's coverage of North Carolina is decent for healthcare and manufacturing but thin for government-adjacent positions. LinkedIn Salary is sparse and self-reported. I use all three as rough triangulation points, not as definitive answers.
Advanced Techniques That Actually Help
Once you are comfortable with the basics, there are a few moves that save significant time. First, learn to use the classification code filters instead of free-text title searches. The search box is sloppy. It matches partial strings and returns duplicates across similar titles. The classification code is stable and maps directly to the pay grade. Querying by code cuts false positives from roughly 30 percent down to under 5 percent. Second, build a simple script or macro that normalizes FTE and calculates annualized pay on import. I wrote a short Python script using pandas that reads the raw export, drops rows with missing FTE values, annualizes partial-year salaries, and outputs a cleaned table grouped by classification. It takes about four minutes to process a full year's export and produces a dataset that is immediately usable for analysis. Without that step, I would spend hours cleaning the file manually each time. Third, track the audit trail. The salary files are updated annually, and the state occasionally corrects retroactive entries. If you are doing longitudinal work, archive every yearly export with the exact download date. The differences between versions can matter when someone received a back-pay adjustment that appears in one year's file but not the prior one.
When to Walk Away From the Public Data
Public salary data is adequate for benchmarking state and local government roles. It is inadequate for most private-sector negotiations, for startup equity discussions, and for roles where compensation is heavily variable. If you are trying to assess total comp for a sales position, a commission structure, or a role with significant stock grants, the public data is essentially irrelevant. In those cases, stick to industry compensation surveys from the NC Society of Human Resource Management or the Robert Half salary guide, which publish region-specific bands for professional roles. The state dataset also breaks down for elected offices, appointed boards, and quasi-public entities. Those positions often fall outside the standard classification system and may appear under generic administrative codes that tell you nothing about the actual role. I learned that the hard way when I spent an afternoon trying to parse compensation for members of various state advisory boards and ended up with a pile of rows labeled simply "Director" with no useful subdivision. Bottom line: the data is there if you know how to pull it and clean it. The portals are functional but not polished. The numbers require adjustments before they mean anything. And there are entire segments of the North Carolina labor market where this approach simply does not work. Knowing the boundary between those two zones is what separates a usable analysis from a misleading one.