Technical writing

Bureau of Prisons Data: The Federal Inmate Population Behind 150,000 Federal Prisoners

· 14 min read· AI Analytics
Federal DataDOJCriminal JusticePrison Data

The Federal Bureau of Prisons manages 121 federal facilities holding roughly 148,000 people convicted of federal crimes—drug trafficking, immigration offenses, financial fraud, weapons violations, and white-collar crimes. That number peaked at 219,000 in 2013 and has declined steadily since, driven by sentencing reform and, briefly, by COVID-19 home confinement. The BOP publishes population statistics weekly. Almost no one treats them as a dataset.

BOP and the federal prison system

The Bureau of Prisons is a component of the Department of Justice and is the only federal agency whose primary mission is operating correctional institutions. It is categorically distinct from state prison systems, which held approximately 1.3 million people as of 2023 for violations of state criminal law—assault, burglary, state drug offenses, murder under state statute. Federal prisoners are people convicted of federal crimes: offenses defined by federal statute, prosecuted by United States Attorneys in federal district courts, and sentenced under federal sentencing guidelines.

The distinction matters for data work. State prison populations are aggregated by the Bureau of Justice Statistics through the National Prisoner Statistics Program and reported annually with a one-to-two-year lag. BOP data, by contrast, is updated weekly on the BOP website at bop.gov/about/statistics. The two systems use different offense classifications, different sentence structures, and different parole and release mechanisms. Conflating them produces nonsense. The combined US incarceration count—federal prisons, state prisons, and local jails—was approximately two million people as of 2019, the last pre-COVID baseline year. The federal population is roughly 7% of that total.

BOP facilities are classified by security level: minimum, low, medium, high, and the ADX administrative maximum at Florence, Colorado—the federal “supermax” housing fewer than 400 inmates under near-total isolation. The BOP weekly statistics page breaks the population by security level, by race and ethnicity, by gender (women are approximately 7% of federal inmates, housed in dedicated Federal Correctional Institutions), by age distribution, by average sentence length, and by average time served. Each of these cuts is a separate HTML table on a separate page.

Offense type: drug offenses at 43 percent

The single most important fact about the federal prison population is its offense composition. As of 2024, drug offenses account for approximately 43% of federal inmates—down from a peak above 50% in the early 2010s but still the largest single category by a wide margin. The next largest categories are weapons and firearms offenses (roughly 20%), immigration offenses (roughly 11%), sex offenses (roughly 10%), robbery (roughly 4%), and fraud (roughly 3%). All other offenses combined account for the remainder.

This offense distribution is the direct product of mandatory minimum sentencing laws passed in the 1980s and 1990s. Under 21 U.S.C. § 841, federal drug trafficking convictions trigger mandatory minimum sentences based on drug quantity thresholds—five years for a threshold quantity, ten years for a higher threshold, regardless of the defendant's role in the offense or criminal history. These thresholds created enormous prosecutorial leverage: the possibility of a ten-year mandatory minimum for a low-level courier made plea bargains to shorter sentences nearly universal.

The crack/powder cocaine 100:1 sentencing disparity, embedded in the Anti-Drug Abuse Act of 1986, is the most studied example of mandatory minimum law producing racially disparate outcomes. Under pre-reform law, a defendant convicted of possessing five grams of crack cocaine faced the same five-year mandatory minimum as a defendant convicted of possessing 500 grams of powder cocaine. Because crack cocaine was disproportionately used and sold in Black communities and powder cocaine in white communities, the disparity translated directly into racial disparities in sentence length. The Fair Sentencing Act of 2010 reduced the ratio from 100:1 to 18:1. The FIRST STEP Act of 2018 made that reduction retroactive, allowing thousands of people sentenced under the old ratio to petition for resentencing.

The FIRST STEP Act also created a risk and needs assessment system, implemented through a tool called PATTERN (Prisoner Assessment Tool Targeting Estimated Risk and Needs), that classifies federal inmates as minimum, low, medium, or high recidivism risk. Inmates classified at low or minimum risk who complete approved recidivism-reduction programming can earn time credits that advance their transfer to prerelease custody—halfway houses or home confinement—up to a year before their projected release date. PATTERN is the statutory mechanism linking risk assessment scores to actual sentence reduction.

Racial composition and documented disparities

Black inmates represent approximately 38% of the federal prison population while comprising roughly 12% of the US population. Hispanic inmates represent roughly 30% of the federal population. The BOP weekly statistics publish these figures without adjustment for offense type, sentence length, or prosecutorial charging decisions. Understanding the source of the disparity requires leaving BOP data and moving to US Sentencing Commission data.

The USSC publishes annual statistical reports covering every sentenced federal criminal case. Commission research has consistently documented that Black male defendants receive sentences averaging roughly 19% longer than similarly situated white male defendants after controlling for criminal history and offense characteristics—a gap that narrows but does not disappear when controlling for charge severity. The gap is larger for drug offenses than for other offense types and larger in districts with fewer resources for federal defense than in resource-rich districts. The USSC attributes part of the gap to prosecutorial charging decisions—specifically, the decision whether to file a charge carrying a mandatory minimum—which occur before judicial discretion attaches.

Bureau of Justice Statistics: the canonical source for national counts

The Bureau of Justice Statistics is the primary federal statistical agency for criminal justice data—a distinct agency from BOP. While BOP manages the federal prison system, BJS collects and publishes data on all components of the US criminal justice system: federal prisons, all 50 state prison systems, local jails, probation, parole, courts, and law enforcement. BJS is a component of DOJ's Office of Justice Programs and operates independently of BOP.

The BJS National Prisoner Statistics program collects annual prisoner counts from all 50 states, the District of Columbia, and the federal government. It is the canonical source for the total US state and federal prison population, the number of people admitted and released each year, and the prison population broken down by sex, race, sentence length, and offense type at the state and federal level. The annual Prisoners bulletin is the primary publication. The data file behind each bulletin is available for download at the BJS website and through the National Archive of Criminal Justice Data at ICPSR.

BJS also publishes the Jail Inmates annual bulletin (local jails, which hold people awaiting trial and people serving sentences under one year); theProbation and Parole annual bulletin (the 3.7 million adults on probation and 900,000 on parole as of 2023); the National Crime Victimization Survey, which estimates victimization rates independently of police reporting; the Law Enforcement Management and Administrative Statistics survey; and the Survey of Prison Inmates, which collects detailed demographic and offense history data from a sample of state and federal prisoners.

US Sentencing Commission data: every federal criminal case

The United States Sentencing Commission publishes case-level data on every sentenced federal criminal case since fiscal year 1991. The USSC Datafiles, available at ussc.gov/research/datafiles, contain one record per sentenced defendant. Each record includes offense type, the advisory guideline range, the actual sentence imposed, whether the sentence was above or below the guideline range and the basis for any departure, the district, and demographic characteristics of the defendant including race, sex, age, and citizenship status.

These are the most granular federal sentencing records available to the public. Researchers use them to measure sentencing disparity across race, sex, district, and judge—though USSC data does not identify individual judges, a limitation that makes judge-level analysis impossible from USSC files alone. The USSC also publishes Quick Facts one-page summaries for specific offense types covering average sentence lengths, demographic breakdowns, and guideline compliance rates. For the offense types that make up the bulk of the federal docket—drug trafficking, immigration, firearms, fraud—the Quick Facts are the fastest path to current aggregate statistics.

The USSC annual Statistical Report is the most comprehensive single document on federal sentencing. It reports, for each major offense type: the number of cases, the median sentence, the percentage sentenced within the guideline range, the percentage sentenced below the range with government motion, and the percentage sentenced below the range without government motion. That last category— below-range sentences without a government departure motion—is the measure of judicial variance from the guidelines, and it varies substantially across districts and has been a consistent subject of USSC monitoring since the Booker decision in 2005 rendered the guidelines advisory rather than mandatory.

PACER and federal court records

Public Access to Court Electronic Records—PACER—is the federal judiciary's electronic filing and retrieval system. Every federal case filing, docket entry, and publicly available document across all 94 federal district courts, 13 courts of appeals, and the Supreme Court is accessible through PACER. Case types are identified by suffix: criminal cases are designated CR, civil cases CV, bankruptcy BK, and appeals AP.

A federal criminal docket typically contains: the initial complaint or information, the indictment if the case went to a grand jury, the arrest warrant and initial appearance, any detention hearing transcripts, the plea agreement or trial verdict, the presentence investigation report (sealed in almost all cases, and therefore not accessible through PACER), and the judgment and commitment order which specifies the sentence. The judgment is public and contains the offense of conviction, the offense level and criminal history category under the guidelines, the guideline range, and the actual sentence.

PACER charges 10 cents per page for downloaded documents, capped at $0.30 for documents under 30 pages. There is a quarterly exemption for accounts that accrue less than $30 in charges. The Free Law Project's CourtListener platform provides free access to a subset of PACER documents, primarily appellate opinions and some district court filings. The RECAP browser extension, maintained by the Free Law Project, automatically uploads PACER documents to the CourtListener archive whenever a user downloads them—creating a growing free archive of otherwise paywalled records.

Supervised release: the federal parole replacement

Federal prisoners do not have parole. The Sentencing Reform Act of 1984, which took effect for offenses committed after November 1, 1987, abolished parole for federal offenses and replaced it with “supervised release”—a fixed term of post-prison supervision imposed by the sentencing judge at the time of sentencing. Federal prisoners must serve at least 85% of their sentence (the “85 percent rule”); good conduct time can reduce a sentence by up to 54 days per year, but the reduction is capped and calculated differently than state parole eligibility.

Supervised release is distinct from parole both structurally and legally. Conditions of supervised release are set by the court at sentencing, not by a parole board after release. Violations of supervised release conditions are adjudicated by the original sentencing judge, not a parole board. A violation finding can result in revocation and re-imprisonment for up to the statutory maximum of the original offense. BJS tracks supervised release revocations in the Probation and Parole annual bulletin. Federal revocation rates tend to be lower than state parole revocation rates, in part because federal supervision resources are more consistent and in part because the federal offense mix is different from the state mix.

Private prisons and federal contracting

Approximately 16–18% of federal inmates are held in privately operated facilities under contract with BOP. The two dominant contractors are CoreCivic (formerly Corrections Corporation of America) and GEO Group. Their BOP contracts are individually visible on USASpending.gov, searchable by recipient name and awarding agency. CoreCivic and GEO Group together hold BOP contracts worth more than $700 million per year. These are not grants; they are service contracts specifying per-diem rates per inmate, facility operating standards, staffing requirements, and audit rights.

The political economy of private prison contracting intersects directly with federal sentencing policy. Both CoreCivic and GEO Group have historically lobbied in favor of mandatory minimum sentences and against sentencing reform legislation—policy positions that directly affect the size of the inmate population on which their per-diem revenue depends. This lobbying activity is documented in their publicly filed lobbying disclosure reports under the Lobbying Disclosure Act, available through the Senate Office of Public Records.

DOJ issued a policy in 2016 directing BOP to phase out private prison contracts as they expired. The Trump administration reversed that policy in 2017. The Biden DOJ reissued the phaseout direction in 2021. As of 2024, private prison contracts remain in force; the facilities involved are listed on the BOP website under its private management page. USASpending.gov contract records provide the contract values, modification history, and expiration dates for each facility agreement.

ICE immigration detention: a separate system

Immigration detention under Immigration and Customs Enforcement is categorically separate from the federal prison system under BOP. ICE detainees are civil detainees—they have not been convicted of federal crimes. They are held pending immigration court proceedings or removal under civil immigration law. ICE detains approximately 35,000 people per day across roughly 200 detention facilities: ICE-owned Service Processing Centers, intergovernmental agreement facilities contracted through county jails and city detention centers, and privately contracted facilities operated by CoreCivic and GEO Group.

ICE publishes detention statistics at ice.gov/detention-management, including average daily population, nationality of detainees, length of detention, and facility list. The average cost of immigration detention is approximately $148 per person per day according to Congressional Research Service estimates, compared to roughly $120 per day for BOP federal inmates. TRAC Immigration at Syracuse University (trac.syr.edu) is the most comprehensive secondary source for immigration enforcement data, processing FOIA-obtained records from ICE and the Executive Office for Immigration Review to track case outcomes, detention lengths, and removal rates by nationality and jurisdiction.

The conflation of ICE detention with the federal prison population is a common analytical error. People in ICE custody are not federal prisoners. They have not been convicted of federal crimes. The legal authority for their detention is civil immigration statute, not the federal criminal code. Their cases are adjudicated in immigration courts under the Executive Office for Immigration Review, not in Article III federal district courts. Their data does not appear in BOP statistics, USSC sentencing files, or BJS National Prisoner Statistics.

Recidivism: what the data actually measures

BJS publishes multi-year recidivism studies tracking specific cohorts of released prisoners. The most cited is the 2018 BJS study following a nationally representative sample of people released from state prisons in 2008: 68% were rearrested within three years, 79% within six years, and 83% within nine years. These numbers are frequently cited as evidence of the failure of rehabilitation. They require careful interpretation.

Rearrest, reconviction, and return to prison measure different things. Rearrest means a law enforcement contact that resulted in an arrest charge—not a conviction, not a new sentence. Many rearrest events result in no charge being filed, or in charges that are dismissed. Reconviction rates are substantially lower than rearrest rates. Return to prison includes both new sentences for new crimes and revocations of supervised release or parole for technical violations (failing a drug test, missing a reporting appointment) that did not involve new criminal conduct.

Federal prisoner recidivism is measurably lower than state prisoner recidivism. BJS research has found federal prisoners rearressted within three years at rates around 44%, compared to 76% for state prisoners. This gap reflects the difference in offense mix: federal prisoners are more heavily concentrated in white-collar crime, large-scale drug trafficking, and immigration offenses where first-time offender profiles are more common, while state prisons hold a higher proportion of people with extensive criminal histories convicted of violent and property crimes. The PATTERN risk assessment tool implemented under FIRST STEP Act attempts to operationalize this offense-mix-and-history dynamic into a structured classification for purposes of earned time credit eligibility.

Python: download and visualize BOP population data

The BOP statistics pages publish HTML tables that update weekly. The following script fetches the security level breakdown and the offense type breakdown, parses both tables, and produces a bar chart ranking offense categories by their share of the federal inmate population. Drug offenses and immigration offenses are highlighted in distinct colors.

import requests
from bs4 import BeautifulSoup
import re
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker

# BOP publishes weekly population statistics as HTML tables at bop.gov.
# There is no JSON or CSV API; parsing requires reading the HTML pages directly.
# The two primary pages used here:
#   1. Total population by security level:
#      https://www.bop.gov/about/statistics/statistics_inmate_sec_levels.jsp
#   2. Offense type breakdown:
#      https://www.bop.gov/about/statistics/statistics_inmate_offenses.jsp

BOP_SECURITY = "https://www.bop.gov/about/statistics/statistics_inmate_sec_levels.jsp"
BOP_OFFENSES = "https://www.bop.gov/about/statistics/statistics_inmate_offenses.jsp"

HEADERS = {
    "User-Agent": "Mozilla/5.0 (research; contact research@example.org)"
}

def fetch_bop_table(url):
    """Fetch a BOP statistics page and return the first data table as a list of dicts."""
    resp = requests.get(url, headers=HEADERS, timeout=30)
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, "html.parser")

    # BOP statistics pages use a standard HTML table for the data.
    table = soup.find("table")
    if not table:
        raise ValueError("No table found at " + url)

    headers = []
    rows = []
    for i, tr in enumerate(table.find_all("tr")):
        cells = [td.get_text(strip=True) for td in tr.find_all(["th", "td"])]
        if not cells:
            continue
        if i == 0 or (not headers and any(c for c in cells)):
            # Treat first non-empty row as header
            if not headers:
                headers = cells
                continue
        if headers:
            row = dict(zip(headers, cells))
            rows.append(row)

    return rows

def parse_count(text):
    """Convert a formatted count string like '23,145' to an integer."""
    cleaned = re.sub(r"[^0-9]", "", text)
    return int(cleaned) if cleaned else 0

def parse_percent(text):
    """Convert a percentage string like '43.2%' to a float."""
    m = re.search(r"([0-9]+(?:\.[0-9]+)?)", text)
    return float(m.group(1)) if m else 0.0

# --- Step 1: Security level population breakdown ---
sec_rows = fetch_bop_table(BOP_SECURITY)
print("Security Level Population")
print("-" * 40)
total_inmates = 0
sec_data = {}
for row in sec_rows:
    # Column names vary; look for a label column and a count column
    label = ""
    count = 0
    for k, v in row.items():
        if re.search(r"level|type|security|category", k, re.I):
            label = v
        if re.search(r"number|count|total|inmates", k, re.I):
            count = parse_count(v)
    if label and count:
        sec_data[label] = count
        total_inmates += count
        print(label + ": " + str(count))

print("Total across levels: " + str(total_inmates))

# --- Step 2: Offense type breakdown ---
off_rows = fetch_bop_table(BOP_OFFENSES)
print()
print("Offense Type Breakdown")
print("-" * 40)

offense_data = {}
for row in off_rows:
    label = ""
    pct = 0.0
    count = 0
    for k, v in row.items():
        if re.search(r"offense|crime|category", k, re.I):
            label = v
        if re.search(r"percent|pct|%", k, re.I):
            pct = parse_percent(v)
        if re.search(r"number|count|total|inmates", k, re.I):
            count = parse_count(v)
    if label and (pct or count):
        offense_data[label] = {"pct": pct, "count": count}
        print(label + ": " + str(pct) + "% (" + str(count) + " inmates)")

# Sort by percentage descending
sorted_offenses = sorted(
    [(k, v["pct"]) for k, v in offense_data.items() if v["pct"] > 0],
    key=lambda x: x[1],
    reverse=True
)

# --- Step 3: Bar chart of offense categories ---
if sorted_offenses:
    labels = [x[0] for x in sorted_offenses]
    pcts = [x[1] for x in sorted_offenses]

    # Color drug offenses and immigration offenses distinctly
    colors = []
    for lbl in labels:
        if re.search(r"drug", lbl, re.I):
            colors.append("#c0392b")   # red for drug offenses
        elif re.search(r"immigr", lbl, re.I):
            colors.append("#2980b9")   # blue for immigration
        else:
            colors.append("#7f8c8d")   # gray for all others

    fig, ax = plt.subplots(figsize=(10, max(5, len(labels) * 0.55)))
    bars = ax.barh(labels[::-1], pcts[::-1], color=colors[::-1], edgecolor="white")
    ax.set_xlabel("Share of Federal Inmate Population (%)")
    ax.set_title("Federal Prison Population by Offense Category (BOP, latest weekly)")
    ax.xaxis.set_major_formatter(mticker.FormatStrFormatter("%.0f%%"))
    ax.set_xlim(0, max(pcts) * 1.15)

    # Annotate bars with percentage
    for bar, pct in zip(bars, pcts[::-1]):
        ax.text(
            bar.get_width() + 0.3,
            bar.get_y() + bar.get_height() / 2,
            str(round(pct, 1)) + "%",
            va="center",
            fontsize=9
        )

    plt.tight_layout()
    plt.savefig("bop_offense_breakdown.png", dpi=150)
    print()
    print("Chart saved to bop_offense_breakdown.png")
    plt.show()
else:
    print("No offense percentage data found; check column names in the parsed rows.")
    print("Raw first row keys: " + str(list(off_rows[0].keys()) if off_rows else "no rows"))

The script above handles the BOP table structure as of mid-2025. BOP occasionally restructures its statistics pages; if column names change, update the regex patterns in fetch_bop_table accordingly. The final print statement logs the raw column names parsed from the first row to aid debugging. For longitudinal analysis—tracking how offense-type percentages shift over time—the script should be scheduled weekly and its output appended to a time-series store; BOP does not publish historical weekly archives, so the only way to build a historical dataset is to collect each weekly snapshot as it appears.


For the FBI Uniform Crime Reports and crime statistics that define the front end of the criminal justice funnel—arrests, clearance rates, and offense counts—before cases reach federal prosecution: FBI UCR: The Federal Crime Statistics Behind Every Public Safety Analysis →

For the DOJ False Claims Act settlement database covering $70 billion in fraud recoveries, which frequently intersects with federal criminal prosecutions of healthcare and defense contractors: DOJ False Claims Act Settlements: The $70 Billion Fraud Recovery Database →

For NLRB union election data covering organizing drives and vote counts in federal labor law enforcement—the labor-side counterpart to DOJ criminal enforcement data: NLRB Union Election Data: The Federal Record of Every Organizing Drive and Vote Count →