Rails at Scale: Patterns That Keep Shopify’s Monolith Running
Shopify’s core application is one of the largest Rails monoliths in production, supporting a global platform with millions of merchants. While the framework’s convention-over-configuration philosophy makes onboarding straightforward, operating at Shopify’s scale requires going beyond those conventions. Over time, the engineering organization has developed a set of internal patterns and tooling to keep that codebase maintainable and to support thousands of developers working across hundreds of projects.
These are the key infrastructure patterns and architectural decisions that make that possible.
Dev: A Unified Developer Experience
One of the first things new Shopify developers encounter is dev, a command-line tool that standardizes workflows across all projects. Historically, each project had its own setup instructions, dependency management, and testing commands. dev was created to replace that fragmentation with a consistent interface.
The tool automates dependency installation and project bootstrapping on macOS—from system-level tools like XCode to database migrations via bin/rails db:migrate. It also handles environment variables, so developers no longer spend days hunting down configuration values before connecting disparate services. Integrations with interconnected services can be enabled or disabled through dev, rather than by manually editing environment configuration.
Even command aliases are standardized. Long, tool-specific commands are replaced with predictable shortcuts that work the same way across repos and programming languages. For example, opening a pull request is simply dev open pr instead of relying on external tooling like the Hub package. This consistency across development environments reduces the debugging issues that arise from subtle local differences. While tools like chruby, bundler, and homebrew handle lower-level dependencies, dev builds on them to provide a single, repeatable setup process.
Podded Architecture: Scaling by Shop
Shopify Core uses a podded architecture, which is an extension of the shard database pattern implemented in Rails in collaboration with GitHub. The database is split into subsets, or pods, each containing a distinct group of shops. Every pod runs the application independently with its own database and full infrastructure—including provisioning, deployment, load balancers, caching, and servers. If one pod goes down temporarily, traffic can be served from the others without interruption.
The key insight is that Shopify services merchants by looking at data in the context of a single store. That means everything—incoming HTTP requests, background jobs, and asynchronous events—can be routed by shop. Every table in a podded database is tied to a shop, which keeps data isolated between merchants and enables horizontal scaling of a monolithic Rails application without fragmenting it into microservices.
Monoliths with Domain Boundaries
Shopify intentionally keeps a monolith, but it is not an unstructured one. The codebase is divided into components along domain lines—what the team calls domain-driven design adapted to Shopify’s reality.
These domains communicate through public or internal APIs, but the underlying database remains a single, shared resource. Because every table is linked to a shop—a necessity of the podding strategy—the Shop model becomes a de facto part of nearly every domain. Instantiating a model from outside its component triggers a warning, but crossing that boundary is a pragmatic requirement of the architecture.
Another deliberate choice: foreign keys are not enforced at the database layer. Instead, model-level associations in ActiveRecord handle relationship integrity.
Migrations are used only for short-term schema changes. Running the full historical migration chain would take far too long, so on a roughly monthly basis, the team merges migrations into a single raw SQL file that represents the complete database schema. This avoids the overhead of replaying up to a decade of incremental migration files and keeps the schema definition tractable at scale—a trade-off documented in discussions around using structure.sql formats in Rails applications.
Keeping Code Quality High While Scaling Fast
With hiring on track to add over 2,000 people in a year, Shopify relies on automated safeguards rather than hope to keep code quality consistent. The company has built a range of internal gems, generators, and systems to catch repetitive mistakes before they become problems.
A Translation Pipeline That Removes Developers From the Loop
One of the most used internal tools is the translation platform, which handles the creation, translation, and publication of strings directly through git. In smaller setups, marketing teams hand over translated files or push them through a CRM—an approach that doesn't scale for a globally distributed application. Shopify's system lets developers push English strings and move on; the text is automatically sent to a third-party service where translators work asynchronously, and the finished translations are committed back into the repo with no developer input required. The project began as a Shopify hack day idea in 2017.
Standardized Maintenance and Event Schemas
For background work, Shopify built a maintenance task system on top of Rails' Active Job library, adapted to its podded infrastructure. It functions as a Rails engine for queuing and managing maintenance tasks, and Shopify has released it as an open source project. The monolith also includes extensive automated tests that flag wrong approaches, plus limits that prevent the system from being overloaded when jobs are spawned.
Another key standardization effort is Monorail, a system inspired by Airbnb Jitney that enforces schemas for widely used events. Monorail creates contracts between Kafka producers and consumers by defining the structure of data sent through JSON. This delivers two main benefits:
- Unstructured events with differing structures would otherwise land in the same data warehouse table. Monorail creates a contract between developers and data scientists via schemas, and any changes must go through versioning.
- The system helps prevent Personal Identifiable Information (PII) leaks. Schemas are reviewed to annotate PII fields so they can be automatically scrubbed through obfuscation or tokenization.
These systems—translation tooling, maintenance tasks, and schema enforcement—are part of a broader effort to let developers focus on shipping features instead of wrestling with infrastructure concerns.



