Skip to content
Latchkey

How to Install and Run Pandas in CI Reliably

Pandas installs from a wheel in seconds on mainstream platforms - the CI pain is usually a missing wheel on a new Python, or an out-of-memory kill on a large DataFrame job.

Pandas depends on NumPy and ships manylinux wheels, so installs are normally trivial. Two things bite in CI: a too-new Python or musl image with no wheel (forcing a slow source build), and memory pressure when a job loads a large dataset into a DataFrame and gets OOM-killed (exit 137).

Why it fails in CI

Install-time, the failure mirrors NumPy: no wheel for the interpreter means a source build that needs a compiler and is slow. Run-time, Pandas holds entire DataFrames in memory; a big read on a small runner triggers the kernel OOM killer and the step dies with exit 137.

  • No matching distribution found for pandas on a brand-new Python or Alpine.
  • Failed building wheel for pandas when compiling its Cython extensions from source.
  • Step killed with exit 137 - the kernel OOM-killed the process on a large DataFrame.

Install it reliably

Keep the wheel by using a glibc base image and a Python version Pandas ships wheels for, and force-binary so a missing wheel fails fast. For memory, give the job a bigger runner or stream data in chunks rather than loading it all at once.

Terminal
# Force the prebuilt wheel
pip install --only-binary=:all: pandas

# Read large data in chunks to bound memory
# for chunk in pd.read_csv('big.csv', chunksize=100_000): process(chunk)

Cache & speed

Cache ~/.cache/pip so the Pandas + NumPy wheels are reused across runs. For data-heavy test jobs, prefer a runner sized to the dataset over fighting OOM with retries.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: pip-pandas-${{ hashFiles('requirements*.txt') }}

Common errors

ErrorCauseFix
No matching distribution found for pandasNo wheel for this Python/muslPin a supported Python; use glibc
Failed building wheel for pandasSource build (Cython)Force --only-binary
Exit 137 on a large readOOM-killedBigger runner or chunked reads
MemoryErrorDataFrame too largeStream/chunk, use dtypes, or downsample

Key takeaways

  • Pandas has wheels - keep the wheel path with glibc + a supported Python.
  • Exit 137 means OOM: size the runner or chunk the data.
  • Force --only-binary so a missing wheel fails fast.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →