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.

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_idfull_namedepartmenttitlehire_datesalarylocationis_remote
2001Ahmed PetersonSupportSenior QA Engineer2019-01-02167821Singaporefalse
2002Anna DiazEngineeringSenior Support Engineer2019-01-05165901Londonfalse
2003Ryan RobinsonFinanceFinancial Analyst2019-01-07129740Bengalurufalse
2004George RichardsonLegalSenior UX Designer2019-01-10179143Seattlefalse
2005Lucas RobinsonSalesSoftware Engineer2019-01-1398525Singaporefalse
2006Richard EdwardsEngineeringStaff Sales Representative2019-01-16230043Berlinfalse
2007Fatima OrtizEngineeringSenior Research Scientist2019-01-18160460Singaporefalse
2008Jessica FloresOperationsStaff Data Analyst2019-01-21230739Berlinfalse

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.

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.