Aura Frames Scaled a Rails Monolith to 41M Requests Per Hour by Disabling Joins
The photo-sharing company handled holiday traffic spikes on a single application by using eight databases and a contrarian ActiveRecord setting that forced developers into simpler, faster queries.…
The photo-sharing company handled holiday traffic spikes on a single application by using eight databases and a contrarian ActiveRecord setting that forced developers into simpler, faster queries.
Aura Frames, a digital photo frame company, reports handling a peak load of 41 million requests per hour on its Ruby on Rails monolith. The figure, shared by engineer Andy Atkinson, was achieved not by migrating to microservices but by leaning into the monolith with a series of disciplined, and sometimes severe, architectural constraints.
At the center of Aura’s strategy is a counterintuitive database configuration. The company uses eight separate databases and a global setting, disable_joins: true, to prevent the Rails application from performing SQL joins. This approach challenges common scaling narratives and provides a playbook for maintaining performance under extreme, seasonal traffic.
One application, eight databases
Aura’s infrastructure runs on a single Rails application connected to eight MariaDB databases. Atkinson states this setup is designed to handle the company's highly seasonal traffic, where load during the holiday season can be orders of magnitude higher than the rest of the year. The databases are partitioned, not fully sharded, meaning developers must be explicit about which database a given query should run against.
This multi-database architecture is managed within the monolith itself. It requires careful routing of database queries to ensure data locality and prevent expensive cross-database calls. The primary goal is to distribute write load and keep individual database connections from becoming a bottleneck during peak traffic events.
Forcing simplicity with disable_joins
The most unconventional tactic is the application-wide disabling of SQL joins. By setting disable_joins: true in their database configuration, Aura’s engineers made it impossible for the application's Object-Relational Mapping (ORM) layer, ActiveRecord, to generate JOIN statements automatically. This is a deliberate constraint. It forces developers to write simpler queries and manually stitch data together in the application layer.
According to Atkinson, this prevents developers from accidentally shipping complex, multi-table joins that can degrade database performance under high load. Instead of a single complex query, a developer might issue two or three simple SELECT statements and combine the results in Ruby code. While this can increase application-level complexity, it makes database load far more predictable.
Aggressive caching and background processing
The database strategy did not operate in a vacuum. Atkinson’s post details a multi-layered caching approach using Redis and Fastly to serve as much traffic as possible without hitting the application servers or databases. This is a standard practice for high-traffic applications.
Additionally, Aura relies heavily on background job processing to defer non-critical work. This ensures that user-facing web requests remain fast by pushing heavier computation, like image processing or sending notifications, into asynchronous queues. This combination of caching, backgrounding, and disciplined database access forms the core of their scaling strategy.
What We'd Change
The disable_joins strategy is a powerful but blunt instrument. Its primary trade-off is developer ergonomics. ActiveRecord's associations and join capabilities are a core part of its productivity appeal. Forbidding them adds cognitive overhead and can slow down feature development, forcing engineers to write boilerplate code for data fetching that the framework would normally handle. This is a steep price to pay for performance predictability.
This playbook is also highly context-specific. Aura’s traffic pattern is characterized by massive, predictable spikes. The engineering team can prepare for the holiday season as a specific event. For a B2B SaaS with less predictable, more uniform traffic growth, the ongoing developer friction from this approach might outweigh the benefits. A more conventional approach of optimizing individual slow queries and vertical scaling might be more appropriate.
Finally, this strategy requires immense engineering discipline. A single developer bypassing the pattern could introduce a performance bottleneck. It works at Aura because the engineering culture supports it. Implementing this in a team without that shared context or discipline could lead to inconsistent code and hard-to-debug performance issues.
Landing
Aura Frames provides a compelling counter-narrative to the "scale with microservices" orthodoxy. The company’s success demonstrates that monolithic applications can handle extreme loads when paired with rigorous engineering discipline and a willingness to impose sharp constraints. The decision to disable joins is not a universal solution but a specific answer to a specific problem: making database performance predictable at all costs. It is a case study in choosing operational stability over developer convenience.
The investor read
Aura's strategy signals significant capital efficiency. By scaling their existing Rails monolith instead of pursuing a costly and time-consuming rewrite to microservices, they demonstrate a focus on pragmatic engineering that maximizes the value of their current technology stack. This approach de-risks the technology for potential investors or acquirers, showing the platform is robust and managed by a team that can solve hard problems without chasing trends. It is evidence of a mature engineering organization capable of making disciplined, if unpopular, architectural decisions that directly support business continuity during make-or-break seasonal peaks. This is not a "lifestyle" business choice; it is a deliberate, high-leverage technical investment in operational stability.
Pull quote: “The decision to disable joins is not a universal solution but a specific answer to a specific problem: making database performance predictable at all costs.”
Every claim ties to a primary source. See our methodology.