---
title: "Caching Without Marshal Part 1: Marshal from the Inside Out"
description: "Rails caching commonly relies on Ruby’s Marshal serialization, which can encode complex objects but also embeds their class names in cache entries. Shopify describes an incident in which a beta-flag refactor changed classes while old and new code overlapped during deployment; old code then failed on cached instances containing unfamiliar class names and methods, despite passing CI. The article examines Marshal through Ruby’s marshal.c implementation, covering atomic and composite types, instance variables, object references, circularity via TYPE_LINK, and core-type subclasses via TYPE_UCLASS. It presents MessagePack as a more compact, stricter, and controllable alternative intended to make caching safer by default, while deferring the cache migration and implementation details to the series’ next part."
---

# Caching Without Marshal Part 1: Marshal from the Inside Out

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

**Type:** Explainer

## Summary

Rails caching commonly relies on Ruby’s Marshal serialization, which can encode complex objects but also embeds their class names in cache entries. Shopify describes an incident in which a beta-flag refactor changed classes while old and new code overlapped during deployment; old code then failed on cached instances containing unfamiliar class names and methods, despite passing CI. The article examines Marshal through Ruby’s marshal.c implementation, covering atomic and composite types, instance variables, object references, circularity via TYPE\_LINK, and core-type subclasses via TYPE\_UCLASS. It presents MessagePack as a more compact, stricter, and controllable alternative intended to make caching safer by default, while deferring the cache migration and implementation details to the series’ next part.

## Context

Shopify’s incident showed that Marshal-serialized cache entries can outlive a deployment and contain class names from newly deployed code. During the rollout, older code encountered beta-flag instances using refactored classes and failed, even though the change passed CI and was not itself incorrect. Reducing cache usage or slowing code changes were considered unacceptable mitigations.

## Approach / What changed

The article investigates Marshal’s behavior using Ruby’s marshal.c implementation and examples of serialized records, self-referential arrays, and subclasses of core types. It proposes replacing Marshal with MessagePack, a more compact binary format with stricter typing and greater control, and identifies circularity and core-type subclasses as features a replacement must address.

## Takeaways

- Marshal serializes an object’s class along with its data, so a deployment can leave older processes unable to read cache entries created with newly refactored classes.
- Rails cache backends share read and write operations and use Marshal.dump and Marshal.load to serialize cached data, including data stored through Memcached, file, memory, or Redis backends.
- Marshal represents circular references with TYPE\_LINK and core-type subclasses with TYPE\_UCLASS; a replacement must account for both behaviors to preserve supported object structures.

**Tags:** [Architecture](https://yomu.fyi/topic/architecture), [Caching](https://yomu.fyi/topic/caching), [Reliability](https://yomu.fyi/topic/reliability)

- Source: [Shopify](https://shopify.engineering/caching-without-marshal-part-one)
- Source URL: https://shopify.engineering/caching-without-marshal-part-one
- Ingested by Yomu: 2026-08-30T13:37:43.306Z

[Read original post](https://shopify.engineering/caching-without-marshal-part-one)
