AL+

Language: RO (română) EN (English)

Email us: paul@alplustech.com

Looking back at the week of 25–31 December 2024

Ruby 3.4 makes collector choice a separate deployment decision

Ruby 3.4 separates runtime upgrades from garbage collector selection. Keep build flags, library choice and rollback explicit before changing production.

Citiți articolul în română

A Ruby upgrade and a garbage collector change should be separate decisions. Ruby 3.4 made that separation more visible by introducing modular garbage collection. For an application owner, the useful consequence is control over which change gets evaluated and released. The feature alone supplies no reason to replace the default collector or promise a faster service.

Looking back from November 2026, the Christmas 2024 release is best understood as an additional operational choice. The Ruby 3.4.0 announcement, dated 25 December, documents a build option that permits dynamically loaded collector implementations, followed by runtime library selection. Those are separate conditions. Installing a runtime carrying the version number does not establish how someone built it or which collector a process loads.

Three decisions hidden in one upgrade ticket

The first decision is the runtime version. It brings language and library changes that deserve their own compatibility assessment. A team can evaluate that upgrade with the default collector and learn whether the application still behaves as intended. Introducing a different collector at the same moment would make any change in behavior harder to attribute.

The second decision is the runtime build. The release announcement names --with-modular-gc as the configuration flag that enables modular GC. A supplied binary therefore needs a known build configuration. A container tag, package label or version string is an incomplete record of the artifact that will run the application.

The third decision is collector-library selection. The same announcement identifies RUBY_GC_LIBRARY as the environment variable used to load a collector library. It also describes a library build of the default collector and an experimental MMTk-based option. Experimental availability is evidence of a capability, not evidence that a specific application will benefit from adopting it.

Give the comparison a business question

Imagine an application whose owners are concerned about delayed order confirmations during busy periods. Before proposing a collector change, the team should identify whether allocation and collection plausibly contribute to that delay. A slow external payment response would lead to a different investigation. This is an illustrative diagnostic question, not an account of an AL+ project.

The proposed comparison should preserve the runtime version, application revision and workload while changing collector selection. Record the request mix and concurrency, then examine response-time distributions, memory pressure and failures together. A lower average alone would be a weak reason to accept a change if long waits or process failures became more frequent.

Memory also belongs in the commercial decision. An implementation that appears attractive under generous memory limits may behave differently within the deployed service's actual allowance. The useful question is whether the proposed configuration improves the service under its operating constraints. Benchmark leadership in an unrelated workload cannot answer that question.

No benchmark was run for this article. These are proposed acceptance conditions, and they intentionally contain no target improvement. A target should come from the application's needs and baseline. An owner who cannot explain the problem being addressed has little basis for paying the operational cost of another collector option.

Rollback has more than one destination

Separating the changes creates a clearer recovery plan. One destination is the new runtime with the known default collector configuration. Another is the previous known-good application and runtime artifact. The first helps isolate a collector issue; the second remains relevant if the runtime upgrade itself causes trouble.

Keep each destination reproducible. The collector library, its location and the process environment belong with the release record. Restoring an application image while leaving an unexpected library-selection variable in deployment settings would not recreate the earlier configuration. A rollback description should say which artifact and settings will run after recovery.

Do not assume that changing an environment variable alters an already running process. Plan replacement of the relevant processes and verify what they start with. The exact mechanics depend on the deployment system. A tested recovery path should use that system's real artifact and configuration handling rather than a generic command copied from an article.

The Ruby 3.4.1 announcement, also dated 25 December 2024, says it fixes the version description. It does not describe a GC fix. That distinction matters when reconstructing a release: a nearby patch number should not become an invented explanation for collector behavior.

Keeping the default is a complete decision

The strongest objection to this exercise is practical. Many teams have no evidence that their collector is a problem, and no capacity to maintain a second configuration. Retaining the default can be the more responsible choice. It preserves attention for database queries, application allocation patterns or other work whose benefit is easier to establish.

An alternative collector becomes worth investigating when a concrete constraint and an achievable comparison justify the effort. Even then, the evaluation includes operational complexity and recovery, alongside runtime behavior. A small latency change may not repay another library artifact and another failure mode for the on-call maintainer.

This retrospective uses the original release announcements to describe the December 2024 feature. It does not import later documentation as proof of the original implementation, and it does not recommend deploying an old patch release today. Selecting a currently suitable supported version remains a separate maintenance decision.

For custom software development, write two acceptance decisions: whether to adopt the runtime and whether to adopt a different collector. Approve the second only when the application-specific evidence supports it. If the default already meets the service's needs, closing the collector investigation is a useful engineering outcome.