---
title: "Optimizing Ruby’s Memory Layout: Variable Width Allocation"
description: "CRuby’s original garbage collector stores most Ruby objects in fixed 40-byte RVALUE slots, leaving differently sized data partly unused or forcing additional allocations through malloc. Shopify’s Variable Width Allocation project adds dynamic-sized allocation APIs and five fixed-size pools—40, 80, 160, 320, and 640 bytes—while increasing heap pages from 16 KB to 64 KB. The design targets cache locality, malloc overhead, memory utilization, and future garbage-collector experimentation; a new GC.stat_heap API reports size-pool statistics, and an escape hatch can disable the feature at build time on Ruby 3.2. Benchmarks on development Ruby 3.2.0 showed gains in most workloads, including 9.8% for psych-load, 5.3% for hexapdf, and 2.1% for railsbench, while mail was 1.7% slower."
---

# Optimizing Ruby’s Memory Layout: Variable Width Allocation

[Shopify](https://yomu.fyi/company/shopify) · 2023-10-18 · Dec 25, 2022

**Type:** Explainer

## Summary

CRuby’s original garbage collector stores most Ruby objects in fixed 40-byte RVALUE slots, leaving differently sized data partly unused or forcing additional allocations through malloc. Shopify’s Variable Width Allocation project adds dynamic-sized allocation APIs and five fixed-size pools—40, 80, 160, 320, and 640 bytes—while increasing heap pages from 16 KB to 64 KB. The design targets cache locality, malloc overhead, memory utilization, and future garbage-collector experimentation; a new GC.stat\_heap API reports size-pool statistics, and an escape hatch can disable the feature at build time on Ruby 3.2. Benchmarks on development Ruby 3.2.0 showed gains in most workloads, including 9.8% for psych-load, 5.3% for hexapdf, and 2.1% for railsbench, while mail was 1.7% slower.

## Context

CRuby’s single 40-byte RVALUE allocation size simplifies garbage-collector management but can waste space, reduce cache utilization, require external malloc allocations, and limit experimentation with alternative garbage collectors.

## Approach / What changed

Variable Width Allocation introduces APIs for dynamically sized objects and fixed-size garbage-collector pools of 40, 80, 160, 320, and 640 bytes. The work also increases heap page size from 16 KB to 64 KB, adds GC.stat\_heap statistics, and provides a Ruby 3.2 build-time escape hatch for disabling the feature.

## Takeaways

- Ruby objects that exceed an RVALUE may store data externally through malloc, adding allocation overhead and potentially requiring pointers or allocator metadata.
- The size pools use powers-of-two multiples of the 40-byte RVALUE, a choice measured to provide approximately 75% average slot utilization and reduce frequent resizing.
- The benchmark suite used Ruby 3.2.0 development commit 80e56d1 with YJIT disabled; mail was the only listed workload slower with Variable Width Allocation enabled.

**Tags:** [Architecture](https://yomu.fyi/topic/architecture), [Performance](https://yomu.fyi/topic/performance)

- Source: [Shopify](https://shopify.engineering/ruby-variable-width-allocation)
- Source URL: https://shopify.engineering/ruby-variable-width-allocation
- Ingested by Yomu: 2026-08-30T13:36:44.755Z

[Read original post](https://shopify.engineering/ruby-variable-width-allocation)
