Plugin histories

Spork: the Rails test server, and what replaced it

Plugin histories · · Published 2026-10-24

A chrome mechanical stopwatch on a white background
A mechanical stopwatch: Spork existed to save seconds on every test run.

Spork was the answer to a complaint every Rails developer of 2010 knew by heart: running a single spec took longer to boot the application than to run the test. It is no longer maintained, but the idea it popularised lives on in Rails itself.

What Spork did

Spork was a small server that loaded your Rails environment once, then forked a fresh copy of that preloaded process for each test run. Test runners connected to it over DRb, Ruby's distributed object protocol: RSpec and Cucumber both had options to send a run to a DRb server instead of booting the application themselves. Because fork copies the parent process, every run started from a clean, already-loaded state in a fraction of the usual time.

Configuration lived in spec_helper.rb (or Cucumber's env.rb), split into two blocks:

require "spork"

Spork.prefork do
  # Loaded once, when the Spork server starts
  ENV["RAILS_ENV"] ||= "test"
  require File.expand_path("../../config/environment", __FILE__)
  require "rspec/rails"
end

Spork.each_run do
  # Run in each forked process, before the tests
  FactoryGirl.reload
end

Everything in prefork was loaded once; each_run ran in each fork. The art of using Spork lay in keeping application code out of the prefork phase. If a gem or initializer loaded your models while Rails booted (route definitions referencing controllers, or authentication plugins touching the user model were common culprits), those classes were frozen in the server's memory, and your edits did not show up in tests until you restarted Spork. Much of Spork's documentation and many blog posts of the time were about hunting down these early loads.

Spork was often paired with Guard, which watched files and ran the relevant specs automatically, through the guard-spork plugin.

Releases and status

Spork dates from 2009, the Rails 2.3 years. According to RubyGems.org, its last stable release is 0.9.2, from May 2012. A 1.0 line moved Rails-specific code into a separate spork-rails gem; it reached 1.0.0rc4 in September 2013, together with spork-rails 4.0.0, and no final 1.0 was ever published. The project's repository, under the sporkrb organisation on GitHub, has seen no release since.

In short: Spork is unmaintained, targets Ruby and Rails versions that are long out of support, and should not be added to a current application. If you find it in an old Gemfile, remove it along with its prefork/each_run blocks when you upgrade.

Why it faded

Three things made Spork unnecessary:

  1. Rails got its own preloader. Spring, maintained under the Rails organisation, appeared in late 2012 and was included in newly generated applications from Rails 4.1. It applies the same fork-from-a-preloaded-process idea to all bin/rails and bin/rake commands, needs no changes to your test helpers, and watches files so that it restarts when configuration changes.
  2. Boot times improved. Bootsnap, included in new applications since Rails 5.2, caches load-path lookups and compiled Ruby, which cuts boot time substantially without any long-running process. The Zeitwerk autoloader, the only autoloader since Rails 7.0, loads code lazily in development and test, so less work happens at boot.
  3. Suites got parallel. Rails 6.0 added built-in parallel testing, so the time saved on boot matters less than the time saved by spreading tests across CPU cores.

Spring itself has become optional: since Rails 7.0, new applications no longer include it by default, as Bootsnap and faster hardware made the preloader's benefits smaller than the confusion caused by stale processes. It is still released (4.7.0 in June 2026) and you can add it if your application boots slowly.

What to use today

GoalTool
Faster boot for every commandBootsnap (already in new apps)
Keep the app preloaded between test runsSpring, optionally with spring-commands-rspec
Faster full suiteRails parallel testing, or a parallel runner for RSpec
Run tests on file changeGuard with guard-rspec or guard-minitest

If your application still boots slowly with Bootsnap, profile the boot before adding a preloader: an initializer that makes a network call or eagerly loads a large gem is a more common cause than Rails itself. bin/rails runner 'puts 1' timed with and without suspect gems is a simple first measurement.

Migrating an old Spork setup

  1. Remove spork, spork-rails and guard-spork from the Gemfile.
  2. Collapse the Spork.prefork and Spork.each_run blocks in spec_helper.rb into ordinary top-level code, or regenerate the helpers with rails generate rspec:install and port your customisations.
  3. Remove --drb from .rspec and any Cucumber profile.
  4. Replace FactoryGirl.reload calls with nothing; FactoryBot definitions are loaded once per run.

For the wider picture, see our guide to testing Rails applications, and the plugin histories for other tools of the same era.