Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsTo run RSpec in parallel on GitHub Actions, split the suite into deterministic, non-overlapping shards and run each shard as a separate job in a matrix. Start with a small number of shards, keep Ruby and service setup identical in every job, and increase concurrency only while the slowest shard—not setup time, queueing, or shared-service contention—continues to improve. The workflow below shows a four-shard starting point and a simple file-based allocator; uneven suites usually need timing-aware balancing.
How parallel RSpec jobs reduce CI time
A GitHub Actions matrix expands one job definition into several jobs. With RSpec, each job should receive its own share of the suite, so the jobs run different specs at the same time rather than repeating the full suite.
The total wall-clock time is roughly the duration of the slowest shard, plus each job’s setup and any time spent waiting for a runner. Four jobs do not make a run four times faster by default: if one shard takes much longer than the other three, the short shards finish early while the slow one holds up the result. More jobs can also repeat checkout, dependency setup, and database preparation.
GitHub’s current workflow syntax documentation says a matrix can create up to 256 jobs in one workflow run and, by default, GitHub maximizes parallel jobs subject to runner availability. That is a platform ceiling, not a recommended RSpec shard count. Use max-parallel to cap simultaneous jobs for runner capacity, service limits, or budget.
#1 Best Overall
Choose a shard count that fits the suite
Begin with a small matrix—four shards is a reasonable configuration to measure, not a universal optimum. Record the duration of each job, including setup, then adjust the shard count based on the actual bottleneck. The useful target is balanced shard durations, not the largest possible matrix.
- When one shard dominates: rebalance the file assignment before adding more concurrency.
- When setup dominates: extra shards may repeat enough setup work to erase the wall-clock gain.
- When shared services are saturated: lower
max-parallelor reduce the shard count. Concurrent tests can compete for database, memory, or other limited resources. - When runners are available and shards are balanced: try a modest increase, then compare wall-clock duration and total runner minutes.
There is no universal speedup figure: results depend on suite timing, runner type and availability, setup cost, service contention, and concurrency limits.
Set up a four-shard workflow
This example sorts spec paths and assigns them round-robin to four jobs. The assignment is deterministic as long as the set of paths is unchanged, and each spec file is assigned to exactly one shard. It is a simple starting allocator, not a timing-aware one: if a few files take much longer than others, use the balancing approach in the next section.
name: RSpec
on: [push, pull_request]
jobs:
rspec:
strategy:
fail-fast: false
max-parallel: 4
matrix:
shard: [0, 1, 2, 3]
runs-on: ubuntu-latest
env:
SHARD_COUNT: 4
SHARD_INDEX: ${{ matrix.shard }}
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Run this shard
shell: bash
run: |
set -euo pipefail
mapfile -t files < <(find spec -type f -name '*_spec.rb' | LC_ALL=C sort)
shard_files=()
for i in "${!files[@]}"; do
if (( i % SHARD_COUNT == SHARD_INDEX )); then
shard_files+=("${files[$i]}")
fi
done
if (( ${#shard_files[@]} == 0 )); then
echo "Shard $SHARD_INDEX has no spec files" >&2
exit 1
fi
bundle exec rspec --order random "${shard_files[@]}"
Adjust the find path and filename pattern if the repository stores specs elsewhere or uses a different naming convention. Every matrix job uses the same Ruby setup and Bundler cache configuration; add the same database, service, environment, and migration steps to every job if the suite needs them. Do not set SPEC_FILES to a shard number and pass it to RSpec as if it were a file path: the workflow must translate each shard index into actual spec paths or example IDs.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Balance shards for a slow or uneven suite
Round-robin assignment gives a reproducible split, but it does not know whether one file takes a fraction of a second or several minutes. Measure file durations and create a manifest that groups files so each shard has a similar estimated total runtime. Keep that manifest under version control or generate it deterministically from recorded timings, and have each matrix job read only its assigned paths.
| Approach | How it assigns work | Trade-off |
|---|---|---|
| Sorted round-robin files | Cycles through a stable sorted list of spec files, assigning each file to one shard. | Simple and reproducible, but can be poorly balanced when file durations vary. |
| Timing-aware file manifest | Uses observed file durations to group work into shards with similar estimated runtimes. | Can improve balance for uneven suites; requires maintaining timing data and validating the allocator. |
| Example-level splitting | Assigns individual examples rather than whole files. | Allows finer-grained splits, but requires reliable example identification and care with tests that share state or depend on order. |
Prefer file-level splitting first unless a small number of oversized files prevents a useful balance. Whether splitting at example level is safe depends on how the suite is written; tests that mutate global state or rely on execution order need particular scrutiny.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Keep failures reproducible and diagnosable
Parallelism changes which examples run together, so a failure that was hidden in a serial run may surface—or a cross-file interaction may disappear when the files land in different shards. Preserve each job’s full RSpec output, including its shard identity and the random seed printed by RSpec. Keep the shard manifest with the run’s artifacts or otherwise retain the exact assignment, so a failure can be rerun against the same paths.
- Run the unsharded suite once and record its duration, failures, and RSpec seed.
- Create a deterministic assignment in which every intended spec appears once and only once.
- Run all shards with the same Ruby, Bundler, database, and service setup.
- Retain logs, the seed, and the shard manifest so the failing shard can be repeated under the same conditions.
- If a failure depends on interactions or ordering, use RSpec’s
--bisectoption to isolate a minimal set of examples that reproduces it. - Rebalance from measured durations before increasing concurrency blindly.
RSpec supports file paths and patterns, order controls including defined, rand/random, and recently-modified, and a seed for reproducing randomized order. Keep the printed seed with the failing shard’s assignment; a seed alone does not recreate a run if the shard contents or environment have changed.
Best Value
Choose whether matrix failures should cancel other shards
GitHub Actions sets matrix fail-fast to true by default. With that setting, a failing matrix job cancels in-progress and queued jobs. Set fail-fast: false, as in the example, when you want the complete set of shard results to diagnose failures in one run. Keep fail-fast enabled when an early failure should stop expensive remaining work and the other shard results add little value.
Matrix sharding uses GitHub Actions’ built-in job expansion and is straightforward to operate. Timing-aware external sharding can balance an uneven suite more effectively, but adds a tool and another allocator whose assignment must be verified. Whichever approach you use, check that no spec is omitted or duplicated: duplicate work wastes runner time, while omitted work creates a misleadingly green result.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

