A deep dive into Ruby Hash memory usage across versions, tracing the evolution from Ruby 2.3 to 4.1. Covers the history of ar_table (array table), Variable Width Allocation, and the lower-byte hashcode optimization. The author explains current work to shrink st_table by 8 bytes via struct packing (moving entries_start into a 1-byte field), enabling mutable hashes to fit in 64B GC slots. Also covers frozen hash optimization already merged, and an in-progress patch for dynamic ar_table sizes that could bring small hash memory usage much closer to theoretical minimums. Includes practical advice: prefer Struct or plain Ruby objects over Hash when structure is known.
Table of contents
Measuring Memory UsageOpen AddressingArray TablesLower Byte HashcodeVariable Width AllocationGoing SmallerKnock-On EffectsData LocalityImmutabilityStruct PackingDynamic AR Table SizesTakeaways99 Impressions