Skip to contents

Alabama’s 717,473 public school students across 153 districts and 1,362 campuses – 5 years of enrollment data (2021-2025) from the Alabama State Department of Education.

Part of the njschooldata family.

Full documentation – all 15 stories with interactive charts, getting-started guide, and complete function reference.

Highlights

library(alschooldata)
library(dplyr)
library(tidyr)
library(ggplot2)

theme_set(theme_minimal(base_size = 14))

enr <- fetch_enr_multi(2021:2025, use_cache = TRUE)
enr_2025 <- enr |> filter(end_year == 2025)

1. Virtual schools exploded to 20,000 students

Alabama’s virtual schools grew from 12,741 students (8 schools) in 2021 to 19,963 students (16 schools) in 2025. Alabama Connections Academy alone enrolls 7,339, making Limestone County appear to be one of the state’s largest districts.

virtual <- enr |>
  filter(is_campus, subgroup == "total_enrollment", grade_level == "TOTAL",
         grepl("Virtual|Connections|Destinations", campus_name, ignore.case = TRUE)) |>
  group_by(end_year) |>
  summarize(n_schools = n(), total_students = sum(n_students), .groups = "drop") |>
  arrange(end_year)

stopifnot(nrow(virtual) > 0)
virtual
#>   end_year n_schools total_students
#> 1     2021         8          12741
#> 2     2022        13          15856
#> 3     2023        14          15138
#> 4     2024        13          16207
#> 5     2025        16          19963
Virtual schools
Virtual schools

(source)


2. Multiracial students are the fastest-growing demographic

Students identifying as multiracial grew from 25,456 (3.5%) to 42,305 (5.9%) since 2021 – a 66% increase. At this pace, multiracial students will outnumber Asian and Native American students combined.

multi <- enr |>
  filter(is_state, subgroup == "multiracial", grade_level == "TOTAL") |>
  mutate(pct = round(pct * 100, 1)) |>
  select(end_year, n_students, pct) |>
  arrange(end_year)

stopifnot(nrow(multi) > 0)
multi
#>   end_year n_students pct
#> 1     2021      25456 3.5
#> 2     2022      29716 4.0
#> 3     2023      33651 4.6
#> 4     2024      37946 5.3
#> 5     2025      42305 5.9
Multiracial trend
Multiracial trend

(source)


3. Black Belt counties are hemorrhaging students

Perry County has lost 32% of its enrollment since 2021 – the steepest decline of any Alabama district with 500+ students. Sumter County lost 29%, and Selma City lost 24%.

decline <- enr |>
  filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL",
         end_year %in% c(2021, 2025)) |>
  select(end_year, district_name, n_students) |>
  pivot_wider(names_from = end_year, values_from = n_students) |>
  filter(!is.na(`2021`), !is.na(`2025`), `2021` >= 500) |>
  mutate(change = `2025` - `2021`,
         pct_change = round((`2025` / `2021` - 1) * 100, 1)) |>
  arrange(pct_change) |>
  head(10)

stopifnot(nrow(decline) > 0)
decline
#>    district_name 2021 2025 change pct_change
#> 1   Perry County 1148  778   -370      -32.2
#> 2  Sumter County 1202  851   -351      -29.2
#> 3 Talladega City 1837 1356   -481      -26.2
#> 4     Selma City 2776 2124   -652      -23.5
#> 5  Dallas County 2775 2211   -564      -20.3
#> 6  Wilcox County 1404 1127   -277      -19.7
#> 7 Conecuh County 1474 1197   -277      -18.8
#> 8 Lowndes County 1311 1081   -230      -17.5
#> 9  Anniston City 1980 1643   -337      -17.0
#> 10  Roanoke City 1475 1239   -236      -16.0
Fastest declining districts
Fastest declining districts

(source)


Data Taxonomy

Category Years Function Details
Enrollment 2021-2025 fetch_enr() / fetch_enr_multi() State, district, campus. Race, gender, FRPL, SpEd, LEP
Assessments Not yet available
Graduation Not yet available
Directory Current fetch_directory() District, school. Principal, superintendent, address, phone, website, grades
Per-Pupil Spending Not yet available
Accountability Not yet available
Chronic Absence Not yet available
EL Progress Not yet available
Special Ed Not yet available

See the full data category taxonomy for what each category covers.

Quick Start

R

# install.packages("remotes")
remotes::install_github("almartin82/alschooldata")
library(alschooldata)
library(dplyr)

# Fetch one year
enr_2025 <- fetch_enr(2025)

# Fetch multiple years
enr_multi <- fetch_enr_multi(2021:2025)

# State totals
enr_2025 %>%
  filter(is_state, subgroup == "total_enrollment", grade_level == "TOTAL")

# District breakdown
enr_2025 %>%
  filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") %>%
  arrange(desc(n_students))

# Demographics
enr_2025 %>%
  filter(is_state, grade_level == "TOTAL",
         subgroup %in% c("white", "black", "hispanic", "asian")) %>%
  select(subgroup, n_students, pct)

Python

pip install git+https://github.com/almartin82/alschooldata.git#subdirectory=pyalschooldata
import pyalschooldata as al

# Fetch one year
enr_2025 = al.fetch_enr(2025)

# Fetch multiple years
enr_multi = al.fetch_enr_multi([2021, 2022, 2023, 2024, 2025])

# State totals
enr_2025[
    (enr_2025['is_state'] == True) &
    (enr_2025['subgroup'] == 'total_enrollment') &
    (enr_2025['grade_level'] == 'TOTAL')
]

# District breakdown
district_df = enr_2025[
    (enr_2025['is_district'] == True) &
    (enr_2025['subgroup'] == 'total_enrollment') &
    (enr_2025['grade_level'] == 'TOTAL')
].sort_values('n_students', ascending=False)

# Demographics
enr_2025[
    (enr_2025['is_state'] == True) &
    (enr_2025['grade_level'] == 'TOTAL') &
    (enr_2025['subgroup'].isin(['white', 'black', 'hispanic', 'asian']))
][['subgroup', 'n_students', 'pct']]

Explore More

Full analysis with 15 stories: - Enrollment trends – 15 stories - Function reference

Data Notes

Data Source

Alabama State Department of Education (ALSDE) Federal Report Card: alsde.edu

Available Years

2021-2025 (5 years of complete data)

What’s Included

  • Levels: State, district (~153), campus (~1,362)
  • Demographics: White, Black, Hispanic, Asian, Native American, Pacific Islander, Multiracial
  • Special populations: Economically disadvantaged, English learners, Students with disabilities
  • Gender: Male, Female
  • Grade levels: PK-12

Alabama ID System

  • District codes: 3 digits (county systems, city systems, and charter operators)
  • Campus codes: 4 digits unique within each district

Data Quality Notes

  • Enrollment counts are as of Census Day (typically early October)
  • Economically disadvantaged rate shows volatility (48%-65%) likely due to reporting methodology changes
  • Special education rate spiked 2022-2024, possibly reflecting expanded identification
  • Virtual school enrollment is reported under the hosting district, inflating some district totals

Known Limitations

  • Pre-2021 data is not available through the current ALSDE data source
  • Pre-K enrollment data is inconsistently reported
  • Charter schools are reported as separate districts
  • Virtual school students counted under hosting district rather than student’s home district

Deeper Dive


4. Alabama lost 12,000 students since 2022

Statewide enrollment peaked at 735,808 in 2022 and has since declined by over 18,000 students. The 2024 drop of 11,073 was the steepest single-year decline.

state_totals <- enr |>
  filter(is_state, subgroup == "total_enrollment", grade_level == "TOTAL") |>
  select(end_year, n_students) |>
  arrange(end_year) |>
  mutate(change = n_students - lag(n_students),
         pct_change = round(change / lag(n_students) * 100, 2))

stopifnot(nrow(state_totals) > 0)
state_totals
#>   end_year n_students change pct_change
#> 1     2021     729786     NA         NA
#> 2     2022     735808   6022       0.83
#> 3     2023     729789  -6019      -0.82
#> 4     2024     718716 -11073      -1.52
#> 5     2025     717473  -1243      -0.17
Statewide trend
Statewide trend

(source)


5. Hispanic enrollment surged from 9.5% to 12.2% in four years

Hispanic students are the fastest-growing racial/ethnic group in Alabama schools, adding nearly 19,000 students since 2021 while overall enrollment declined.

hispanic <- enr |>
  filter(is_state, subgroup == "hispanic", grade_level == "TOTAL") |>
  mutate(pct = round(pct * 100, 1)) |>
  select(end_year, n_students, pct) |>
  arrange(end_year)

stopifnot(nrow(hispanic) > 0)
hispanic
#>   end_year n_students  pct
#> 1     2021      69093  9.5
#> 2     2022      74561 10.1
#> 3     2023      78638 10.8
#> 4     2024      84661 11.8
#> 5     2025      87790 12.2
Hispanic trend
Hispanic trend

(source)


6. Mobile County is Alabama’s largest system – and shrinking fastest

Mobile County Public Schools serves 47,366 students, nearly 14,000 more than second-place Jefferson County. But Mobile has lost 5,768 students since 2021, a decline of 10.9%.

top_10 <- enr_2025 |>
  filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
  arrange(desc(n_students)) |>
  head(10) |>
  select(district_name, n_students)

stopifnot(nrow(top_10) > 0)
top_10
#>        district_name n_students
#> 1      Mobile County      47366
#> 2   Jefferson County      33844
#> 3     Baldwin County      30491
#> 4  Montgomery County      25491
#> 5    Huntsville City      22776
#> 6      Shelby County      20159
#> 7     Madison County      19769
#> 8    Birmingham City      19710
#> 9  Tuscaloosa County      18135
#> 10  Limestone County      15816
Top 10 districts
Top 10 districts

(source)


7. Alabama’s student body: 56% white, 32% Black, 12% Hispanic

Alabama’s racial demographics are shifting. White students still form the majority but their share dropped from 58.3% to 56.1% since 2021, while Hispanic and multiracial shares both grew.

demographics <- enr_2025 |>
  filter(is_state, grade_level == "TOTAL",
         subgroup %in% c("white", "black", "hispanic", "asian",
                         "native_american", "pacific_islander", "multiracial")) |>
  mutate(pct = round(pct * 100, 1)) |>
  select(subgroup, n_students, pct) |>
  arrange(desc(n_students))

stopifnot(nrow(demographics) > 0)
demographics
#>           subgroup n_students  pct
#> 1            white     402422 56.1
#> 2            black     228708 31.9
#> 3         hispanic      87790 12.2
#> 4      multiracial      42305  5.9
#> 5  native_american      30582  4.3
#> 6            asian      11511  1.6
#> 7 pacific_islander       1945  0.3
Demographics
Demographics

(source)


8. Nearly 3 in 5 Alabama students are economically disadvantaged

The economically disadvantaged rate jumped from 51% in 2021 to 65% in 2023, then settled at 59% in 2025. This volatility may reflect changes in reporting methodology rather than true poverty shifts.

econ <- enr |>
  filter(is_state, grade_level == "TOTAL", subgroup == "econ_disadv") |>
  mutate(pct = round(pct * 100, 1)) |>
  select(end_year, n_students, pct) |>
  arrange(end_year)

stopifnot(nrow(econ) > 0)
econ
#>   end_year n_students  pct
#> 1     2021     371737 50.9
#> 2     2022     351049 47.7
#> 3     2023     477329 65.4
#> 4     2024     465245 64.7
#> 5     2025     422645 58.9
Econ disadv trend
Econ disadv trend

(source)


9. Birmingham City lost 2,191 students in four years

Birmingham City Schools has shed students every single year since 2021, dropping from 21,901 to 19,710 – a 10% decline. Once a top-5 Alabama district, it now ranks 8th.

bham <- enr |>
  filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL",
         grepl("Birmingham City", district_name)) |>
  select(end_year, n_students) |>
  arrange(end_year) |>
  mutate(change = n_students - lag(n_students))

stopifnot(nrow(bham) > 0)
bham
#>   end_year n_students change
#> 1     2021      21901     NA
#> 2     2022      21163   -738
#> 3     2023      19921  -1242
#> 4     2024      19829    -92
#> 5     2025      19710   -119
Birmingham decline
Birmingham decline

(source)


10. English Learners grew 52% in four years

Alabama’s English Learner population surged from 33,595 (4.6%) to 51,068 (7.1%), closely tracking the growth in Hispanic enrollment and reflecting the state’s demographic transformation.

el_trend <- enr |>
  filter(is_state, subgroup == "lep", grade_level == "TOTAL") |>
  mutate(pct = round(pct * 100, 1)) |>
  select(end_year, n_students, pct) |>
  arrange(end_year)

stopifnot(nrow(el_trend) > 0)
el_trend
#>   end_year n_students pct
#> 1     2021      33595 4.6
#> 2     2022      36956 5.0
#> 3     2023      41430 5.7
#> 4     2024      47838 6.7
#> 5     2025      51068 7.1
EL trend
EL trend

(source)


11. Special Ed spiked to 18% then fell back to 14.5%

Special education enrollment jumped from 14% to 18% between 2021 and 2024, then dropped to 14.5% in 2025. The spike may reflect expanded eligibility or pandemic-related identification, with the recent decline suggesting a correction.

sped <- enr |>
  filter(is_state, subgroup == "special_ed", grade_level == "TOTAL") |>
  mutate(pct = round(pct * 100, 1)) |>
  select(end_year, n_students, pct) |>
  arrange(end_year)

stopifnot(nrow(sped) > 0)
sped
#>   end_year n_students  pct
#> 1     2021     102117 14.0
#> 2     2022     130946 17.8
#> 3     2023     130655 17.9
#> 4     2024     129379 18.0
#> 5     2025     104371 14.5
Special Ed trend
Special Ed trend

(source)


12. 3rd grade is the largest class in Alabama

With 57,054 students, 3rd grade edges out 1st grade (56,798) and kindergarten (55,467) as the most enrolled grade level in 2025.

grade_dist <- enr_2025 |>
  filter(is_state, subgroup == "total_enrollment",
         grade_level %in% c("K", "01", "02", "03", "04", "05",
                            "06", "07", "08", "09", "10", "11", "12")) |>
  mutate(grade_level = factor(grade_level,
                              levels = c("K", "01", "02", "03", "04", "05",
                                        "06", "07", "08", "09", "10", "11", "12"))) |>
  select(grade_level, n_students) |>
  arrange(grade_level)

stopifnot(nrow(grade_dist) > 0)
grade_dist
#>    grade_level n_students
#> 1            K      55467
#> 2           01      56798
#> 3           02      56515
#> 4           03      57054
#> 5           04      54307
#> 6           05      53653
#> 7           06      53450
#> 8           07      54573
#> 9           08      55053
#> 10          09      56624
#> 11          10      55541
#> 12          11      53178
#> 13          12      50839
Grade distribution
Grade distribution

(source)


13. Mobile County: 73% low-income, 51% Black

Mobile County’s demographics are dramatically different from statewide averages. Its economically disadvantaged rate (73%) is 14 points above the state average, and its Black student population (51%) is 19 points above the statewide share.

mobile_demo <- enr_2025 |>
  filter(is_district, grade_level == "TOTAL",
         grepl("Mobile County", district_name),
         subgroup %in% c("white", "black", "hispanic",
                         "econ_disadv", "total_enrollment")) |>
  mutate(pct = round(pct * 100, 1)) |>
  select(subgroup, n_students, pct) |>
  arrange(desc(n_students))

stopifnot(nrow(mobile_demo) > 0)
mobile_demo
#>           subgroup n_students   pct
#> 1 total_enrollment      47366 100.0
#> 2      econ_disadv      34569  73.0
#> 3            black      24070  50.8
#> 4            white      17525  37.0
#> 5         hispanic       3262   6.9

14. Charter schools are Alabama’s smallest districts

Alabama’s charter sector is small but growing. The smallest 10 districts by enrollment are dominated by charter and specialty schools, with Freedom Prep Academy enrolling just 36 students.

smallest <- enr_2025 |>
  filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
  arrange(n_students) |>
  head(10) |>
  select(district_name, n_students)

stopifnot(nrow(smallest) > 0)
smallest
#>                                    district_name n_students
#> 1                           Freedom Prep Academy         36
#> 2                 Alabama Aerospace and Aviation        146
#> 3  Floretta P. Carson Visual and Performing Arts        193
#> 4                     Covenant Academy of Mobile        302
#> 5                  Magic City Acceptance Academy        307
#> 6                    Breakthrough Charter School        359
#> 7                     Empower Schools of Alabama        375
#> 8                                    Linden City        380
#> 9                                   LIFE Academy        497
#> 10                                   Legacy Prep        501
Smallest districts
Smallest districts

(source)


15. Middle school enrollment is shrinking while elementary grows

Elementary (K-5) and high school (9-12) enrollment both grew since 2021, but middle school (6-8) dropped from 173,548 to 163,076 – a loss of over 10,000 students.

grade_bands <- enr |>
  filter(is_state, subgroup == "total_enrollment",
         grade_level %in% c("K", "01", "02", "03", "04", "05",
                            "06", "07", "08",
                            "09", "10", "11", "12")) |>
  mutate(band = case_when(
    grade_level %in% c("K", "01", "02", "03", "04", "05") ~ "Elementary (K-5)",
    grade_level %in% c("06", "07", "08") ~ "Middle (6-8)",
    grade_level %in% c("09", "10", "11", "12") ~ "High School (9-12)"
  )) |>
  group_by(end_year, band) |>
  summarize(n_students = sum(n_students), .groups = "drop")

stopifnot(nrow(grade_bands) > 0)
grade_bands
#>    end_year               band n_students
#>  1     2021   Elementary (K-5)     327017
#>  2     2021 High School (9-12)     211750
#>  3     2021       Middle (6-8)     173548
#>  4     2022   Elementary (K-5)     329002
#>  5     2022 High School (9-12)     212460
#>  6     2022       Middle (6-8)     171009
#>  7     2023   Elementary (K-5)     330453
#>  8     2023 High School (9-12)     213639
#>  9     2023       Middle (6-8)     167263
#> 10     2024   Elementary (K-5)     332704
#> 11     2024 High School (9-12)     216257
#> 12     2024       Middle (6-8)     165208
#> 13     2025   Elementary (K-5)     333794
#> 14     2025 High School (9-12)     216182
#> 15     2025       Middle (6-8)     163076
Grade band trends
Grade band trends

(source)