textlize pricing account
Ryan Stawarz & Austin Story: Inside Doximity’s 15-Year Rails Monolith
Cover

01:10:27

Inside Doximity's 15-Year Rails Monolith: Scaling to 200+ Engineers

How a single Ruby on Rails application has powered a healthcare platform for over a decade, evolved to support massive scale, and why it remains a strategic advantage.

Key Takeaways

  • Proven Path & Philosophy: Rails' "omakase" nature and doctrine provide a comprehensive, adaptable foundation for long-term development.
  • GraphQL as a Mobile-First Enabler: Adopted to provide type safety, prevent breaking changes for mobile clients, and streamline cross-team collaboration.
  • Federation for Resilience: Transitioned to GraphQL Federation to decouple services, improve resiliency, and enable independent product development.
  • Pragmatic Service Extraction: New features default to the monolith; services are spun out only for compelling reasons like data isolation or product independence.
  • Data & Debugging at Scale: A combination of robust seed scripts, internal tooling (e.g., `docs-tasks` engine), and a culture of trust empowers engineers to work effectively.

Why Rails After All These Years?

For engineers Ryan Stawarz and Austin Story at Doximity, the decision to stay with Ruby on Rails for over 15 years boils down to its proven, pragmatic path for development. The framework offers a comprehensive set of tools that allows teams to move from zero to production quickly, while providing clean integration points for custom business logic.

"I keep playing with every platform out there," says Ryan Stawarz, "and I haven't found anything that has the same comprehensive set of proven paths." Austin Story echoes this sentiment, highlighting the empowering philosophy of the Rails doctrine—the ability to take an idea from start to finish to enterprise with the same set of well-understood tools.

Scaling the Team and the Monolith

Doximity's engineering team has experienced significant growth, expanding from less than 20 engineers touching the Rails monolith to nearly 200 today. This growth necessitated evolving patterns and practices to maintain productivity and code quality.

The core monolith, which houses the majority of the platform's business logic, has been maintained for over a decade. To manage complexity within the monolith, teams use the `packwerk` gem to isolate quasi-domains into packages, providing a clear path for future extraction if needed.

The GraphQL Evolution: From REST to Federation

The initial driver for adopting GraphQL was a front-end migration from older frameworks like jQuery and Backbone to Vue.js. This shift required a more robust and standardized backend API.

Key challenges with REST APIs for mobile:

  • Difficulty iterating on the backend without accidentally breaking mobile clients.
  • Lack of type safety and clear contracts between front-end and back-end teams.
  • Proliferation of versioned APIs (v1, v2, v3) that were hard to keep in sync.

GraphQL, implemented with the `graphql-ruby` gem, provided a single, type-safe interface that could serve web and mobile clients alike, preventing breaking changes and improving developer collaboration.

Scaling GraphQL with Federation

As more teams adopted GraphQL, a new problem emerged: how to integrate data from external microservices and new products into the monolithic GraphQL schema? The initial solution—manually mapping data from service gems into the monolith—was cumbersome and created fragile, transitive dependencies.

A breaking point was an outage where an unrelated database migration in one service took down another team's service completely due to these tight couplings.

The solution was to adopt GraphQL Federation. This allowed Doximity to:

  • Break the monolith's Graph schema into independent, federated services.
  • Eliminate fragile dependencies and improve overall system resiliency.
  • Empower teams to build and launch new products as independent services from day one, which could then federate their schema into the central graph.

The Art of Pragmatic Service Extraction

Doximity's approach to service-oriented architecture is highly pragmatic, not dogmatic. The default is to build new features within the monolith using packaged gems.

Checklist for a new service: Compelling reasons to spin out a new service include products that need to change for their own reasons (e.g., Residency Navigator) or data that requires special isolation (e.g., HIPAA compliance). The philosophy is to incubate and prove the business case within the monolith first, with an eye toward extraction later if necessary.

This pragmatic culture embraces the fact that sometimes the team will "get it wrong," prioritizing speed to market and learning over prolonged analysis. The ability to make the best decision with available information and correct course later is a core strength.

Debugging and Data Management at Scale

With a massive monolith and numerous services, providing engineers with realistic data is crucial. Doximity employs a multi-faceted approach:

  • Seed Scripts: Teams maintain their own domain-specific seed scripts to generate realistic data for development and testing.
  • The `docs-tasks` Engine: An internal tool built on the public `rake-ui` gem that provides a UI for developers to search for and execute complex data setup tasks across different services.
  • Asynchronous Data Migrations: For large-scale data changes on multi-terabyte databases, teams write one-off rake or Thor tasks. These are run as asynchronous jobs in production via a platform that allows them to run in separate pods, sometimes for days. These same tasks are automatically run across all staging environments before production deployment, serving as a robust test.

Establishing Patterns Across a Large Org

Doximity fosters a high-trust, flat culture where any engineer can talk to anyone else. Patterns are established adaptively, not prescriptively. When repeated problems are identified, the platform team works to build solutions with tight APIs.

The process for introducing new patterns involves:

  1. Identifying a common pain point from post-mortems or proposals.
  2. Writing a "Needs Assessment" or "Tech Proposal" in a shared document.
  3. Building the tooling and actively recruiting 2-3 teams to implement it first, refining the API based on real feedback.
  4. Using quarterly planning to commit resources to organization-wide goals.

This approach ensures new tools are battle-tested and address actual needs before being promoted broadly.

Rails: The Secret Weapon

Both engineers affirm that Rails is a key competitive advantage for Doximity. Its "paved path" and cohesive ecosystem allow for rapid development and consistent integration of complex tooling like authentication, metrics, and front-end frameworks.

The richness of the framework means no single engineer knows all of it, and that's okay. The culture encourages deep diving into the code with tools like `pry` to understand how things work when needed, embodying a practical, learn-by-doing approach that has successfully scaled for over 15 years.

© 2025 textlize.com. all rights reserved. terms of services privacy policy