---
title: "Rails"
description: "7 posts about Rails, summarised, each linking to the original."
---

# Rails
> 7 posts about Rails, summarised, each linking to the original.

## Articles

### [Static Typing for Ruby](https://yomu.fyi/post/static-typing-for-ruby.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Nov 19, 2020

Shopify’s Ruby monolith spans 37,000 files, 622,000 methods, and more than 2,000,000 calls, making fast feedback and stability difficult despite rigorous reviews and 150,000 automated tests. Sorbet was selected after the team evaluated requirements for gradual typing, speed, and support for Ruby and Rails features including metaprogramming, overloading, and class reopening. Its RBI files represent constructs it cannot infer, while per-file sigils allow adoption to progress without blocking development, and SorbetMetrics tracks sigils, typed calls, and method signatures. Shopify treats typing as a product, combining CI enforcement, developer support, surveys, and interviews to guide rollout and measure sentiment. The excerpt reports 80% of monolith files, including tests, at typed: true or higher, with almost half of calls and methods covered and type checking under 15 seconds on developer machines.


### [How to Introduce Composite Primary Keys in Rails](https://yomu.fyi/post/how-to-introduce-composite-primary-keys-in-rails.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Oct 29, 2020

Shopify addressed inefficient data access in its multi-tenant Rails application, where auto-incrementing primary keys interleaved records from many shops even though queries usually targeted one shop. InnoDB stores rows in B+ trees and loads pages into a buffer pool, so the team changed orders and other suitable tables to composite primary keys such as \[shop\_id, order\_id\] while keeping an auto-incrementing id secondary key and configuring Active Record to use id. Supporting Ghostferry, migration tooling, and data extraction systems also had to accommodate the schema change, with unique secondary constraints avoided in some cases because LHM migrations could deadlock. On the most queried table, common queries improved 5–6x, median buffer pool reads fell from 1.8 to 1.2, and elapsed database time dropped roughly one hour per day per shard, while inserts became about 10x slower.


### [Enforcing Modularity in Rails Apps with Packwerk](https://yomu.fyi/post/enforcing-modularity-in-rails-apps-with-packwerk.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Sep 23, 2020

Large Rails monoliths can develop high coupling, low cohesion, cross-component calls, shared Active Record models, and classes that know too much because Ruby and Rails provide limited boundary enforcement. Shopify created Packwerk, an open-source static analysis tool that groups Ruby files into packages and enforces dependency and privacy boundaries, including controlled public APIs for constants. It reports the violation type and location with actionable next steps, integrates with CI, and can run locally; installation begins by adding the gem and running packwerk init. Because Ruby static analysis is complex, Packwerk ignores constants that are not autoloaded, reducing false positives at the cost of false negatives. The excerpt says it runs in six Shopify Rails applications, with 48 packages and 30 boundary enforcements in the core codebase, while adoption also prompted work on dependency inversion.


### [Under Deconstruction: The State of Shopify’s Monolith](https://yomu.fyi/post/under-deconstruction-the-state-of-shopify-s-monolith.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Sep 16, 2020

Shopify describes the ongoing effort to modularize its core Ruby on Rails monolith, which contains more than 2.8 million lines of Ruby and 500,000 commits. The initiative organizes code into independently owned components intended to narrow developer focus, reduce affected test suites, preserve contracts, and clarify operational ownership, while recognizing that large-scale refactoring is also a people problem. The work has already improved exception triage, distributed codebase chores, and design awareness, while its current practices emphasize grassroots participation, tooling, targeted reviews, and a holistic architectural view. Packwerk restricts dependencies for about a third of the 37 main-monolith components. Shopify is pursuing a cleaner dependency graph, componentized Rails applications by default, and isolated component tests, while reserving service extraction for cases such as storefront rendering and credit-card vaulting.


### [How to Track State with Type 2 Dimensional Models](https://yomu.fyi/post/how-to-track-state-with-type-2-dimensional-models.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Aug 27, 2020

Application databases often retain only current values in Type 1 dimensions, limiting analysis of historical settings such as feature adoption, retention, and switching behavior. The post explains Type 2 dimensional models through Shopify’s need to track users’ admin languages over time, contrasting application-model changes, scheduled database snapshots, and event logging. Its selected implementation uses Rails after\_commit callbacks to send created or updated records to Kafka, then transforms that event history into records with valid\_from, valid\_to, and is\_current fields using ETL recipes involving PySpark and dbt. The approach provides the required granularity but can miss changes or events, requires delete handling and data-quality checks, and is presented as an iterative solution; MySQL binlogs are described as a more reliable future source.


### [How Shopify Reduced Storefront Response Times with a Rewrite](https://yomu.fyi/post/how-shopify-reduced-storefront-response-times-with-a-rewrite.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Aug 20, 2020

Shopify rewrote the server-side Storefront Renderer, which loads Liquid themes and storefront data before returning HTML, because the legacy Rails-monolith implementation had developed stricter performance demands and rising time-to-first-byte as traffic grew. The new single-purpose application separates storefront traffic from checkout, admin, and API traffic, uses active-active replication with dedicated read replicas, and adds mechanisms for high-load resilience. During migration, a Ruby verifier compares status codes, headers, and bodies from both implementations, while a custom Lua module on OpenResty samples production traffic and routes requests based on verification results. The rollout had reached more than 90% feature parity, and the new implementation averaged 4x faster server response times, with ongoing work aimed at full parity and retiring the legacy system.


### [Media at Scale: Callbacks vs pipelines](https://yomu.fyi/post/media-at-scale-callbacks-vs-pipelines.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jul 9, 2020

Shopify’s Rails monolith needed to add native product videos and 3D models while continuing to support an image infrastructure containing more than 7 billion images. The design question was whether media creation should rely on Active Record callbacks or an explicit pipeline, with transactions protecting interdependent database writes. Callbacks were quick for simple cases, but adding media-specific behavior such as video thumbnails spread conditionals across models and made lifecycle ordering difficult to follow and debug. The pipeline design routes requests through a single Product Create Media Service and media handlers, each organized into before\_transaction, during\_transaction, and after\_transaction steps, while confining logic to one media type. This structure separates concerns, controls creation order, limits model access, and makes implementation details easier to understand and maintain as the feature grows.
