The breach record in one spreadsheet: what 1,036 breaches show
The public breach catalogue holds 1,036 breaches and 17.8 billion loaded addresses. Grouped by year, data class and size, it says where defensive effort belongs.
Most breach coverage is one incident at a time, which makes every breach look like the same event with a different logo. Put the whole public record in a spreadsheet instead and it stops looking like a list of incidents and starts looking like a distribution, with a shape that tells a defender where the effort belongs. This article does that with the Have I Been Pwned breach catalogue as it stood on 19 September 2026: 1,036 breaches and 17,816,217,392 loaded email addresses, grouped by year, by class of data exposed, and by size. It ships the script that produces the summary and the per-year CSV behind every number here.
What the catalogue is, and what it is not
The catalogue is metadata about breaches, not breached data. Each record carries a date, a count, a list of data classes, and a set of flags; it contains no addresses, no passwords, and nothing that could be used against an account. The script we ship reads those records and counts them.
Three field definitions decide how the numbers should be read, and the API documentation states all three plainly. PwnCount is "the total number of email addresses loaded into the system", which "is usually less than the total number reported by the media due to duplication or other data integrity issues in the source data". BreachDate is "the date (with no time) the breach originally occurred on", with the warning that "frequently breaches are discovered and reported long after the original incident. Use this attribute as a guide only." DataClasses is "an alphabetically ordered string array of impacted data classes", assigned per breach.
Two flags separate different kinds of entry. A spam list "means that the data has not come as a result of a security compromise", and a malware-sourced entry "flags that the data was sourced from a malware campaign rather than a security compromise of an online service". An unverified breach is one where, in the project's own words, "whilst there is legitimate data within the alleged breach, it may not have been possible to establish legitimacy beyond reasonable doubt." The catalogue holds 42 unverified breaches, 3 flagged as fabricated, 2 retired, 94 sensitive, 16 spam lists, 9 sourced from malware, and 6 stealer-log collections. Those 42 unverified entries account for 3.16 billion of the loaded addresses, or 17.8 percent of the total, so the verification flag is not a rounding error on the aggregate.
Our own sum of PwnCount across all 1,036 records comes to 17,816,217,392, and the project's public summary page states "1,036 Total Breaches" and "17.8B Pwned Addresses". Matching their published headline is the check that the pull was complete.
Size: a few enormous corpora, and a long tail
The median breach in the catalogue holds about 993,000 addresses. The mean holds 17.2 million. When the mean is seventeen times the median, the average is describing a distribution that has no typical member.
| Size band | Breaches | Share of breaches | Share of addresses |
|---|---|---|---|
| Under 100,000 | 151 | 14.6% | 0.0% |
| 100,000 to 1M | 370 | 35.7% | 0.9% |
| 1M to 10M | 336 | 32.4% | 6.7% |
| 10M to 100M | 142 | 13.7% | 26.0% |
| 100M and above | 37 | 3.6% | 66.3% |
Thirty-seven breaches, 3.6 percent of the record, hold two thirds of every address in it. The largest ten hold 40.1 percent. The largest single entry, Synthient Credential Stuffing Threat Data, is dated 11 April 2025, was loaded on 6 November 2025, lists two data classes, and carries 1,957,476,021 addresses on its own: 11 percent of the entire catalogue. Half of all breaches, the smaller half, together account for 0.9 percent of the addresses.
This matters because the two halves are different problems. The giant entries are aggregated credential corpora, and they are the reason a password that leaked from a forum in 2016 is a live risk to an unrelated account in 2026. The long tail is individual sites, and for any given user the tail is where their specific data sits.
Class of data: what actually leaks
The catalogue uses 163 distinct data classes. Ten of them describe most of the record.
| Data class | Breaches | All | Before 2017 | 2017 onward |
|---|---|---|---|---|
| Email addresses | 1,029 | 99.3% | 98.4% | 99.7% |
| Passwords | 674 | 65.1% | 87.4% | 55.6% |
| Names | 556 | 53.7% | 27.2% | 64.9% |
| Usernames | 484 | 46.7% | 70.2% | 36.7% |
| IP addresses | 387 | 37.4% | 48.9% | 32.5% |
| Phone numbers | 373 | 36.0% | 15.2% | 44.8% |
| Physical addresses | 301 | 29.1% | 15.2% | 34.9% |
| Dates of birth | 284 | 27.4% | 26.5% | 27.8% |
| Government issued IDs | 27 | 2.6% | 1.9% | 2.9% |
Email addresses are nearly universal, which follows from how the project indexes breaches in the first place. The interesting movement is underneath: the classes that identify a person are rising while the classes that authenticate one are falling. Grouping phone numbers, dates of birth, physical addresses and government identifiers into a single "identity data" composite of our own definition, 75 percent of breaches dated 2026 list at least one of them, against 37 percent in 2016.
One caution on reading class trends as reality. "Website activity" appears in 22.3 percent of pre-2017 breaches and 1.1 percent of later ones, which is far more likely to reflect a change in how the catalogue labels things than a change in what attackers take. Class assignment is editorial, applied by one project over thirteen years.
By year
| Year | Breaches | Addresses | Median size | With passwords | With identity data |
|---|---|---|---|---|---|
| 2016 | 104 | 1,774,074,079 | 1,062,958 | 81% | 37% |
| 2019 | 82 | 3,562,548,964 | 1,682,183 | 71% | 51% |
| 2020 | 98 | 1,291,578,986 | 1,437,894 | 72% | 70% |
| 2022 | 61 | 190,999,082 | 919,790 | 52% | 48% |
| 2023 | 46 | 192,240,143 | 468,499 | 46% | 67% |
| 2024 | 85 | 1,514,050,771 | 892,854 | 38% | 67% |
| 2025 | 62 | 2,899,897,583 | 643,435 | 31% | 60% |
| 2026 | 83 | 294,106,303 | 732,162 | 14% | 75% |
The full twenty years are in the CSV. The password share falls from 100 percent of breaches dated 2012 to 14 percent of those dated 2026, while identity data climbs to 75 percent. We would not read that as attackers losing interest in passwords; the single largest credential corpus in the record is dated 2025. The likelier reading is that password-bearing breaches now arrive consolidated into a small number of very large aggregate entries rather than as many separate site breaches, and that the individually-loaded breaches of recent years are more often customer databases than login tables.
Load lag has collapsed: the median gap between breach date and load date is 3,362 days for 2007, 263 days for 2016, and 14 days for 2026. Part of that is genuine, and part is arithmetic, because a breach dated 2026 cannot yet show a multi-year lag. Recent years are also incomplete in a second way: breaches that happened in 2026 but have not been discovered or loaded are not in the record, so the most recent rows will keep growing after this was written.
What a defender does with this
The distribution argues for a particular ordering of effort.
Credential reuse is the control with the best ratio, because 674 breaches carrying 11.8 billion addresses list passwords, and the largest entries are explicitly aggregated for reuse against other services. SP 800-63B-4, published in July 2025, makes the countermeasure a requirement rather than a suggestion in section 3.1.1.2: "Verifiers SHALL compare the prospective secret against a blocklist that contains known commonly used, expected, or compromised passwords", and "If the chosen password is found on the blocklist, the CSP SHALL require the subscriber to select a different secret and SHALL provide the reason for rejection." The mechanism is available: the project's Pwned Passwords corpus is "a huge corpus of previously breached passwords made freely available to help services block them from being used again", checked with a range search in which only the first five characters of the password's SHA-1 hash leave the client.
The same section removes a control many organisations still run, and adds the one that replaces it: "Verifiers and CSPs SHALL NOT require subscribers to change passwords periodically", but "verifiers SHALL force a change if there is evidence that the authenticator has been compromised." Scheduled expiry is not a response to the record above; appearance in it is.
The rising half of the class table has no equivalent fix, and that is the point worth carrying. A password is revocable and a date of birth is not. When 75 percent of recent entries carry identity data, the exposure they create is permanent, which moves the defensive question from rotation to minimisation: what a system collects, how long it keeps it, and whether the fields that cannot be reissued are in the table at all.
Limitations
- This is one project's catalogue, not the world's breaches. It contains what has been found, verified to its standard, and loaded.
- Summing
PwnCountcounts an address once per breach it appears in. The 17.8 billion figure is addresses-in-breaches, not people. - Breach dates are, by the documentation's own instruction, a guide. Grouping by load date gives a different and equally defensible picture, which is why the script takes
--by added. - The size bands and the identity-data composite are our groupings, not the project's.
- Nothing here measures harm. A million-address breach of one class and a million-address breach of nine are one row each.
The dataset
_README for the-breach-record-in-one-spreadsheet.csv, one row per breach year:
year,breaches,addresses: the year of the breach date, how many breaches carry it, and the sum of their loaded-address countsmedian_size,p90_size: the median and 90th-percentile breach size in that yearlargest_name,largest_addresses: the largest single breach dated to that yearverified,unverified,sensitive,spam_list,malware,stealer_log: flag counts as recorded in the cataloguewith_passwords,with_email,with_names,with_phone,with_dob,with_physical,with_govid,with_card: breaches listing each headline data classidentity_any: breaches listing at least one of phone number, date of birth, physical address, or government identifiermedian_days_to_load: median days from the stated breach date to the date the record was loadedsource,retrieved_at: the endpoint and the retrieval date, 2026-09-19
Reproducing it
The endpoint needs no authentication and returns metadata only.
python code/the-breach-record-in-one-spreadsheet.py --fetch --catalogue catalogue.json
python code/the-breach-record-in-one-spreadsheet.py --catalogue catalogue.json \
--out summary.csv --classes --concentration
Rerun it in three months and the recent rows will have moved, because the record is a record of discovery as much as of compromise. The shape, though, has been stable for years: a handful of enormous credential corpora at one end, a long tail of individual sites at the other, and a slow shift from data you can change to data you cannot.
Sources
- Have I Been Pwned, the public breaches endpoint (1,036 records retrieved 2026-09-19)
- Have I Been Pwned, "API v3" documentation, breach model field definitions (read 2026-09-19)
- Have I Been Pwned, "FAQs", definitions of breach, unverified, sensitive, spam list and stealer logs (read 2026-09-19)
- Have I Been Pwned, "Who's been pwned", published totals of 1,036 breaches and 17.8B addresses (read 2026-09-19)
- NIST, SP 800-63B-4 Sec. 3.1.1.2 "Password Verifiers" (read 2026-09-19)
- NIST, publication record for SP 800-63B-4 (published July 2025)
- Have I Been Pwned, "Pwned Passwords", the blocklist corpus and its range search (read 2026-09-19)