# Speed up CI with parallel ExUnit partitions

Running your full test suite sequentially in CI is wasted time. ExUnit has built-in support for partitioning — split your suite into N slices and run them in parallel, each in its own process.

```bash
# ❌ Sequential — all tests in one process, one after another
mix test

# ✅ Parallel — 6 partitions running at the same time
for i in 1 2 3 4 5 6; do \
  MIX_TEST_PARTITION=$$i \
  MIX_TEST_DB_SUFFIX=ci$$i \
  MIX_BUILD_PATH=_build/test_part$$i \
  mix test --partitions 6 --max-failures 5 \
    > log/ci/test_part$$i.log 2>&1 & \
PIDS="$$PIDS $$!"; \
done; \
for pid in $$PIDS; do wait $$pid || PART_EXIT=1; done
```

ExUnit hashes each test file name to assign it to a partition. The assignment is deterministic — the same file always lands in the same partition across runs, so failures are reproducible without re-running the full suite.

Two isolation pieces are required for this to work correctly.

**Build path isolation.** Without `MIX_BUILD_PATH=_build/test_part$i`, all six parallel compilations write to the same `_build/test` directory and race each other. Giving each partition its own build path eliminates the race.

**Database isolation.** Ecto's SQL sandbox is designed for concurrent tests within a single process, not across operating system processes. If two partitions share the same database, they can see or corrupt each other's data. The fix is to give each partition its own database:

```elixir
# config/test.exs
partition = System.get_env("MIX_TEST_PARTITION") || "0"
suffix = System.get_env("MIX_TEST_DB_SUFFIX") || partition

config :my_app, MyApp.Repo,
  database: "my_app_test#{suffix}"
```

`MIX_TEST_DB_SUFFIX` is a project-level convention, not something built into ExUnit. You set it in the shell and read it in config. With six partitions, you get six databases: `my_app_test1` through `my_app_test6`. Run `mix ecto.create` and `mix ecto.migrate` for each before the first CI run.

`MIX_TEST_PARTITION` is required whenever `--partitions N` is set. If you omit it, `mix test` refuses to run and exits with an error. Setting `--partitions 1` with `MIX_TEST_PARTITION=1` is useful for running a single file through the partition machinery while debugging:

```bash
MIX_TEST_PARTITION=1 mix test --partitions 1 test/my_module_test.exs
```

[`mix test --partitions` docs](https://hexdocs.pm/mix/Mix.Tasks.Test.html#module-operating-system-process-partitioning)


---

Created by: almirsarajcic
Date: May 27, 2026
URL: https://elixirdrops.net/d/9yfNCu2j
