Thirteen Years of Rails at the Auto Shop: How Shop-Ware Maintains a Mature Monolith With a Smaller Team
Ruby on RailsShop-Ware makes software for independent automotive service shops. Its codebase started as a Rails app in 2013 and is still more than 90% Rails. On this episode of On Rails, host Robby Russell of Planet Argon talks with Nikky Southerland, lead software engineer at Shop-Ware, which is part of the parent company Vehlo. The conversation asks what it takes to keep a large, decade-old Rails application healthy after the engineering team has shrunk to roughly half its former size.
Southerland credits Rails' conventions for much of what keeps the system manageable. The interview also covers the harder parts: a front-end migration still in progress, an API architecture the team regrets, a move from biweekly to daily releases, cautious experiments with LLM tools, Postgres scaling lessons, and an upcoming move off Heroku.
From Perl Forums to Rails
Southerland has worked in Rails for 12 to 13 years and describes the attachment as "pure love." Every time Southerland drifts to other tools, they end up coming back, because nothing else gives "the warm embrace" of a framework that feels cared for and fits the work.
Southerland started in the 2000s on Perl forum software: a CGI-bin application that "probably like three people used." It stored its data in a flat text file rather than a real database. After that came a lot of WordPress and PHP work.
Russell asked whether Perl and Ruby felt similar. Southerland said not really. The biggest difference at the time was that Rails had an actual ORM, while the old Perl forum had no database at all. Southerland still defended Perl, saying it has a bad reputation that it doesn't deserve. In Southerland's view, it is friendly for what it tries to do and was designed with a lot of thought and intent.
What Shop-Ware Does
Southerland calls Shop-Ware one of those categories of software most people never think about. A customer brings a car to a shop. A service advisor inspects it and tells the customer what the repair will cost ("always more than you'd probably like"). The customer approves the estimate, and the job goes to a technician, who does the work and logs labor hours. Shop-Ware tracks that whole job and serves as an all-in-one platform for running the shop.
The platform is mainly for internal operations, but it can also communicate with vehicle owners. Shops can send customers an inspection, which usually includes many photos taken during the inspection, and the platform supports some texting. It does not handle marketing or public websites. Southerland said other products within the parent company cover that. Shop-Ware handles payments, including down payments on large jobs, and estimate approvals. Southerland explained why approvals matter: on a large job, the owner wants to approve the spending before thousands of dollars of parts go into the vehicle. The product is SaaS.
Rails From the First Line of Code
Southerland has been at Shop-Ware for about four years. Southerland understands that the very first line of code was Rails, probably Rails 3, and says lines from that era still survive in the codebase. The company also has some platform services and AWS Lambdas, as most companies of that era do, but Southerland estimates the codebase is more than 90% Rails. It totals "a couple hundred thousand lines of code." About 10 to 12 engineers maintain it, including some contractors.
Southerland describes Rails' opinions as the platform's "secret sauce." If you trust the people behind the framework, you don't have to bikeshed every decision or research and second-guess the choices they already made. Southerland sees another benefit: when you want to do something that strongly goes against the framework, Rails lets you, but it also makes you stop and ask whether the idea is sound. The team uses that as a built-in check. If an approach will take four times as long because it isn't the Rails way, the team asks whether it is worth doing or whether the feature should be designed differently.
Russell asked whether the team starts from "how would Rails do this" or from "what's the best way" and then adapts to Rails. Southerland said it's both. The engineers are "very steeped in the Rails way," and people are shaped by what they have experience with. So when the team designs new architecture, the Rails approach is always in their minds, even if only subconsciously, because they know it works well with the system.
Active Record, MVC, and a Team of Full-Stack Engineers
Southerland named Active Record as the biggest single benefit, as it is for most Rails teams. It gives a well-structured way to work with the data layer, and new developers, including those without Rails experience, pick it up quickly. For a team that rarely hires, that matters a lot.
The model-view-controller separation also matters. Southerland has seen cluttered applications with no clear boundaries between layers. Rails, by contrast, draws a "really bright line," and if you take care to enforce it, the code stays well organized. As a codebase grows, that clarity also shows who the expert is on each part, who maintains it, and where application logic belongs.
Everyone on the team, including Southerland, is a full-stack engineer, and Southerland believes that is the right model. People lean toward the back end or front end, especially as they become more senior. But because of how the application is organized, an engineer can do application-layer work one day and HTML or CSS the next, depending on what the business needs.
Infrastructure is handled by the same team rather than a separate one. Southerland said dedicated infrastructure staff are sometimes better, but the current arrangement works well for Shop-Ware. The senior and senior-plus engineers who have been around a long time understand how servers and application layers behave, so the team monitors, deploys, and hosts the application itself. Southerland also thinks keeping engineers close to production is valuable. They see how a code change behaves in production, they spot performance problems quickly, and they stay aware that careless work can cause downtime later. Southerland called that "the ultimate like accountability tool."
Observability: New Relic and Sentry
Asked about monitoring, Southerland recalled a Rails class around 2013. An instructor installed the New Relic gem and application keys on what was probably Rails 3.2. The students, most of them from PHP and WordPress, "were all just like stunned." They could see application performance data broken down by individual controllers, along with the actual queries and their EXPLAIN plans, and it felt "like magic." Southerland says New Relic has since grown into a much bigger product, but the core is still there. Tools like it keep the team closely connected to how the code behaves in production.
Error reporting also still feels "a bit magical" to Southerland, and Sentry is the tool Southerland has used most. The team sees errors almost in real time. Sometimes they can fix a problem before support hears about it, or they can warn support that complaints are coming in about ten minutes and that the fix has already shipped. According to Southerland, that gives the team the confidence to ship faster and more reliably.
Seeds, Onboarding, and Local Stress Testing
Southerland says the team's database seed strategy "has grown organically over the past decade." Southerland considers a reliable seed file important because a good way to start on a new bug is to wipe the database and rebuild the dev environment from scratch, so everything is known to be clean. The team has specs that verify the seed file runs cleanly. For example, if someone drops a table and forgets to remove it from the seeds, the spec fails and the change can't be merged.
Onboarding is harder. Because the team is small, it doesn't onboard often, and "every time we do, something new and unexpected and fun comes up": a new service, a missing key, a database step that doesn't quite work. The onboarding docs have also grown organically, with each new developer adding to them. At the time of recording, Southerland was going through the process personally after breaking a laptop and having to set up a new dev environment. Southerland said it has been useful to experience the process from scratch and confirm that every step works.
Everyday seeds don't produce production-scale data, so the team has written many stress-testing scripts. Southerland credits Ruby and Rails for making these easy to write. The scripts quickly insert hundreds of thousands of associated records. At that scale, Postgres behaves closer to production: instead of relying on sequential scans, it actually uses indexes. Southerland also praised the QA team for providing good reproduction steps when bugs come in. When asked about more formal processes, Southerland answered plainly: "there's no great processes in place."
The Long Migration From Backbone to React
Southerland said any Rails application started in the past decade faces the same front-end problem: the original framework choice was a best guess about what would survive. Shop-Ware chose Backbone. Southerland still thinks Backbone is "quite cool," especially the Backbone Relational component, which fits well with Rails. But it is unmaintained, it doesn't do what the team needs, and "no developers know what it does anymore."
The team is moving to React, which works well for them, though Southerland stressed that it is quite different from Backbone. Southerland also observed that Rails gave strong guidance on back-end best practices but, for a long time, gave little on the front end. Everyone, Shop-Ware included, went their own way, and getting back to something more coherent has been "a journey." Front-end assets are still compiled as part of back-end releases. The team is working to decouple them, but it is slow going because of assumptions and libraries that are hard to unwind once they are baked in. Both the Backbone and React code live in the same repository.
The team is actively migrating existing screens, not just building new features in React. Southerland explained why it is slow: the application has highly skilled power users whose workflows center on a few core pages. Anything rebuilt in React has to be fast, reliable, and work from day one without disrupting those workflows, because changes can seriously affect these businesses. Southerland said most of the application has moved to React so far, and user feedback has been very good.
Russell asked whether React could end up where Backbone is now in five years. Southerland said this "always keeps me up at night," because the team's veterans have been burned by abandoned frameworks too many times. Still, Southerland doesn't expect React to reach that point for a very long time, pointing to its momentum, corporate backing, and community. Southerland also expects that any future deprecation would come with much more notice. In Southerland's view, React has done well at keeping developers from worrying that the rug will be pulled out.
Could an LLM finish the migration? Southerland said the team had discussed exactly that the previous week. Many Backbone views are simple CRUD screens that an LLM could probably convert just fine, and Southerland believes enough Backbone training data exists for that. The core pages are a different story. The value, as Southerland sees it, is in clearing out the routine conversions so engineers have more time for the core pages that need careful human work.
"Lukewarm Waters": Where LLMs Help and Where They Don't
Southerland said the team has been "dipping our toes into the LLM water," and so far the water is "lukewarm." Part of the difficulty is the codebase's size. Agents have to be told how to navigate it: where helpers and service classes live, and that a method probably already exists somewhere instead of needing to be rewritten.
Southerland named two clear wins. The first is writing specs. Southerland's workflow is to have the tool write specs first based on the intended change to a model or controller. The code is then written, possibly with LLM help. Afterward, Southerland goes back and asks whether any edge cases were missed and adds specs for those. Southerland doesn't worry about having too many unit tests, since they run very fast, and would rather have slightly too many than slightly too few, because low-level bugs tend to be found there.
The second is early pull request review. GitHub Copilot can review a PR, which catches syntax issues, unused variables, and similar slips before a human looks at it. The human reviewer can then focus on larger structural questions instead of misspellings or renaming variables.
Russell asked whether "lukewarm" described the results or the team's enthusiasm. Southerland said the most common and still very useful role is a rubber duck: asking a CLI tool a question is easier than searching Stack Overflow or a search engine. Questions that used to become a standup "parking lot" item now often get answered by engineers on their own when they are stuck, which keeps people unblocked.
The uncertainty is about how much new code should be generated in the main application. Southerland thinks LLMs are great for greenfield work. When the team recently added a new API, Southerland built a simple interface to test it in about ten minutes: code that hit the endpoint and showed the results in the browser. The product team has also used LLMs to build proofs of concept and try out UI ideas.
Inside the Rails monolith, Southerland said code generation "is a hit or miss." It helps engineers new to a framework, such as someone new to the platform services or to Ruby. The team hasn't yet worked out how to generate large amounts of code or re-architect parts of the application without breaking what already exists.
Southerland described the core problem. Rails apps like Shop-Ware's are strictly separated by concern, which is good for humans. For an LLM, though, the files relevant to a request are often far apart, and the tool can't always grasp what a large refactor is trying to do. Test coverage is good enough that the team feels prepared to experiment, and some attempts have worked. Often, though, "you throw it away and you throw it away" until something makes sense. The pattern that works best for now is to use the LLM for a proof of concept inside the monolith, confirm it works and has some tests, and then hand that code to an engineer as evidence that the approach is possible: "this is probably not that great, but it physically shows that it's working. Let's make it better."
The Cultural Side Effect, and Code Review as the Backstop
Russell asked whether self-service answers from LLMs might be isolating people on the team. Southerland said the thought had come up just minutes earlier. Shop-Ware is fully remote and encourages pairing, huddles, and working through problems together, which builds the familiarity that makes people comfortable asking questions. LLMs can have a siloing effect.
Southerland also pointed to a difference in quality. A colleague's answer will usually be highly relevant to the question. An LLM makes an educated guess based on pattern recognition across the codebase. If 80% of the code follows a pattern from ten years ago that the team no longer uses, the LLM doesn't know that, "but your colleague a Slack room away does."
Russell added that this problem existed before LLMs. Consulting clients with 40 engineers already struggle to decide when to refactor toward a new pattern and when to leave old code alone. LLMs might speed that process up, but they also make it harder to keep everyone aligned.
Southerland described several checkpoints the team uses to stay aligned, and said the earlier a problem is caught, the better. For epics and feature work, engineers write the tickets themselves and think through everything from UI to back end to deployment strategy. Someone reviews that plan, usually Southerland, so there's no ambiguity about the intended architecture. Then the code is written, "through whatever means." The final checkpoint is code review.
Southerland considers PR review even more important than it used to be. Ten years ago, a PR was written by a human, copied from Stack Overflow, or perhaps produced with an early tool like Tabnine. Now it can come from anywhere. Copilot handles small syntax issues. For the larger questions, Southerland considers the author and the PR approver equally responsible for any code that reaches production. The review is where someone can say that a service isn't used anymore or that the team doesn't do things that way. Southerland added that reviewers can also catch decisions an LLM made that the author, deep in the work, didn't notice.
The Public API: Two Codebases and One Big Regret
Shop-Ware has a public API used both by customers and by third-party integrators. When the API was built, before Southerland joined ("a little bit of archaeology here"), the decision was made to put it in its own codebase, separate from the main Rails app. "We regret this decision," Southerland said. "I think we regretted this decision almost the minute it was made."
The main cost is duplicated logic. A model change in the main app has to be mirrored in the API. So do validations and any service helper that does a dynamic calculation. Southerland called it "a big morass" that the team is trying to unwind without taking the API down. The team keeps the two in sync partly with scripts that automatically copy over model code and the schema file, which "keeps us somewhat honest." They also copy and paste service-level calculators when needed.
On data flow, the API app reads through read-only database connections. For writes, it acts as a proxy: a POST arrives, and the API app sends a separate request to internal, non-public APIs in the monolith, which enforce data integrity and access rules. The read-back then goes through the read-only connection. No other internal consumers use those internal APIs.
The team is in the early stages of rethinking this design. Southerland said there is broad agreement that the next time a major API effort comes up, the API will move back into the main application.
The API is REST, or "RESTish," because it was built before GraphQL became popular. Southerland said that if they started from scratch they would "surely" choose GraphQL, but the current model works, and there is no pressure or demand in their ecosystem to switch. Still, "we certainly gaze at GraphQL with wistful eyes sometimes" for the flexibility it could offer. Russell joked that LLMs might eventually make merging the API codebase easy, and Southerland agreed that it's possible.
Doing the Same Job With Half the Team
A few years ago, the engineering team was about twice its current size, with several parallel efforts to build new things and launch new applications. It has since been scaled back. Southerland said losing colleagues is never good, and a lot of institutional knowledge leaves with them despite the team's best efforts at documentation, cross-training, and avoiding silos. Rails helps recover some of that knowledge because its structure forces some organization, so engineers aren't completely lost in unfamiliar code. But Southerland said Rails gets them "part of the way but not all the way."
Southerland thinks prioritization has changed mostly because less work gets done overall. The key point is that infrastructure work stays roughly the same whether a team has 10 engineers or 100. A large team can spread the hours for DevOps and on-call duty across more people. A small team has to make infrastructure as efficient as possible, because inefficiency costs the business proportionally more. Southerland expects defects to scale with feature output, so fewer features should mean fewer defects.
Third-party integrations don't shrink with the team, though. Vendors upgrade their APIs and ask Shop-Ware to update integrations built a decade ago, for example replacing an old SOAP interface. Southerland sees this as a natural fit for LLMs: working with APIs is "an LLM's bread and butter." Giving the model an API and asking how it works and what an integration needs gets the team through the first several steps. Russell recommended this use case to LLM skeptics, especially for publicly documented APIs.
Niche Integrations and No Off-the-Shelf Gems
Russell asked about using Ruby gems for integrations. Southerland said gems can become a future blocker, because adding one is a bet that someone will still maintain it when new Ruby versions arrive, or else the team ends up maintaining it. In practice, Southerland couldn't think of a case where an off-the-shelf gem fully covered one of Shop-Ware's integrations. Southerland sees an upside: the team controls its integration code, knows exactly what it does, configures it as they want, and can code defensively in ways that are hard with a gem that doesn't quite fit.
The integrations are unusual. Southerland doubts most Rails developers buy automotive parts from wholesalers programmatically or pull data from vehicle lookups. The auto industry has standardized a huge amount of data keyed to a vehicle's VIN, including identifiers for the engine, transmission, submodel, trim, and transmission type. Southerland finds the amount of data "really incredible." Southerland guessed that maybe 50 people in the world consume this data, and there are only a few providers.
Southerland said Shop-Ware is a relatively new cloud-based entrant in a market that computerized early. One of the first uses of desktop computers in the 1980s was auto shops tracking their work. As a result, many shops still run on pen-and-paper notebooks or on Windows XP- or Windows 95-based terminal applications. Those tools have been discontinued, but shops keep them because they work. Much of the job is migration: handling the nuances and helping shops see the value of moving to a modern system.
Onboarding Shops and Migrating Their Data
Customers include both single shops and entities that own multiple shops. Unless a shop runs on paper, it brings data from another system, so data migration is a large part of onboarding. Southerland said the company believes shops should be able to both import and export their data, and it tries to make bringing data in as easy as possible. But there are many source systems, some requiring custom work, and in some cases a migration is "not even really possible" because the old system is so different. Customers range from sophisticated shops to new ones that intend to become sophisticated. Russell confirmed that the migration and onboarding process is part of the value Shop-Ware offers.
Russell asked whether the codebase contains customer-specific conditionals for large accounts. Southerland said the team works hard to avoid them. When a customer asks for features A, B, and C, the team evaluates each one. Features relevant to many customers become available broadly, and others may go on the roadmap. Southerland added that they aren't closely involved in how product prioritizes. The team generally avoids tenant- or shop-specific code, "because every time you do that you're like doubling your complexity." Southerland admitted it does "happen a little bit." Russell said that from his consulting work, it's oddly reassuring that even polished SaaS platforms make occasional exceptions for a big customer.
Feature Flags With LaunchDarkly, Including Kill Switches
Instead of custom forks, Shop-Ware relies heavily on feature flags. A customer who pushes hard for a feature can get it early through an early-access program. That helps the team check how the feature works before rolling it out to larger groups and then to all shops.
The team uses LaunchDarkly. Southerland said it took a few years to settle on a workflow and get everything working as intended, but it is now very helpful. The product team controls when features are enabled. They can turn them on per tenant or for everyone, and toggle them on and off, completely independently of engineering. Southerland said this is what makes frequent deploys possible, because new UI and logic changes ship behind flags.
Engineering also keeps some permanent flags of its own, notably kill switches for third-party integrations. If an integrator goes down and that makes parts of Shop-Ware slow or unresponsive, the team can switch off that integration with a flag until the integrator recovers.
From Biweekly Waterfall Releases to Daily Deploys
When Southerland joined, Shop-Ware released every two weeks, at least in theory, and "everyone hated" the process. A QA regression pass lasted about a week and sometimes found bugs. Features that had been promised were often pushed in at the last minute, delaying the release candidate and hoping nothing broke. If you missed the window, you waited two more weeks, and bugs went unfixed for two weeks unless they were serious enough for a special release. Southerland said it consumed a lot of engineering time and a very large amount of QA time, product was unhappy with the slow pace, and the waterfall process forced many trade-offs.
A few years ago, after a big discussion of the pros and cons, the team moved to daily deploys. An engineer deploys the code each day. Almost all engineers are deployers, which also means they are on call and close to production. Bug fixes ship faster, and product changes ship incrementally as tickets on a feature are completed. That code runs in production early and can be enabled for early-access or testing tenants, where the product team can verify it on the production environment.
Southerland highlighted a change in developer mindset. The large manual regression pass that used to act as a backstop is gone. Engineers now have to think defensively about what their code does to production queries and third-party integrations. Southerland said people have become much more aware of those trade-offs and more careful about what they push, and considers the change "a big success."
Southerland listed the results: less time spent deploying, more time on targeted QA against things that matter, and, Southerland believes, fewer defects, because code ships when it's ready instead of being rushed to meet a two-week deadline. Rolling back now means undoing a day of changes instead of two weeks. Russell added that fast feedback keeps context fresh: a developer can remember what they did yesterday far better than what they did three weeks ago.
Russell asked whether the smaller team made this easier. Southerland first stressed that Shop-Ware's customers depend heavily on stability. If the application is down, shops can't repair vehicles, see new customers, take payments, locate cars, or order parts. There is "a real human cost," and the team treats incidents seriously. Even so, Southerland doesn't think team size matters much for frequent deploys, as long as everyone buys in. QA checks what an engineer directly touched, the change ships, and engineers stay very aware of the "blast radius," because they're the ones who get paged or asked about it a day or two later. If a new Sentry exception appears the day after a release, the engineer probably knows what caused it. Two weeks later, they may be on a different epic and remember nothing.
Postgres: Unlearning the Fear of Connections
"We love Postgres for a lot of reasons," Southerland said. "We don't love scaling Postgres for a lot of reasons, but less reasons than why we love it." Southerland described the standard advice: relational database connections are precious, especially in Postgres, where new connections are expensive in compute and memory. So you keep connection counts as low as possible and aim for close to 100% utilization. The usual fix is a connection proxy, with PgBouncer the best-known option.
According to Southerland, what nobody tells you is that these proxies can hit CPU saturation themselves, and when they do, it is very hard to observe. Southerland recalled starting on Heroku 10 to 12 years ago, when connection limits were very small, around 20 as Southerland remembered it. The team used every built-in Rails tool and connection pooler it could to keep connection counts down. Over time, they learned not to fear connections so much. The team has decided to "embrace connections again" and return to Rails' own connection management. That may mean somewhat more connections, but the application stays stable instead of overloading middleware that can take the whole application down.
Everything runs in one large Postgres database. Southerland said that works well almost all the time, but tenant sizes vary widely, so indexes can become unbalanced, large, and hard to maintain. The team tried Postgres partitioning by tenant ID, but it ran into problems on Heroku Postgres, where they lack full access to advanced administrative tools. It became "workarounds upon workarounds," and they concluded it wasn't workable on Heroku. Southerland said they hope to do it on AWS, because they are very interested in sharding tenants and isolating them from one another. Russell noted that other guests had split databases for a different reason: they were hitting size limits on AWS Aurora.
Reading the Writing on the Wall With Heroku
The episode was recorded in mid-March. Russell described how Heroku had recently made clear, a few weeks before, that it would not invest much more in developing the platform. Asked whether Shop-Ware is evaluating hosting options, Southerland said "it is very safe to say yes."
Southerland said the team started looking at alternatives the year before. After several incidents over the past couple of years and Heroku's lack of new offerings, "I think we all read the writing on the wall." To Southerland, the platform looks like it is in maintenance mode, keeping what it has without adding features. Southerland also said that if you open Heroku today, it would feel familiar to someone who learned it in 2010. The evaluation is still going, and they hope to move within the next year or so. Southerland said the obvious answer is AWS or something similar, where they can run containers and scale flexibly.
Southerland explained that Shop-Ware's load depends heavily on time of day. Most customers are U.S. shops open roughly 9 to 5 across time zones, so overnight a very large database sits mostly idle, "because nobody's repairing cars at 3:00 a.m. Pacific time." Southerland sees a big opportunity for smarter resource scaling on a more modern platform. The team currently deploys on Heroku's default stack ("we've been spoiled"), and containerizing the app is in progress as the first step.
The Atypical Thing: Async Updates Without Action Cable
Russell asked Southerland to imagine writing a letter to an experienced Rails developer joining while Southerland was away on a six-month sabbatical. What unusual thing about the codebase should they know? Southerland's answer was asynchronous updates. Shop-Ware has them, as many apps do, but they don't use Action Cable. The feature was built before Action Cable existed and relies on a third-party provider, which Southerland thinks is called Stream. This trips up new developers, who assume the app uses Action Cable or has been converted to it.
The flow works like this: third-party code integrated into the app opens the WebSocket and listens for updates from the provider. When the app needs to send an async update, it pushes the update to the provider, which Southerland assumes runs something like Redis, and the provider delivers it to clients. "It's essentially Action Cable, but like we're doing it pre-Action Cable."
Book Recommendation: Digital Apollo
Asked for a non-technical book recommendation, Southerland happened to have one nearby: Digital Apollo by David Mindell. It covers the design and architecture of the Apollo Guidance Computer, built in the 1960s, which Southerland describes as one of the first pieces of computer hardware that was both mission-critical and widely known to the public. Southerland likes it because it looks back at where the field came from and shows how today's decisions closely mirror ones made 30 to 50 years ago. The work of earlier engineers still informs today's.
Asked where listeners can follow the team, Southerland answered: "We have no blog. We have no socials."
Welcome to On Rails, the podcast where we dig into the technical decisions behind building and maintaining production Ruby on Rails apps. I'm your host, Robby Russell. I also run Planet Argon. And for over 20 years, we've helped teams maintain and evolve their long-lived Rails apps. So, I tend to approach these conversations through that lens. On this episode, I'm joined by Nikky Southerland, lead engineer at Shop-Ware, which is part of Vehlo. Shop-Ware is a software platform that helps automotive service shops run their businesses. Behind the scenes, Ruby on Rails has played a major role in powering the platform, and it's grown and evolved over the years. In our conversation, Nikky and I dig into how their Rails app has evolved over that time, how their team approaches API design and front-end architecture decisions that have accumulated over the years, and what it looks like to continue maintaining and improving a mature Rails system with a much smaller team than they once had. Nikky joins us from Philadelphia, United States. All right, check for your belongings. All aboard.
Nikky Southerland, welcome to On Rails.
Thanks, Robby. Happy to be here.
All right, Nikky. So, to kick things off, what keeps you on Rails these days?
Oh, it's pure love. I've been on Rails for 12, 13 years now. And every time I drift away, I always come right back because nothing else makes me feel the warm embrace of something I think is really cared for, and a framework that really makes sense for what I'm trying to do.
Out of curiosity, what tech stacks did you work with prior to Ruby on Rails?
Well, I got started working on Perl forums back in the 2000s.
Okay.
And that was real fun. And then a lot of WordPress experience after that and, you know, so PHP as well, but that's kind of the general progression.
Is that back in like the Perl CGI script era, or?
Yep. CGI bin directory, and it was a forum software like probably like three people used and did not work very well, but it was great at the time.
Oh, brings back memories myself as well. I did quite a bit of work in Perl actually in the early 2000s, a couple years before I started using Ruby on Rails myself. Did you find any interesting similarities between Perl and Ruby at the time?
Not really. I did appreciate, you know, the fact that Rails had an actual ORM, whereas our Perl database was actually a flat text file. They don't believe in actual databases, this particular piece of software. So that was fun. But I do find other languages that I think Perl has a bad rap, but I disagree. I think it's really friendly for what it's trying to do, and I think it's designed with a lot of thought and intent, which is what I really appreciate about it.
Nice. All right. So why I wanted to have you on the podcast is, so for listeners who might not be familiar with Shop-Ware, can you give us a little bit of an overview of the platform and how Ruby on Rails kind of fits into the architecture today?
Yeah, sure. So we've been around for a little over a decade now. I think we got started like 2013, and it was a Rails app from the very beginning. You know, Rails probably version three at the time. As a company and group has grown, Rails has grown along with us. It's really helped us kind of meet the challenges that a growing platform needs, and provides the guardrails, recommendations to do things kind of the Rails way, which is the way that we wanted to do them initially.
What is Shop-Ware actually like?
You know, there's lots of things in the world that you don't really know about, and I think this is software for auto shops. There's mechanics every day who are working on your car, and you bring it in and you have some sort of issues, and you have a service advisor who inspects your car and tells you how much money you need to pay to get your vehicle operating safely. Again, it's always more than you'd probably like, but, you know, that's a software that helps keep track of that job. You know, you can approve your estimates, and then it gets handed off to the technician who then actually does the work and tracks their labor hours. And it's kind of an all-in-one platform to help an auto shop business kind of run their shop, which is, you know, a lot of like insider industry stuff that we don't think about, but they care a lot about, and we try to help them and match enthusiasm.
Is this primarily for like internal operations, or does it handle like marketing-related activities as well, or kind of across the board?
It's a little bit of both. It primarily is for communicating with an actual like vehicle owner. So, it's mostly internal, but we can communicate with the vehicle owner if we need to. Like, we show them an inspection of the car, which usually includes lots of photos that they take, and we can do some like texting platforms as well, but we don't really do much of the marketing side of public websites. That's kind of on the shops to do. And there's other solutions that we have for that within our parent company, but we focus on internal operations mostly.
So, it's like someone brings their car to an automotive shop and they're using this to bring in, do some customer intake, tracking their workflow. Does it handle like billing and things like that as well, or?
Yeah, it handles payments. It handles, you know, sometimes there's a down payment with a large job. It handles estimates and approving those estimates. You know, if it's a large job, you want to approve that spend before they actually start throwing in like thousands of dollars worth of parts into your vehicle.
So is this like a SaaS-type product then, or?
Yeah, exactly.
Interesting. And so you said that's been around for, you said 12, 13 years. Is that right? Or?
Yep.
Maybe you mentioned this earlier, but when did Rails kind of enter the picture for Shop-Ware?
I think it's the very beginning. Like, I've only been around for about four years now, but my understanding is like the first line of code was Rails code, and we still see some of those like 12, 13-year-old pieces of software lines in our codebase still. So it's from the very beginning.
Are there other tech stacks kind of in the workflow that kind of fit into this as well?
Yeah, there's a couple, as with most companies that existed in the 2020s. We have some platform services and some AWS Lambdas and various stacks in there, but it's almost, I would say, like 90% plus is a Rails-based codebase.
Do you know off the top of your head approximately how large of a Rails codebase these days?
I'd say it's a couple hundred thousand lines of code.
Okay. Overall. And how big of an engineering team is kind of managing that today?
We have around 10, includes some contractors as well, but around 10 to 12 usually engineers is what we're looking at.
That definitely helps us at least help set the scene for some of the topics I want to dig into. So for developers that might be listening, so Shop-Ware has grown. Where do you feel like Rails has been, say, part of the platform's secret sauce?
The really nice thing about Rails is that it is an opinionated framework, and I think there's a lot of value in having those opinions because you're not having to bikeshed everything at that point. You know, kind of that as long as you trust the people behind it and the groups behind those frameworks, you don't have to do a ton of like second-guessing and research about the decisions that they've made that you're advocating for. And I think it's really helpful in that as you have this framework and you are trying to go do something that's extremely against it, you can do that, which you can do in Rails of course, but it really makes you kind of think and pause about: is this a good idea? Do I need to be really contemplative about this thing before doing it in a way that's not the Rails way? And that's been really helpful for us because it is kind of that built-in check of, like, you want to do this thing that will take us four times as long because it's not the Rails-recommended way of doing things. Is this worth it, or should we maybe rethink how we actually want to implement this?
You know, when you're thinking about adding new functionality or making architectural decisions, do you find yourself mapping out like how can we do this with Rails, or is it like what's the best way to do this and then try to figure out how to do that within Rails? Is there kind of a direction your team tends to navigate when you think about these things?
I don't think it's either/or. I think it's a combination of both. I think, you know, our engineers are very steeped in the Rails way of doing things. And so I think it comes really naturally to them, and myself included, to think about these. We are shaped by what we are experienced with and what we've been working in. And so as we build these architectures out, we're always thinking, I think, of the Rails way, even if it's subconscious, just because that's a way that we're used to doing and we know works well with the system.
Right. You mentioned like the ORM and like Active Record, and that's a pretty common thing. Is there something about Active Record that you feel like has really resonated really well with the type of platform that you built there? And, follow-up question, are there any other particular Rails features or conventions that you feel like have really paid dividends over time?
I think Active Record is huge for us, as is huge for almost anybody who I think uses Rails, in that it does provide this really well-intentioned way of visiting your data layer, and it's a way that, you know, can be familiar with developers who are onboarding as well, who maybe not be familiar with Rails. Like, we're saying, okay, here's our data layer, here's how we view it, and it's extremely easy for them to pick up, which is huge for us. And the second part question was, what else do we find useful?
Yeah. What other aspects of Rails that comes kind of bundled with Rails you feel like is really helping pay off for your team?
The separation in model-view-controller of course is also huge for us. Like, we've seen applications in the past that could be extremely cluttered, or there's not like a clear separation between all those things, and there's a really bright line in Rails. As long as you take care to enforce that bright line, that really helps you keep everything extremely well organized. And especially as your codebase gets larger and larger, it helps you understand who's the expert in what and who maintains it and where all this application layer should actually be going.
Do you find that, I don't know if you can compare this to previous tech stacks or roles that you've been a part of, but do you feel like there is hyper-specialization within your team, given how you're approaching Rails? Or do you feel like because of how Rails approaches things, people can move around the codebase a little bit more freely than you might have experienced in other organizations?
Yeah, it's great. Our team is, they're all full-stack engineers, myself included, and I truly believe that is correct. Some of us are more experienced in the back-end or front-end layers, and as you progress kind of in seniority, that's to be expected. But at the end of the day, the way that the applications are organized and architected means that you can work one day in the front end doing some really application-layer stuff, and then the next day be working on like HTML or working on like CSS platforms or something, which is really great because it does give that flexibility for engineering staff to be kind of working in all different areas depending on what the need is for the business.
Do you think that's also, given some of the way that Rails approaches the stack, you're able to focus a little bit more on the product than the infrastructure itself? Do you feel like it's kind of helping a lot in that area as well? And do you have people on your team that kind of focus more on the infrastructure side? And are they actively working on the Rails app, or are they kind of like a separate team that manages infra?
Yeah, it's all the same team, and it is really helpful because the way we monitor applications and view our applications is in the way that's really familiar with us. And especially our senior, senior-plus engineers who have been around a long time really kind of understand how servers behave and application layers behave in a way that makes it so that we can monitor and deploy and deal with our application hosting itself. And, you know, it's not perfect. Like, sometimes dedicated staff are better for that, but for us I think it works well. And I think it's also really helpful for the engineers to be extremely close to your production instance, because if something goes wrong, you know much better of what's happening. If you make a change to the code, you can see how it reacts in production. I think it can help spot issues and performance things really quickly, and you're much more cognizant of what you do has potential downtime down the road if you don't do it in a meaningful way, which I think is great, because that's the ultimate accountability tool.
Sure. You know, I'm curious, how is your team currently thinking about monitoring and observability? Are you leveraging many observability-specific tooling things at this point, or where does that kind of fit into there? And then if one of your engineers is assigned to, let's say, deal with a bug that's only able to be reproduced in production, what's that workflow look like for being able to kind of figure that out, if you don't mind sharing a little bit behind the scenes.
So I think one of the best attributes of Rails in the very beginning is, I remember I was doing a small class, probably 2013, with Ruby on Rails, and one of the instructors like pulled out New Relic. He's like, "Hey, check this out," and installed the application keys, installed the gem, and it's probably Rails 3.2 at the time. We were all just like stunned. We'd never seen anything like that, most of us from PHP WordPress land, but to be able to see this like app-specific information that actually drills down to your individual controllers and see your actual queries and those explains behind it was like magic. It was absolutely amazing. And I think we still see that today with the observability tools that we have: they're really, really good. New Relic has obviously gotten into a much larger thing now, but the core product is still there, and we have really close connection with the code and how it behaves in production because of these tools. And I think error reporting also seems a bit magical to me. You know, like Sentry is, I think, kind of the main tool that I've used a lot. It is great, like the ability to see this error almost real time, and in some cases address it before you even hear from support staff, or you can notify them like, hey, in 10 minutes you're going to get probably somebody complaining about this. We've already fixed it, but just to let you know it's already happened. That's great. That really gives so much confidence that we can ship things faster and ship them more reliably and know that we're not causing issues.
Let's say an issue pops up. It sounds like you're using Sentry there potentially, and something pops up in Sentry, there's an issue. Is your team needing to figure out things that are going on with production data at all, or are you able to, like, what's that workflow for? And also, how does your team approach a healthy database seed strategy for, let's say, local development or testing things out in staging? What sort of tooling has your team put together there, or is that an area that you're still trying to figure out?
I would say it has grown organically over the past decade.
Like good seeds do.
Exactly. Yes. And it's always a challenge, because I think a lot of developers don't think about that always, and I think it is important to have a
seed that is reliable, because one of the best ways I think of approaching some of these things is you do start from scratch. Like, you have a new issue, a new bug, like, let's wipe the database, let's start our dev environment from scratch so we know everything is clean and ready to go for our next work. And so a clean seed file is a really important part of that, and we have specs that ensure that the seed file runs cleanly, million, and if we drop a table and later don't brew it from our seed file as well, it's going to complain about it, and that spec never even passes whenever we merge that in. That's been really helpful for us, the tooling around that.
But onboarding is always a challenge. Like, we are a smaller team, so we don't onboard that often, and it seems like every time we do, something new and unexpected and fun comes up that we have to contend with, you know, some new service or some key or some database thing doesn't quite work. But it's a result of, like, we have organically grown documentation that every developer, as they onboard, helps add to. And then we're in a state where I myself am actually going through it. I broke my laptop and have to get a new dev environment set up, and it's been really helpful seeing that experience from scratch, that I have to actually go through this and make sure everything is working.
Do you feel like your team is able to your seeds? You mentioned it's kind of grown organically. Is there typically enough volume to stress test anything, like maybe on a performance level locally, or if you got, say, production issues that seem to be maybe just from the sheer volume, what resources and tooling does your team have access to to try to mitigate those types of issues?
Yeah. So we've developed, largely through kind of the ease of Ruby and Rails' scripting capabilities, lots of stress testing scripts that we can run that will quickly seed and insert into the database hundreds of thousands of associated records. And that's very helpful because that usually gets us to be at the scale where we can start looking at what Postgres is doing in a near production-like environment, and it's not just relying on sequential scans anymore, but actually using indexes, which is very helpful. And we have a really good quality assurance team, and they really help out with effects, and as a bug comes in they usually will give us very good reproduction steps on that. I don't have too much to say on that. Like, we do things, but there's no great processes in place.
Okay, that's fair. So many long-running, say, Rails applications, you know, the application's been in development for over 12, 13 years now, so they tend to have a lot of front-end decisions that might date back several eras in the ecosystem. So what does that look like at Shop-Ware today? Is everything up to date on a most recent version of the frontend ecosystem, or maybe not?
Yeah, that's a story as Ruby on Rails applications have evolved, and I think anyone started in the past decade is experiencing this, where the front-end framework decisions that these applications have made were largely best guesses. You kind of pick what framework you think was going to survive in the future and works with what you have right now. And in some cases, us included, our initial framework was Backbone, which I don't know if you're familiar with that one, but I am. I think it's quite cool, especially there's a Backbone-relational component to it, which I think really fits within the Ruby on Rails framework, but it's also unmaintained and doesn't really do the things you want it to do, and no developers know what it does anymore. And so we've been moving over to the React side of things, which works really well for us, but it is different than Backbone. I'd argue quite significantly different. And yeah, as much information that we get from the Rails back end on best practices and ways to do things, I think we didn't get that for a long time from Rails on the front end.
And I know this is not like a new story or a new revelation at all. Everyone, I think, has kind of gone their own path, us included. It's been a journey to get us back to something that makes a little more sense. We're still compiling our assets coupled with our backend releases, but we are working towards decoupling those, but it's a process because there's a lot of baked-in assumptions there and libraries that are hard to unwind once those decisions have been made.
So is it safe to assume all that Backbone is in the same repository? And what about the React side? Is that in a separate repository that you're doing that, or are you using something like React on Rails to kind of have that be part of it?
It's the same repository.
Okay. Are you migrating things from Backbone to React, or are you building out new things with React and hoping to eventually get back to deprecating Backbone at some point?
Actively migrating things from Backbone to React. It's a long process, as our application has a whole set of extremely competent power users who have a lot of really good workflows built up around a few really core pages. We have to take a lot of care to make sure that what we build in React is extremely performant and reliable and works from day one and doesn't interrupt their workflows, because we make changes and it could have significant impacts to these businesses. So it's a contemplative, long process to move these from Backbone to React. The things we've done so far, and most of the application has moved to React at this point, we get really good feedback from, but it takes time to do.
I haven't honestly gone back to look at the Backbone website in a while to see if there's been many new versions in like a year or two, and I don't remember what I remember figuring out, but I've always, like, well, at the time it was modern. Do you feel like the migration to React versus, like, I know that Rails is maybe encouraging things like Hotwire and things like that, do you feel like you're going to end up in a similar situation in five years, or do you feel like React has enough momentum on it with their community there that you're not concerned about that anytime soon?
Oh, this always keeps me up at night. We've been burned by this too many times in the past, and I think the grizzled veterans always have that in the back of their head of, like, what happens if this framework goes away? What happens if this goes into maintenance mode? I don't think React's going to get there. I don't think it's going to get there for a very, very long time. I think there's a lot of momentum behind it and corporate backing and a community that keeps things going far into the future. And if something does get deprecated to a point, I think we'll have much more notice and information about it. But I just think that React has done a very good job of keeping everyone calm and centered and not worried about the rug being pulled out.
Do you get a sense that if you were to bet that maybe a year from now you'd feel pretty confident that you could task an LLM code tool to be like, hey, migrate the remainder of our Backbone to React given the patterns we've already been using? Or have you been able to experiment with that? And I say that because I know that you have a robust QA department there that seems like it could potentially be a strategy to experiment with, if they could test the before and after, make sure things are still working there.
Yeah, it's actually something we were talking about last week internally. You know, there's a lot of views in Backbone that are really simple, simple CRUD, simple things that I think an LLM would do just a fine job converting over, and some of the really core pages of the app, maybe not so much. But if we can at least get a lot of these smaller things or more routine conversions out of the way, which I think it should be able to do, I think there's enough Backbone training data there to be able to handle that, it does free us up to spend more time on the really core parts of the app that probably do require a lot more human intervention to get right, because they just are so core to the business and how people use it.
Has your team been adopting and leveraging much on the LLM front at this point, specifically within the context of code generation and working on issues and tickets and things like that?
Yeah, we've been dipping our toes into the LLM water, as I'm sure everyone else is to some extent, and it's been a lukewarm water so far for us. As I mentioned, we are a large codebase, and there is a lot of work to be done informing the agents and LLM models how to interact with our codebase, where our helpers are, where our service classes live, how to find things. You probably don't need to rewrite that method from scratch, because somewhere someone's already written that; you need to go know where it is.
And we found it helpful for code generation for sure. I think the big win in my mind is writing specs. It's been really great to kind of have an idea of something that you want to add to your models or your controllers or whatever else, and you have it write the specs first, kind of guiding that process. Write the code, maybe LLM-assisted, and then go back and revisit the specs and kind of ask, like, is there anything that we've missed, any edge cases I would have introduced? Add those to the codebase as well. That's been great, being able to write these really low-level unit tests, and I don't have a problem with having too many unit tests personally. They're extremely fast. I'd rather have an issue of having perhaps a little bit too many than a little bit too few, because I think that's where a lot of your low-level bugs have been found.
And the second component to that is I found it useful for a really early PR review look. There's a feature in Copilot and GitHub land where you can request a review on a PR, and that's great for spotting syntax issues, unused variables, things that maybe slip through the cracks before a human even gets eyes on it. So that by the time a human sees it, they're not looking for, like, oh, maybe I need to rename this variable a little bit. They're looking at the much bigger structural things, not getting distracted by, you know, misspellings or a method maybe not being used right.
You mentioned that lukewarm. Is that primarily on the results of just the experiments that you're running, or is that kind of lukewarm adoption with just your teammates as humans? Is everybody on your team kind of excited to play with these things, or is it kind of a little bit of a mixed bag at the moment? And I know that their opinions on this might change in a month or two anyways, as mine did over the last three or four months myself. So share what you're willing to share, I suppose.
Yeah, it's a journey, and I think the initial use case for a lot of these, and I still think a really powerful use case of it, is just it's a rubber duck. It's something that you can ask questions to, get information from. It's a little bit easier to enter some CLI tool versus searching Stack Overflow or seeing some search result on Google or DuckDuckGo. Definitely been helpful for us. Like, we see a lot of usage where things that might have required a group, you know, standup parking lot or something that they ask questions about, now they're being resolved kind of on their own just when they're stuck. They're like, "Hey, I got a question," and it might be able to help out on the feet, and helps out some of the time. I think it keeps people from getting blocked and, you know, helps them unstick themselves from whatever things they're running into.
You know, I think the lukewarm part is, like, we're still not sure about how much new code will be generated on our mainline application. I think LLMs are great for greenfield apps. Like the other day, we had a new API and I was able to create an interface to test it out in, you know, 10 minutes. I knew what I wanted. I just wanted some simple, you know, pre-compiled code to go in and hit this endpoint and show me the results in the browser, and it could just do that, no problem. And it's been useful for our product team too, to create a lot of proofs of concept and kind of play around with how they want the UI to work.
Code generation inside our actual Rails application is a hit or miss for us. It can be useful, especially if we have a new user coming online working on our platform services or working on Ruby who's not super familiar with those frameworks. But we're still trying to figure out how to best generate large swaths of code and rearchitect parts of our application in a way that doesn't break what we currently have.
And do you feel like your test coverage there is substantial enough that you feel like there's a lot of confidence that if things make changes, you're like, okay, we know things are breaking? Or when you say you're having lukewarm on code generation, can you tell me a little bit more? Is it like it's not quite doing what we would kind of expect it to, following existing patterns, or what does that actually look like?
Yeah, it's a lot of trying to figure out, in our existing patterns, how to fit all of the paradigms together in the way that makes sense for us. And part of it is that I think a lot of these applications, you know, Rails applications especially, have grown where your codebase is extremely regimented and separated, like in a separation of concerns, which is great, but to an LLM that means the files that are proximate to whatever you're asking it are going to be way far away, and it's not always able to fully contemplate what you're trying to do in a large-scale refactor. And I think our test coverage is there, which gives us, we're prepared to do it, and we have been trying it out, and results have been successful sometimes, but you know, you throw it away, and you throw it away until you get something that makes sense. And then I think it's useful to kind of do a proof of concept inside our monolith application. You do a POC, you make sure it kind of works, you have some tests for it, and then you say, okay, now we can work on it for real, and give someone the POC code and say, like, hey, this is probably not that great, but it physically shows that it's working. Let's make it better. Let's improve on it.
Sure. You know, one of the things you mentioned there was that some of the LLM tooling is helping your team maybe answer some questions themselves before they need to go to, I don't know, maybe I'm just assuming, some engineering help Slack channel or whatever. Do you feel like there's any weird side effects, that your team is less able to bond and help each other as a result, and you feel like you're siloing the work a little bit more as a result of that? I'm not saying that as a good or bad thing. Just, have you seen any interesting cultural side effects to that?
Yeah. No, I was actually just thinking about that a few minutes ago, and it is something that I think we're seeing. We're an all-remote team. We really foster pairing and huddles and collaborative question and answer, and let's work together to find solutions to these problems and kind of help me figure out what's going on. And I think it does give you that familiarity with your colleagues that makes you more comfortable asking those questions, and sometimes I think it can be a siloing effect. And you know that the answers you're getting from the other person are probably going to be extremely relevant to what your question is. With an LLM, it's making
educated guess. You know, it's doing pattern recognition based off of your codebase, and you hope it's the right answer. And in some cases, you know, it might be the way that you did it 10 years ago that has 80% of your code, and that's not the way we do it anymore, but the LLM doesn't know that.
But your colleague a Slack room away does.
I do think that's an interesting thing that I feel like teams are going to have to wrap their head around and be mindful, like, okay, where are we if we adopt these tools and it starts accelerating some things and we spend more time managing and orchestrating these LLM tools? Where are we kind of jelling together as a team and helping each other? You know, sure, the marketing materials on all of these tools are like, you're going to get to focus on these bigger issue things now, and it's like, I hope maybe we get there. And I don't know, I'm not an expert on any of this stuff, so take my thoughts with a grain of salt here, but I do wonder, like, as you mentioned, okay, well, how we used to do things 10 years ago, and there's plenty of code in your codebase that might be like, this is how we were organizing things then, and now we have a new architecture approach. Maybe we were using service objects for a long time, or now we're trying to do something different over here, so we want anything new, like these old things, to be kind of in this new pattern, trying to manage the LLMs to make sure they keep doing that.
It's not that that problem hadn't already existed with large growing teams, because I've had plenty of consulting clients. They're like, "We've got 40 engineers and we're struggling to figure out how to keep everybody on the same page about, like, we're moving this way, but when do they decide to refactor existing approaches? When do they start moving towards the new thing? When do you just make three-line code changes to an old way versus let's revisit this and move it over to the new way, the pattern of how we want to start moving this?" LLMs, I feel like, might expedite some of that, but also, how do we make sure that they're doing the same thing and everybody's on the same page there? But tell me a little bit about your team's experience with, like, are you using service objects, or in the past, or how do you organize a lot of that type of business logic in your codebase?
I think there's a few different touch points along the way to make sure that your code and your team stay connected with what you want to be doing. And I think the earlier you catch that, the better. As we get epics and feature work to be done, I like engineers going through and scoping those, like writing those tickets out, thinking through the potential from a UI through backend and deployment strategy. I think it's really important to kind of touch base with, like, hey, this is how we think this should go. You know, someone on the team will review that. Usually it's me, but it can be someone else too. Like I said, yeah, this is the direction we want to go on this, and there's not going to be any sort of ambiguity about how we want to architect this thing. And then the code is written, through whatever means the code is written. And then kind of the final touch point is our code reviews.
And I view a PR as even more important than they used to be, because 10 years ago you knew that this PR was written by a human, or perhaps copy-pasted from Stack Overflow, or maybe a really proto, like, Tabnine LLM or something was happening at the time. And now it's code that someone has written perhaps through any means, and that's kind of our final check to make sure that everything is kind of what we want it to do from an organization and architecture perspective.
And that's where we have Copilot give it a review for the small syntax stuff. I really expect that anything we push out to production, there's going to be an author and then there's the PR approver, and I view them as equally responsible for the code that goes out, because that is our backstop. And it does give us the opportunity to say, hey, I think this should be done a different way, or let's discuss this. You know, you used a certain type of service that we're not using anymore, or we don't really do this anymore. And I think it can help spot things that LLMs are making too, because sometimes you're just so steeped in whatever you're making, you're not able to fully back out and see what decisions it's making. And that really helps, having another person in that loop.
Ever wish you could ship a feature and have someone talk you through it like you're wandering a conference hallway pretending you're just grabbing water? Introducing the On Rails CLI with on rails generate:podcast. Just run one command and it generates a brand new podcast episode custom-made for the exact feature you're building right now. Are you building approvals into your application? You get a 34-minute deep dive on state machines, audits, and regret. Refactoring a controller? Congrats. You've got a calm voice explaining why it grew and a slightly worried voice asking why it's still alive. And yes, it's like having me and Obie Fernandez in your ears arguing politely about the exact trade-off you're about to make, because it's trained on hundreds and hundreds of hallway conversations from conferences, meetups, and those late-night "Wait, how did you do that?" moments. It even adds tasteful sponsor breaks like this one that you didn't request, but honestly, you kind of deserve. Use the On Rails CLI to generate your next podcast, because pairing on a feature is great, but pairing with me and an AI-generated podcast guest is probably inevitable.
Maintain confident opinions, gentle disagreement, and occasion. Not responsible for shipping features because the episode made it sound easy.
So, I'm going to switch gears a little bit, Nikky. So I know that Shop-Ware, we had a previous conversation, kind of like prep for this, but I know that Shop-Ware has an API that your customers can interact with, right? And that's part of your architecture. So, how does that fit into it? And I know that you also handle a bunch of integrations, but can you tell us a little bit about how your API is designed and how that's been approached over the years?
So we have a public API, and it's public in that both users of our application can use it and also some third-party integrators can as well. And the API has also grown a bit organically as well. And when it was first created, the decision was made to have essentially two separate codebases.
We had a codebase for the API and we have a codebase for the rest of the Rails application. We regret this decision. I think we regretted this decision almost the minute it was made, and it causes us a lot of grief in that we essentially have a lot of duplicated logic between the two. You make a model change on your main application, well, now your API application has to know about that. If you have a validation, your API needs to know about that. If you make some sort of service helper that does some sort of dynamic calculation, well, your API needs to know that too. That's been a big morass for us that we're trying to unwind in a way that doesn't take our API down in the meantime.
I'm assuming that you have a lot of models and things like that in your main Rails app that don't exist in the API repository. What's been the pattern? Have you needed to use Git submodules? I've seen a lot of teams use a lot of different approaches to try to keep their models in sync across two different codebases. Or is it literally just some copy-pasting every once in a while of certain methods, or a little bit of everything?
There's a fancy way, and we have some automatic script syncing that will sync over our model code and our schema file, and that's helpful to keep us somewhat honest. And there's also been some copy-pasting too when we need to bring in some additional service-level calculators.
So how tightly coupled is the Rails application to the API layer then? And how does that workflow go? If your end user is hitting your API, is that then connecting with its own connection to the same database, or is it connecting as a read-only type of thing, or is it talking to your main app as well?
Yeah, you nailed it. It's exactly that. There's read-only connections and there's also a main application connection as well, which helps with ensuring the right access and data integrity roles that we're trying to enforce.
So if there's like a POST that comes through your API, what does that life cycle look like for the request?
That makes a separate POST request to our internal monolith APIs that will then actually make that request, and then usually on the read back it will come through our read-only connection.
Do you have like a proxy or anything between the two to handle that, or is it just a different host name, or how do things get routed based off of the requests?
They're just secret APIs.
The secret API is that your API is then passing on the right action to your secret API, or is...
Yeah, essentially when the right request comes through, the API app is essentially a proxy for the main application.
Okay. So it just turns...
It just passes the request on without a whole lot of other things.
Are there internal consumers of that API?
Nope.
Interesting. So in retrospect you maybe regret doing that. Is there an effort that you've attempted a couple times at all to try to bring it back all into the same repository, or...
We're in the nascent stages of rethinking how this should be rearchitected. But there's a broad consensus on our team that the next time we need to do a major effort inside the API, we'll move it back into our main application code.
I mean, a lot of the other companies I've talked to so far on the podcast have mentioned GraphQL. Has that been part of the conversation at all?
Yeah, so a lot of our API work was done prior to the GraphQL world becoming popular. So we're still a REST-based, RESTish-based architecture. And I think the same model of what we have now is working for us. There's no need to move us to GraphQL. If we did it brand new, we would choose GraphQL, I'm sure. But what we have is working, and there's not a huge push to move things to a new architecture, and there's not really demand inside our ecosystem for that. But, you know, we certainly gaze at GraphQL with wistful eyes sometimes, at the flexibility and capability it could give us.
I know that APIs tend to reveal a lot about how systems evolve. Were you around when that decision was made to have it be a separate repository? That sounds like it's probably...
I was not. Yeah, there's a little bit of archaeology here.
I can kind of get why teams might have considered that at one point in time, but I can definitely see that being a challenge, and maybe LLMs will help solve this problem for you at some point and you'll just be like, "Yeah, just migrate everything over, right? It's gonna be super easy."
It's very possible. Yeah.
So another topic was that, you know, while preparing for this conversation, you mentioned I think the engineering team right now is around 10 people, but it's also smaller than it once was. Can you remind me how large of an engineering team it scaled up to at one point, maybe at its peak?
Yeah, we were probably double that a few years ago. There was a lot of different concurrent effort to build new things and get new applications up and running, and then we kind of scaled it back a bit. And, you know, I think it's never great losing colleagues and realizing that that can happen, and I think you lose a lot of institutional knowledge in that process despite your best efforts. We try to have really good documentation internally, we try to have everyone kind of cross-trained, we try really hard not to have silos, but it happens. And when it does, I think Rails can help us gain that knowledge back a bit, in that it at least forces you to be a little bit more organized with your code, and so you're not completely lost when you're trying to figure out something new, new to you I should say, and how it's operating. You know, when a colleague moves to some new position, you always lose that, and Rails helps us part of the way, but not all the way.
Do you feel like with a smaller team it changes how your team prioritizes work amongst yourselves?
I think it's just less work that scales. I mean, as you envision a mature application that's been deployed, you always have X amount of hours that's set to DevOps and DevOps-like things. On a larger team you can allocate that out more; engineers are on call less, engineers, you know, expect X number of hours a week, a month, a quarter, whatever, working on that infrastructure work. But infrastructure work is essentially the same whether it's a team of 10 or a team of a hundred. And so as the teams get smaller, you're looking for more ways to make infrastructure be as efficient as possible, because it has more of a cost to the business when you are not taking the care and intention to have that be really efficient. And there's always defects as well that come in, and defects are somewhat correlated to the amount of features you're pushing out. So if you're pushing out fewer features, your defects should be scaling accordingly. But
we also have a lot of integrations with third-party vendors and third-party suppliers, and they are also upgrading their APIs. They're upgrading the way that they handle things. Maybe they're an old SOAP-based interface and they're like, you know, it'd be really great to not use the SOAP interface anymore. Could you upgrade your integration that you built a decade ago? And we're like, sure, but, you know, that's something that a now smaller team has to spread around too. But I think as that happens, integrating with APIs is really, I consider, an LLM's bread and butter. As engineers, we're doing that constantly, and being able to just say, here's an API, can you kind of give me a sense of how it works, what the framework is, what we need to do to integrate with it, is really helpful, getting us from the first step to maybe the first 10 steps, and getting that...
No process solved. I think that's a really good example of a good use case for anyone listening out there that's maybe a little skeptical of experimenting with LLMs. I feel like that is a really good use case, especially if it's a publicly accessible API; you maybe don't need to reinvent the wheel. I'm curious, how does your team think about when you might bring in, say, a Ruby gem that maybe already integrates with that API, if that is the case? That might not necessarily be the case with the specialist industry that you're working in there. But are you able to leverage Ruby gems very often for things like that, or does your team have an opinion about Ruby gems? Some Ruby gems can potentially become a blocker for us in the future, because you're kind of taking a little bit of a bet on: will this gem be maintained in four or five years when new versions of Ruby come out, or am I going to be the one having to maintain this myself as a team?
It's rare for there to be an off-the-shelf gem for us with a lot of these integrators. I can't think of an example where we're able to fully leverage that, which is nice in some respects, because, as you mentioned, we do have control over the integration code. We know exactly what it's doing. We're able to configure things the way we want them to, follow best practices, and be very defensive about it in a way you don't always get with a gem, or with something you pull in for that gem even though it's not entirely what you're looking for.
That's fair. And I think I can imagine, as I said, you're working in a very specialist industry where there might be not a lot
of other Ruby teams needing to integrate with these different automotive related industry platforms. I'm guessing you're integrating with... Can you give me an example, one of those, what might be a couple of integrations that would be atypical for a typical Rails developer to ever need to encounter?
Yeah, I doubt most Rails developers will be purchasing automotive parts from wholesalers in the way that we would be. And I don't think many developers will be pulling in data from, you know, motor vehicle lookups. There's this huge amount of data that the auto industry has around standardization of your vehicle, where you look up your vehicle's VIN and there's IDs associated with the engine, the transmission, the submodel, the trim, your transmission type. The amount of data that they pull from these VINs is really incredible. And you know, there's like, I don't know, 50 people consuming this probably in the world, and there's just a few providers out there for that.
And a lot of the, you know, Shop-Ware is one that's a little bit newer on the block. It is cloud-based. A lot of the older automotive platforms... One of the earliest applications of desktop computers back in the 80s was automotive shops, because they needed to keep track of these things even back then. And so there's a lot of these shops who are using, you know, pen and paper notebook systems, or they're using Windows XP or Windows 95-based terminal applications and went away, but they still maintain it because that's the system that works for them.
Yeah. And migration is huge, and it's all those little nuances about how you deal with that and how you bring a lot of these shops, kind of having them recognize there is a lot of value in moving to a doer system from what they currently have and what they're running.
Is it safe to assume that if you're onboard... is it typically individual shops that are acquiring this, or is it typically an entity that owns multiple shops, or a combination of that?
It's a combination of that, and they'll typically, unless they are a pen and paper based business, they're bringing in data from some other system. And so data migrations are a big part of that, where we really believe that you'd be able to both import and export your data, and we really try to make it as easy as possible to bring in your data. But again, there's a myriad of systems, some of which require custom care and attention to bring in their data from whatever database they had in the past. And in some ways it's not even really possible. It's just so far and so different from what we'd be experiencing. But yeah, I'd say it's a combination of really sophisticated shops coming on board and shops that are just getting started but know they want to be a sophisticated shop.
So I imagine then, if you've got one of those, your team, your organization has an onboarding process to bring in and help them migrate and import their data into the thing, and that's part of the value out of working with Shop-Ware.
Okay. Yeah. Exactly it.
Out of curiosity, is there a lot of very custom code in your codebase that's specific for, like, hey, specific customers or clientele need some specific features that your sales team needed to negotiate? And so, are there conditionals in your codebase or feature flags for specific... this huge tire company, we need to do this one special thing for them. Is there a lot of that in your codebase?
We try really hard, where if there is a request that someone is asking for, we try really hard to evaluate that. And if it's something that makes sense for a larger group of customers, that's something that's just available to a larger group of customers as well. Like, you know, I want feature A, B, and C. Great. Features A and C are super relevant to a lot of people. Feature B we can get on our road map and we can think about it. And I'm not too privy about how our product team is doing a lot of those prioritizations, but we generally tend not to have tenant or shop specific code in our codebase, because every time you do that you're doubling the complexity of your code.
But it happens a little bit.
It can happen a little bit.
Yeah, I've just seen, you know, working on the consulting side of things, we'll come in and help companies, and I'm always refreshingly, like, I suppose, I guess there's a little bit of comfort knowing, oh yeah, at the end of the day, even a SaaS platform that's trying to present itself as, hey, this is out of the box, it's going to do all these things, there still tends to occasionally need to be these few exceptions to the rule that they'll do. Like, hey, this is something we're going to spend a bunch of initiative on for this one big customer that's going to bring 50 automotive shops into the platform. It's going to be worth it to have this one thing that we might not be ready to roll out to everybody else, but let's get it in there for them so we can get them in the door, and then we'll figure out how we can roll this out for other people or not. But some companies don't always have an opportunity to go back and refactor that or roll it out to everybody else necessarily. But anyway, I was kind of curious about that.
Yeah, I mean, we use feature flags a lot, and we get an opportunity to roll things out to early adopters. And if someone is really pushing for a feature, then yeah, we can roll it out early because of feature flags, and they can go into an early access type thing, which is really helpful for vetting how that feature works. And then once it all seems good and everyone's happy, then we can roll that out to larger groups and just all the shops at large.
Are you using any specific tooling for feature flags, or is it just something kind of homebaked?
We use LaunchDarkly.
Okay.
Which has worked out really well for us. It took us a few years to kind of get our workflow down and get everything working the way we wanted it to. But now that we're on it, we find that really, really helpful.
Who gets to control when things get turned on for everybody else? Engineering decision or product team?
Yeah, our product team does, which is really great, because we're able to do really frequent deploys knowing that new UI changes and logic changes are behind feature flags. And so our product team can roll those out, you know, on a per tenant level. They can roll them out to everybody. They can turn them on and off. And it's completely decoupled from engineering, which is really, really helpful for us.
And we still have some permanent engineering flags as well. We have a lot of third party integrators, and we have kill switches for those. Let's say an integrator goes down and them being down causes parts of our application to be really slow or not responsive. We can shut that integration off via feature flag until that integrator comes back online.
That's interesting. What's your deployment strategy look like then? With your infrastructure, does everything kind of get deployed? Are you doing canary deploys or anything like that?
When I first joined, we were doing, in theory, bi-weekly deploys and releases, and that was a process that everyone hated, as far as I know, for a very long time. And there was a huge QA regression test that happened that lasted like a week, and sometimes they would find bugs, and sometimes features we'd need to go in that were promised, and we'd have to, you know, shove them in at the last minute and hope they don't break anything, and delay the release candidates being cut until they were merged in. And there's just a lot of stress, and if you missed that, then you had to wait two weeks for the next release, and bugs didn't get fixed for two weeks unless it was a really important bug and you did a special release for it. And that was not working.
It took a ton of engineering time. The QA time was exceptionally large. Product wasn't happy because things were being released really slowly, and a lot of trade-offs are being made when you do a waterfall deploy like that. And so we switched a few years ago. We had a pretty big discussion about the pros and cons of switching to a daily deployment, where the code is deployed, you know, daily by an engineer, and almost all of our engineers are deployers, which means they're also on call. They're really close to this production server, which is great.
And that's worked out really well for us, because we can push out bug fixes a lot faster. We can push out product changes incrementally. You know, as we kind of finish tickets on a particular feature, we start rolling those out, and that code is being exercised in production early, and it can be turned on for early access for testing tenants way early as well. You know, as these things get rolled out, our product team can verify that on the prod environment in a testing tenant really easily.
I think it gives a lot of developers another sense that their backstop is gone. There's no more, you know, large manual QA regression testing happening for each release. The code that you write, you really need to think defensively about it and really think about the implications it has for your production queries, for your production third party integrations. And it's really good. I think we are finding people much more cognizant of those trade-offs and being really, really careful about what they do push out, and overall I think it's been a big success.
We spend a lot of time deploying. We spend much more time doing targeted QA against things that actually matter. We are able to even have, I think, decreased defects, because we're not pushing code out anymore to meet this two week window. We can just push that when it's ready and we're really, really confident in it, and if you need to roll back code, it's just a day's worth versus two weeks.
I really like to hear that as a reinforcer of, let's say, better habits for software engineers, to think, we're going to be deploying more frequently, so the stuff we're working on really matters. We need to show up, do the work, do our due diligence, and push things out, and know that we're going to get quicker feedback. Because there's a lot of teams out there, and maybe a lot of people in the Rails community listening might be like, ah, that sounds wild, why would we wait every couple weeks to deploy? Rails just makes it super easy. But there are companies that have to slow things down for regulation reasons, stability things. There are reasons for that, legitimate reasons.
But if you don't have to worry about, like, we need to queue this all up because it's really difficult to work on... say a ticket, I'm going to work on a bug or something or a new small feature change, and it's going to take a couple weeks before it goes through QA and gets deployed, and then maybe a bug comes back. What was I working on three weeks ago? You know, it's difficult, versus what was I working on earlier today or yesterday? That context is there, so you can quickly go, oh, you know, I forgot about that one little thing, and you can hopefully get that addressed in the next day or so.
It's refreshing to hear that your team was able to do that, and to do that with a much smaller team. Do you think there was any correlation to you having a smaller team making it easier to do that? Do you feel like when you're a couple times the size, maybe slowing things down is a safer thing to do, or do you feel like it would be ideal regardless of your team size now?
I have a couple thoughts, and I think one of the really interesting ones is that, you know, we are in a business that does really value stability. These are, you know, auto shops where, if our application doesn't work, their businesses don't run. They're not repairing vehicles. They're not seeing new customers. They can't have customers pay them. They don't know where these cars are. They can't order parts. It's really huge. And stability is something that we care a lot about, and we spend a lot of time thinking about, and we take all these incidents really seriously, because there's a real human cost to these things when things aren't working right.
Also, I think that team size doesn't matter too much when you're dealing with these more frequent deploys, as long as everyone's on the same page and really buys into the idea that the code that you push is really close to production. There is a QA check to make sure that the things you're immediately touching are good, and then you're out. And then, you know, you make really sure that your blast radius... you're very blast radius sensitive, because you have to be, because you know that if things go sideways, you're going to be the one who's getting paged, who's getting asked a day or two later about what happened.
As you mentioned, it's also really beneficial because you're super close to the code. You release something one day, you see a new Sentry exception the next, you're pretty sure you know what you did and how to fix it, versus if it's a couple weeks ago, you might be on a whole different epic at that point and you don't remember anything of what you did. Hopefully you do, but you might not. And so yeah, it just keeps that loop much, much tighter, which we found really, really helpful for us.
No, I appreciate that. I'm curious about, you know, you brought up Postgres earlier. Have you had any scaling issues at all with your database, or needed to do anything? Are you integrating with any other tooling for reporting type tools that your business and product teams can get access to? I've talked to a couple people on the podcast so far where they've talked about how they've needed to push some data into different platforms so they can extract and build reports a little quicker, so that engineers aren't having to write a bunch of custom reports themselves and some backend interface themselves. How does your team kind of approach that these days?
Yeah. So we love Postgres for a lot of reasons. We don't love scaling Postgres for a lot of reasons, but fewer reasons than why we love it. One of the things that you are kind of taught when you create a Postgres database, or any sort of relational database, is that connections are really precious and you want to keep your connection counts as low as possible. You want your connections to be utilized near 100% of the time. There's that balance there, because those new connections are expensive, and especially in Postgres land they're really expensive computationally-wise, memory-wise. It's a whole thing.
And so the kind of comical answer for that is you use a connection proxy. Has one, most things have it. PgBouncer is kind of the big one for that. What they don't tell you is those can also have CPU saturation, and it's extremely not observable when that happens. And we've learned over time that maybe we don't fear connections as much as we used to.
I remember, you know, 10, 12 years ago, starting with Heroku, there was the idea that you had, I think it's like 20 connections or some really small limit. And so we tried really hard to use all the built-in tools that Rails gives you, and connection bouncers, to get that as low as possible. And then you spool up a bouncer. Now things are different in a weird way. And you say, you know what, I'm going to embrace connections again. We're going to go back and make sure that we're using the Rails way of managing connections. And that's okay. And maybe we'll have a little bit more, but we know that our application is going to be stable and not saturating related middleware that causes our application to basically go down in the meantime.
Quick question. Are you running this on Heroku? Mhm.
>> Is it safe to say that your team is evaluating your hosting options at this point, or
>> It is very safe to say yes.
>> For our listeners, we're recording this in the middle of March, and I think it was maybe four or six weeks ago, give or take, Heroku kind of made it very clear that they were not going to be investing a lot more development efforts on evolving the platform, period. I think it was kind of like, and you can read between the lines, that like that's potentially an issue. So maybe you haven't made a decision on that yet, but how is your team kind of navigating that conversation right now? Have you landed on a destination yet?
>> Yeah, that's something we started pursuing last year. I think we all read the writing on the wall after the last few incidents over the past couple years, with Heroku not really expanding their offerings, staying pretty limited in what they were doing. It definitely seems like an application in maintenance mode, where they're maintaining what they have but not really adding new features. And yeah, we're evaluating still, and that's something we're hoping to do within the next like year or so.
But I think that the very obvious answer is something like AWS or something similar, where we can just run, you know, on a container and scale up and down and do all those things in a way that is more flexible for us too. You know, our workload is extremely time dependent. Like, we mostly run United States-based shops, and those shops are open, you know, 9 to 5 across various time zones, and at night we have this very large, beefy database that is essentially being unused, because nobody's repairing cars at 3:00 a.m. Pacific time.
>> Sure.
>> So I think there's a lot of opportunity for us to kind of have a lot more intelligent resource scaling. Most existing platforms are a little bit more modern than Heroku, which has essentially remained unevolved for like the past, you know, 10 or 12 years. I think if you open it up today, it'd be very familiar to you if you had just learned about it in 2010.
>> Agreed. As I was just helping a client, we were literally just working on this a couple hours ago before I got on this call. I was helping navigate some plans for one of our clients there on that front. So curious to see, maybe we can check back in with you and see how that migration went. And out of curiosity, are you deploying with containers at the moment, or is it just using the default Heroku stack at this point?
>> We've been spoiled and we've just been using the default Heroku stack, and there's a containerization effort in progress, because that's like the first step to getting us into something more dependable.
>> Okay. Touching back on the database thing real quick. You mentioned multi-tenant. Are you doing that all within Postgres? Do you split up your database at all between different instances, or are you primarily running one just huge database at this point?
>> Yeah, just one huge database, and there's a lot of benefits to doing that. It all runs pretty well when it runs well, which is almost all the time. But there's also some scaling things too. As we've mentioned, some tenants are quite small and some tenants are really, really large. And so you can imagine your indexes can be potentially a little bit unbalanced and large, unwieldy to maintain.
We've experimented with some tooling around like Postgres partitioning, where you can partition tables based off your tenant ID, which caused issues in Heroku's Postgres because we don't have full access to all their really fancy administrative tools. So some things we wanted to do weren't really possible, and so it was kind of workarounds upon workarounds, and we're like, this is not really tenable in Heroku land. We were hoping to be able to do it in AWS land, because that is something we're really interested in, having those much more sharded out and kind of isolated from each other.
>> That's something that definitely a number of the guests so far have talked about, needing to kind of split those out a little bit, and some of the scaling. But some of those guests talked about how they basically were reaching AWS Aurora's size limit, and so they needed to split it up just because they were hitting size limits within AWS itself. So maybe a different sort of scaling issue on that front, but knowing that your smaller customers could potentially be impacted by your larger customers at the same time, you definitely want to be mindful of those types of things.
All right, Nikky, I want to shift gears a little again real quick with you. I'm curious. Let's just say hypothetically you had a new engineer starting tomorrow and you needed to be gone for the next, say, six months, and a very competent Ruby on Rails developer was going to join. They have years of experience. They're going to come in and help work with your team while you're gone on your sabbatical. Well, much deserved, by the way. And you needed to leave them a letter and be like, "Hey, new developer, let's call them Shannon. Shannon, you're starting tomorrow, and it's a typical Rails app, big app, a lot of typical things you might see, but there's this one very atypical thing that we've done that you might want to know about." What would you leave in that letter for them about what's going on in the Shop-Ware codebase?
>> We have asynchronous update support, which is a very common thing for applications, and we don't use Action Cable to do that. It was all built pre-Action Cable, and we have a third-party service provider that provides all of this, and it trips up a lot of people new to the codebase, because I think the assumption is you're using Action Cable or you converted over to it, and we are not.
>> What's this third-party service, out of curiosity?
>> I think it's called Stream, just some org that did these things because Rails didn't have it built in. So
>> I see.
>> we ship it off to them instead.
>> What does that workflow look like then? Is it just passing things, like outsourcing some background jobs in a way, or
>> Yeah, that's essentially it. We have to make an async update. We have this third-party code that we integrate that will open the websocket, and then it listens for updates from this third-party provider, and then we push an update to this provider, who presumably runs like Redis or something, to send those updates along. It's essentially Action Cable, but we're doing it pre-Action Cable.
>> Oh, I see. Okay, fair enough. So I really do appreciate you coming on the podcast to talk shop with us and share a little bit about the Shop-Ware platform. So I think you're talking shop about the Shop-Ware platform. You've definitely shared a lot of things with our audience today on how a small, mighty team can still maintain things even with a smaller team than they maybe used to have, and just getting a sense of how different companies are using Ruby and Rails and deploying that out in the real world.
So I have a couple of quick last questions for you, Nikky. Is there a non-technical book that you find yourself recommending to teammates or peers over and over?
>> That's a really good question, because I actually have it right here. I wasn't expecting this question to be asked, but I really like a book called Digital Apollo. It's about the design and architecture of the Apollo DSKY. So the guidance computer that was conceived and created in the 1960s, and kind of one of the first pieces of computer hardware that was both mission critical and really well known to the public.
I love it for a lot of reasons. I think it's a great text, kind of reminiscing on where we came from and how these decisions that we're making today are so really relevant to ones that were being made like 30, 40, 50 years ago, and the things that our predecessors have done are still informing us today.
>> Who's the author for that?
>> Let me see that. Let me see that book. We got video here.
>> It's just a... I don't have a... we take off our card cover, so
>> Okay.
>> It's just called Digital Apollo by David Mindell.
>> Okay. We'll definitely include a link for that for our listeners in the show notes. David Mindell. Excellent. And where can folks follow you? Does Shop-Ware, does your team have an engineering blog or anything of that sort? Do you stay active online?
>> We have no blog. We have no socials.
>> Perfect. Well, we'll definitely not include a link to that in the show notes for everybody. And with that, Nikky, it's been such a great conversation. Thank you so much for stopping by to talk shop with us on On Rails.
Yeah, great. Thanks, Robby.
That's it for this episode of On Rails. This podcast is produced by the Rails Foundation with support from its core and contributing members. If you enjoyed the ride, leave a quick review on Apple Podcasts, Spotify, or YouTube. It helps more folks find the show. Again, I'm Robby Russell. Thanks for riding along. See you next time.
Article published
