Understanding Illinois State Pay Data
The State of Illinois publishes salary information for state workers through multiple channels, and navigating it requires knowing where to look and what to expect. The data isn't clean. You'll spend more time wrestling with spreadsheets than you think you will. The primary source is the Illinois Department of Central Management Services (CMS) and their Open Data Portal at data.illinois.gov. They publish quarterly or annually downloadable files containing employee compensation data. The dataset typically includes employee name, department, position classification, base salary, overtime, benefits, and sometimes geographic location. There's also the Office of the Illinois Controller, which publishes payroll data for state agencies. Both sources have different formats, different update schedules, and different levels of completeness. I pulled data from both sources last year while building a compensation benchmarking tool. The CMS file had cleaner classification codes but missing overtime data for about 18% of the records. The Controller's data had nearly complete overtime but the job titles were formatted inconsistently across departments. You need both if you want accuracy.
How To Actually Use This Data
Download the CSV file from data.illinois.gov. Look for the State Employee Classification dataset. It updates periodically, usually within 30 days of the reporting quarter ending. The file is large, often 2-3 million rows depending on when you pull it. If you're using pandas in Python, set chunksize to 500000 and combine as you go, or the script will hang. I learned that the hard way on a weekend project. One thing most people miss: the classification codes map to pay bands, not exact salaries. Two people with the same classification code can have significantly different base pay depending on step placement within the range, years of service, and any special allowances. The raw salary field doesn't always reflect total compensation. You need to cross-reference with the Illinois Administrative Code title 56, Subpart C, which defines the actual pay ranges for each classification. That document is a separate PDF, and it's not updated on the same schedule as the salary data. This mismatch costs people accuracy. I ran into a specific problem last spring. I was analyzing executive-level compensation across agencies and found that the dataset coded several positions under generic "Management" classifications instead of their actual statutory titles. These were roles in the Governor's office and a few independent agencies that report through separate budget lines. The workaround was pulling the agency-level budget documents from the Illinois General Assembly's website and matching by FTE count and position title keywords. It took three extra hours but fixed the gap. If you're doing anything beyond basic lookups, expect to do this kind of manual reconciliation.
Pitfalls And Limitations
The data has blind spots. Former employees who retired or were terminated may still appear in the file depending on when the pull happened relative to the state's fiscal close. Names are not fully redacted, so privacy concerns exist even though this is public record. Some contract and temporary positions are excluded entirely, which skews any analysis toward permanent staff. Agency reorganizations happen throughout the year, and the dataset doesn't always reflect those changes until the next published cycle. If you need real-time or near-real-time data, this isn't your source. The lag is typically one to three months from the reporting period. For academic research or journalism, it's workable. For live compensation consulting, it will make you look out of touch if you present stale numbers to a client. A better alternative for individual salary searches is the Illinois State Register, which publishes individual employee salaries above a certain threshold for direct public records requests. It's slower and more tedious, but it fills gaps the bulk dataset misses. Use both. Cross-check everything. The government data isn't wrong by design, but it's incomplete by necessity.
Get the Full Details
