Jamie Lawrence

Podia at scale

I’m attending the Rails At Scale event prior to RailsWorld in Amsterdam and attendees were asked to provide a brief piece of the challenges of using Rails “at scale” (for whatever scale means to us).

I wrote a revised piece but unfortunately discovered the email to Amanda sitting in my drafts folder after the submission deadline. Duh! 🤦‍♂️

So, here’s my piece about the scaling challenges that Podia faces—lightly edited for public consumption…

Overview

Podia is a 10 year old Rails codebase that enables tens of millions of $ of digital product sales each month, from tens of thousands of creators, to millions of their audience members. We have an extremely broad product—a website builder; a checkout handling one-time purchases, subscriptions, coupons, taxes, upsells etc; an email designer with campaigns and automations; a digital product creator for courses, digital downloads, webinars; a blog with comments and embeds; a community with complex topic enrollments; and all the associated admin infrastructure—all built and maintained by a small team of just 10 developers.

Our scaling challenges

Our most pressing scaling issues are not what people traditionally refer to when they say “Rails doesn’t scale”.

We have those types of technical challenges too, like wrangling response times, N+1 queries, background processing queues, DDoS attacks, and stampeding herds of webhooks, but they all seem pretty solvable with time and attention.

And unlike much larger companies, we don’t have the challenge of scaling teams sizes whilst maintaining culture fit, quality, alignment, and standards. We rarely hire and aim to maintain our existing size.

No, our biggest scaling challenges are around how we can do more, at a higher quality, without increasing team size.

How do we scale each developer’s capability to work effectively in the face of increasing complexity?

This manifests itself in solving problems like:

  • Understanding the codebase when you haven’t worked on that feature in years. We don’t have permanent domain experts as people cycle through new projects, in new areas of the product, with some features remaining untouched for up to 6 years.
  • Reducing in-progress work and cycle times by employing feature flags, data migrations (almost constantly!), and trying to to keep CI times down. Momentum is extremely important so we ship code many times per day.
  • Meeting high product quality goals (such as design consistency, integrated features, and attention to edge cases) without increasing cognitive complexity.
  • Managing complex routes files and large numbers of controllers (thanks, Turbo).
  • Pruning old code after refactoring, when so much of Rails is implicitly-coupled (e.g. partials, routes, i18n)
  • The Rails Way is usually too simple for our needs and more advanced usage—something as simple as extend in routes.rb or namespacing models/controllers—is not widely discussed. Sometimes we need to radically extend Rails features (e.g. ActiveStorage) and sometimes replace them entirely (ActionText)
  • We needed to adopt alternative rendering systems like ViewComponents to manage our design system complexity.