Sample dataset · CC0
An HR roster where the salaries make sense.
Eight columns of employee record covering seven years of hiring. Salary is not a flat random range: it follows the seniority prefix in the title, so a senior engineer out-earns a junior one and headcount cost by band is a real number.
8 columns · 100 or 1,000 rows as a file · up to 1,000,000 rows generated here · CSV, JSON, JSONL, Excel, Parquet
Take a file
The 1,000-row file is a mid-size company. The 100-row file is a department, and it is the better one for a screenshot because you can see the whole thing.
| Format | Small | Standard |
|---|---|---|
| CSV | 100 rows (8.0 KB) | 1,000 rows (78.7 KB) |
| JSON | 100 rows (18.2 KB) | 1,000 rows (182.2 KB) |
| JSONL | 100 rows (17.9 KB) | 1,000 rows (179.3 KB) |
| Excel | 100 rows (21.2 KB) | 1,000 rows (132.9 KB) |
| Parquet | 100 rows (4.8 KB) | 1,000 rows (24.2 KB) |
Bigger rosters, built here
Bigger sizes keep the same seven-year hiring window and the same five salary bands, so the distribution stays the same while the density goes up. A million-row roster is not a realistic company, but it is a realistic stress test.
The first eight rows
The first eight rows of the 1,000-row file. is_remote and location never contradict each other.
| employee_id | full_name | department | title | hire_date | salary | location | is_remote |
|---|---|---|---|---|---|---|---|
| 2001 | Ahmed Peterson | Support | Senior QA Engineer | 2019-01-02 | 167821 | Singapore | false |
| 2002 | Anna Diaz | Engineering | Senior Support Engineer | 2019-01-05 | 165901 | London | false |
| 2003 | Ryan Robinson | Finance | Financial Analyst | 2019-01-07 | 129740 | Bengaluru | false |
| 2004 | George Richardson | Legal | Senior UX Designer | 2019-01-10 | 179143 | Seattle | false |
| 2005 | Lucas Robinson | Sales | Software Engineer | 2019-01-13 | 98525 | Singapore | false |
| 2006 | Richard Edwards | Engineering | Staff Sales Representative | 2019-01-16 | 230043 | Berlin | false |
| 2007 | Fatima Ortiz | Engineering | Senior Research Scientist | 2019-01-18 | 160460 | Singapore | false |
| 2008 | Jessica Flores | Operations | Staff Data Analyst | 2019-01-21 | 230739 | Berlin | false |
Eight columns, and what each one holds
| Column | Type | What it holds | Example |
|---|---|---|---|
| employee_id | integer | Primary key, 2001 upward. | 2001 |
| full_name | text | Given name and family name in one field, so splitting columns has something to bite on. | Ahmed Peterson |
| department | text | One of nine departments. | Support |
| title | text | Job title. The seniority prefix matches the salary band. | Senior QA Engineer |
| hire_date | date | Start date, ascending through the file. | 2019-01-02 |
| salary | integer | Annual salary in USD, banded by seniority and department. | 167821 |
| location | text | Office city, or Remote. | Singapore |
| is_remote | boolean | true when location is Remote. The two columns never disagree. | false |
What it models
A headcount export: who works here, where, doing what, since when, and for how much. It is the file that gets attached to a planning spreadsheet, and it has the shape of a real one, including a full_name column that is one field rather than two, because that is how these exports usually arrive and splitting it is usually the first thing anybody does.
Hire dates run from January 2019 to mid-2026 and ascend through the file, so the roster reads like a hiring history rather than a snapshot. Tenure is therefore computable, and a chart of hires per quarter has a real curve.
Salary is banded, not random
There are five seniority bands, each with its own salary range: junior from 62,000 to 92,000, unprefixed from 88,000 to 138,000, senior from 130,000 to 186,000, staff from 172,000 to 235,000, and head of from 195,000 to 290,000. The bands overlap at the edges the way real pay bands do, so the boundaries are not clean cuts.
The prefix on the title is the band, which means the relationship is visible on the row and checkable without a lookup. Group by the first word of the title and the mean salary steps up monotonically. Most generated HR data draws salary from one uniform range and produces a box plot that says nothing; this one produces a box plot you could actually use to explain what a box plot is.
The draw across bands is a bell rather than a flat line, so the middle bands are the fat part and there are relatively few heads of anything. That gives a salary histogram a right skew, which is what real salary distributions have and what makes the mean and the median differ enough to be worth discussing.
The remote column
location is one of seven offices or the string Remote, and is_remote is the boolean that agrees with it. They never disagree, which makes this a small, safe file for demonstrating a consistency check: two columns encoding the same fact is a common real-world pattern and a common source of real-world drift.
It is also a clean grouping column for a two-way pivot. Department down the side, remote across the top, mean salary in the middle, and you have the table that starts an argument in every company that has ever had one.
What people use it for
- Salary distribution work: histograms, quartiles, box plots with a real right skew.
- Splitting a full name column into given and family names.
- Tenure calculations from hire_date against a fixed reference date.
- Two-way pivots of department against remote status.
- Demonstrating a consistency check between location and is_remote.
Open it somewhere useful
Salary makes this one of the few sample files where a box plot or a quartile summary tells you something.
License, and the people in it
This dataset is dedicated to the public domain under CC0 1.0. Put it in a course, a paid product, a test suite, a bug report, a screenshot, a conference talk or a book. There is nothing to ask for, nothing to sign and no attribution required. A link back is welcome and is not a condition.
Nothing in this file describes a real person. The names are drawn from a fixed pool, the addresses are cities rather than street addresses, and every email address ends in example.com, the domain RFC 2606 reserves so that test mail can never be delivered to anybody. There is no personal information here to anonymize and none to leak.
Questions people ask about this file
Are the salaries realistic?
They are plausible for the US technology market and they are internally consistent, which matters more for a sample file. Five bands run from 62,000 at the junior end to 290,000 for a head of function, the bands overlap slightly at the edges the way real ones do, and the seniority prefix on the title tells you which band a row is in.
Why is the name in one column?
Because that is how HR exports usually arrive, and splitting it is usually the first task. A file that hands you first_name and last_name already separated skips the step most people are actually trying to practice. If you want the pre-split version, the customers dataset has separate given and family name columns.
Can location and is_remote ever disagree?
No. is_remote is derived from location on the same row, so it is true if and only if location is the string Remote. Two columns encoding one fact is a common real-world pattern, and having a file where they are guaranteed consistent gives you a baseline to compare against a file where they are not.
Is any of this a real employee record?
None of it. Names are assembled from fixed pools, departments and titles are generic, and there are no addresses, birth dates, national identifiers or anything else that would describe a person. The file exists so that HR demos and payroll integrations can be built and screen-recorded without a real roster anywhere near them.
More sample data
All twenty datasets · Messy files and every other format · Build your own schema