Code with Jason

242 - John DeSilva, CTO at Revela

Jason Swett

In this episode, we reflect on the shift from remote work to in-person connections and explore Detroit's transformation into a vibrant place to live and work. With guest John DeSilva, CTO of Revela, we discuss his company’s growth from a basement startup to success with Ruby on Rails and the challenges of upgrading apps with Turbo. We also dive into database design, managing outdated data, and the surprising value of old-school technology in today’s world.

Speaker 1:

Life hasn't been the same since the pandemic. Instead of working at an office around people all day, like we used to, most of us now work remotely from home, in isolation and solitude. We sit and we stare at the cold blue light of our computer screens toiling away at our meaningless work, hour after hour, day after day, month after month, year after year. Sometimes you wonder how you made it this far without blowing your fucking brains out. If only there were something happening out there, something in the real world that you could be a part of, something fun, something exciting, something borderline, illegal, something that gives you a sense of belonging and companionship, something that helps you get back that zest for life that you have forgotten how to feel because you haven't felt it in so long. Well, ladies and gentlemen, hold on to your fucking asses. What I'm about to share with you is going to change your life. So listen up.

Speaker 1:

I, jason Sweat, host of the Code with Jason podcast. I'm putting on a very special event. What makes this event special? Perhaps the most special thing about this event is its small size. It's a tiny conference, strictly limited to 100 attendees, including speakers. This means you'll have a chance to meet pretty much all the other attendees at the conference, including the speakers. The other special thing about this conference is that it's held in Las Vegas. This year it's going to be at the MGM Grand, and you'll be right in the middle of everything on the Las Vegas strip.

Speaker 1:

You got bars, restaurants, guys dressed up like Michael Jackson. What other conference do you think you can go to, dear listener? Or you can waltz into a fancy restaurant wearing shorts and a t-shirt, order a quadruple cheeseburger and a strawberry daiquiri at 7 30 am and light up a cigarette right at your table. Well, good luck, because there isn't one Now. As if all that isn't enough, the last thing I want to share with you is the speakers. And remember, dear listener, at this conference, you won't just see the speakers up on the stage, you'll be in the same room with them, breathing the same air. Here's who's coming.

Speaker 2:

Irina Nazarova. Oh yeah, chris Oliver oh yeah, jason Charnes, fafridum Dumlao, prathmasiva, fido Von Zastrow, ellen Rydal Hoover and me.

Speaker 1:

There you have it, dear listener, to get tickets to Sin City Ruby 2025, which takes place April 10th and 11th at the MGM Grand in Las Vegas. Go to sincityrubycom. Now on to the episode. Hey, today I'm here with John DeSilva.

Speaker 3:

John welcome to the show. Thanks for having me, Jason. Good to be here.

Speaker 1:

Good to have you. So you and I saw each other at RailsConf in Detroit. That wasn't the first time we met, but it was kind of a funny occasion because we met really briefly in Detroit.

Speaker 3:

I don't know when, but some number of years ago, maybe a lot of years ago and then we just like ran into each other at RailsConf all these years later yep, I was trying to figure out what that was, because there was a decent turnout, I think, at that event, but I couldn't remember who was running it. I couldn't remember who was running it, I couldn't remember who was attending it, and so we recently had a Ruby meetup in Detroit and I was trying to scour all of my known lists of Ruby people and it would have been helpful to know what that event was. But it's been purged from meetup and so, yeah, I think we also probably were um contemporary at like in our ruby brigade at some point, maybe, maybe not yeah, um.

Speaker 1:

So for background, um, john, you live in? Well, I think you live in detroit do you?

Speaker 3:

do you live like? Actually in detroit in detroit, detroit, yep. Yeah, I used to say that I lived in Detroit and people would be like, no, you don't. But now I actually do. So, yeah, I'm in what they call North End, which is it's Detroit proper. It's like two miles up from up Woodward, from the center.

Speaker 1:

Yeah, Okay, yeah, and, dear listener, if you're not familiar with Detroit, when you ask people where they're from and they're from that area you know it's kind of like there's a like prestige or street cred or whatever that comes with being from Detroit. So people like oh. I'm from Detroit. It's like, oh like, where exactly? Oh, like Bloomfield Hills. It's like OK, that's not Detroit at all, but yeah, nice try. That's not Detroit at all, but yeah, nice try.

Speaker 1:

But you live in actual Detroit and it really is, I think, more common now, because there was a time period when obviously Detroit took a huge economic dive and the population really shrank. But there's been a huge economic revival and now it's like a really sought after place to live. I understand.

Speaker 3:

Yeah, I think it really is. Um, I know a lot of people just like to kind of show their their hometown, but Detroit actually is really nice by now. Um, especially the downtown area, the riverfront. Um, I'm sure you saw some of that at rails conf. Um, we have some nice weather days, so when the weather is cooperating, um, it is a very nice night city.

Speaker 1:

Yeah yeah, yeah, I like it a lot. I used to teach a class in detroit. That would happen each summer and I would stay there for like five weeks. Um, and for context, if anybody doesn't know, I live on the other side of the state. I live in the Grand Rapids area, which is like two and a half hours away from Detroit. So I would like drive to Detroit and teach this class during the week and then drive back home on the weekends, which was like kind of tough because my kids were really young at the time and I felt like really guilty for leaving so much of the time. That was one of the reasons I stopped teaching that class. But I did it for three years and I really, really enjoyed Detroit. It's like I don't know the people in Detroit just like give off like really different and positive vibe.

Speaker 1:

I feel like and obviously that's not going to be like that's kind of a blanket statement. That's not going to be like that's kind of a blanket statement. That's not going to be true for all areas of Detroit, but that was at least my experience when I was there yeah, um, there's a good sense of community and I think, um, it's there's a good sense of entrepreneurship here too.

Speaker 3:

it's always been tough because there's been lack of resources, but everybody is like trying to start something, or they got a group going or like a collective or a meetup. It's a good environment for that, and now, you know, we're seeing some more inflow of dollars, which has been helpful for, you know, actually getting some of those things off the ground.

Speaker 1:

But there is a big sort of grassroots vibe here and I think, um, you know, detroit was struggling kind of for a while and it it bred sort of an interesting culture of people that are pretty, pretty resilient and focused on sort of the small things I would say, um, so, yeah, it's a, it's a great area um, okay, and so we were talking about we met at at RailsConf in Detroit, and this is one of the many podcast episodes that that conference stirred up for me and I want to know a little bit about your personal background ago, and then we saw each other, um at rails conf, but we haven't gotten to spend a huge amount of time conversing yet. So, like I know that you're the cto at revela I don't even know if I'm saying that right, but can you tell us a little bit about revela and yourself?

Speaker 3:

yep, um, yeah, revela, it's like the I didn't come up with the name, but it's. It's the latin sort of pronunciation, I guess. I don't even know if that's true, but yeah, um, so we're, we're real estate software. So, um, it's very erpe, so I won't bore you with the details. It has a lot of reporting and things like that, um, but ultimately, our customers are people that, um, manage apartment complexes, manage single family homes, manage rentals. So, yep, that's a lot of maintenance, logistics, accounting, reporting, payment processing, things like that.

Speaker 3:

We've been around for a little over 10 years, or our 10-year anniversary is like right now, I think. So my business partner Grant had a little bit of a head start on me. So my business partner Grant had a little bit of a head start on me, but I've been working on this since 2016. So, yeah, it's been a lot of Ruby programming.

Speaker 3:

When I was in college, I was sort of already in love with Ruby and I knew that I wanted to work on a large Ruby code base or build a product out of like a Rails app basically. And so Grant kind of showed up one day, pitched what he was wanting to work on and kind of told a compelling story, and I was pretty naive. I was like, oh, it sounds easy. Like I'm a Rails programmer, I guess it'll be no problem Get that done in a couple, couple of weeks. But here we are, you know, a decade later kind of working on it. But, um, yeah, we've grown to a good size, we've got um around 30 employees. So it's cool to see um, see that grow and sort of come to fruition at this point. You know, we started in grant's basement, then in a warehouse, then a co-working space, then, um, now we're finally in a proper office. So it's been rewarding.

Speaker 1:

It's been a lot of work, a lot of Ruby and how many developers.

Speaker 3:

We're around like call it. We just had somebody start yesterday, so I think that we're up to like six now. Yeah.

Speaker 1:

Okay, and I'm really curious about the like evolution of the code base over that period of time and the challenges that you've had along the way and the ways you've addressed that and stuff like that. Obviously, that's a huge question and we could spend so long discussing it if we wanted to, but feel free to take that question in any direction you want.

Speaker 3:

Yeah, I'll give it a gist. Um. So when when I started it was, uh, rails four days. Right, this would have been um just before, I think, rails five came out.

Speaker 3:

So tail end of rails four um and at that time I was sort of considering what my options were. I loved Ruby, I knew Ruby, I knew Rails pretty well at that point already. But there was some other sort of things in the space. Right, there was Elixir. Phoenix had just kind of come into popularity a little bit. I also knew Java. So I was like maybe this could be a Play 2 framework or that, or maybe even Scala. And I even looked at Rust at the time was kind of also brand new in terms of the mindshare, but it didn't really have like a web story yet. So ultimately I went with Rails and I'm glad I did. I think I would make that decision again Because a lot of those things, uh, haven't really changed.

Speaker 3:

Rust still doesn't have a exact out of the box story, um and whatever, um, but anyway. So we started with rails 4 and I think honestly that was a blessing, because I think, if you, if you know rails and you've known rails, for a blessing, because I think if you know Rails and you've known Rails for a long time, I think the hardest transition probably would have been 3 to 4, maybe 2 to 3. There weren't a lot of Rails 2 apps out there, I don't think, but anyway, I think probably the hardest transition would have been 3 to 4, because that's when they changed mass assignment, that's when they changed from adder accessible, I think, to permitted for RAM. So we didn't have to go through that and I think at that time sort of the full stack of Rails was pretty well defined, except for, I guess, the front end. So Rails 5 came out. Um, and I think that is when web packer happened, or was that six?

Speaker 3:

I don't remember, I don't remember, but so we were already on, we were already using web pack sort of in a bespoke way, um, and so we didn't have to do the Webpacker thing either, and so by the time Webpacker was gone it was like, well great, we never had that. So I think not a lot has changed in the code base in terms of Rails architecture, except for, I would say, the front end would be the most interesting place. So we started out with some React of Rails architecture, except for, I would say, the front end would be the most interesting place. So we started out with some React and that was React 15, 16 at the time, which sounds like a high number, but I think that was still really early days for React and turned out to be not super productive, at least for me.

Speaker 3:

I was not a great React programmer and we tried to build some fancy interfaces but ultimately kind of stopped doing that and we tried to stay towards simpler tools, simpler server-rendered traditional Rails interfaces and had better luck sort of building our own internal components library. I'd say this also was before Vue component. And so now at this point we've adopted Vue component, which has been, I would say, positive, and we've adopted stimulus, which I would also say has been positive and we're on the latest Rails but we don't have Turbo yet, so we're kind of stuck with Turbo links for the moment. So often a problem comes across our desk and it's like wow, that would be real swell if we had Turbo. It'd be a no-brainer.

Speaker 1:

But don't have that yet, JOHN MUELLER. What's the?

Speaker 3:

obstacle to that I would say that we Okay, here's a Rails 4-ism.

Speaker 3:

If you remember the switch from form4 to formWith and then local true, remote true, local false, that switchover we stuck with the Rails 4 default, which is all of our forms are not remote by default. Most of them we turn that on for, but there's some out there that I think either the test suite or it's probably the test suite kind of silently breaks, because when we switch to Turbo it introduces kind of like a raise condition about where Kavibar would have previously waited for a form submit to happen and now doesn't. Maybe it sounds like your flaky test podcast, but I think it's basically just that we have some forms that don't seem to play nice when we flip on Turbo. Other than that, it's a big find and replace kind of task. All of our you know document on turbo load becomes turbo links load or vice versa. So there'll be a big find and replace event which might have to be kind of a stop the world thing if it's going to touch so many files. Yeah, I am curious to see if that can be like partially done.

Speaker 3:

but hasn't happened yet interesting.

Speaker 1:

Yeah, anytime that you like can figure out a way to do something like that in small pieces rather than having to do a big bang.

Speaker 3:

Change is obviously good, but sometimes it's like really not clear how that might be done yeah, in this case we have a number of different, like portals, I would say, or modules that are like their own sort of not engines, nothing like that, but their own kind of front end, and I'm hoping that we can test it with one of those. Um. But I'm not really sure how the turbo Turbo controller side of things works too well. I'm not super familiar with that because in the migration document it comes with this patch that you can add to application controller. That does something. I'm not really sure what it does something with redirects and I know that also Turbo changed how redirects work a little bit using some new status codes that I don't think Rails developers are super familiar with, like whatever the 304 is, I don't know. So that's something I think that needs to be looked at.

Speaker 1:

I have a little bit of a different question for you. So we've talked a little bit about like upgrades and tooling and stuff like that. I'm curious about the application code in terms of just like the pure business logic and stuff like that, because a lot of Rails applications have this problem where, like, they start off with I don't know five database tables and so they have five active record models and then the application grows and those older models tend to be the more fundamental ones. There's usually like one single model that is kind of the biggest one. Like I worked on a medical application and it was patient. I'm sure you have one that you know right off the top of your head is is the biggest one. I'm just curious, do you have one that's like?

Speaker 1:

the biggest one.

Speaker 3:

Um, we have a few. I would say we've actually avoided that sort of um, yeah, uh, big ones would obviously, you know, know, we're property management, so property would be a big one. Um, uh, I would also say, um, you know, we have some user classes that are that are quite large residents or sort of like employee yeah, and those have a lot of behaviors the problem that I see a lot is like those fundamental classes.

Speaker 1:

they just like grow and grow and grow until there are hundreds or maybe even thousands of lines in those models. Um, and people like they, they see that problem and they feel that pain and they're like there's different reactions. Some people react by saying, oh, rails sucks because it doesn't handle this problem for me. Some people look to techniques like interactors and service objects and stuff like that. There's various different reactions to that, or some places they just live with it and don't change it. I'm curious if you've felt that pain and it sounds like you've found some ways to address that pain, and I'm curious what those are too.

Speaker 3:

Yep, so I think we're doing okay. I'm just looking at a quick word count, dash L of my models folders. We have like 500 probably models and concerns and the longest one is 430 lines, which I think is pretty good. Um, we probably um, we use a lot of concerns, a lot of a lot of modules. I think some people would probably think that's cheating a little bit because you know, if you had expanded all those modules, those classes become really, really um big.

Speaker 3:

But I would say that, um, one of my focuses has been um to use uh sort of additive behavior through concerns and trying to think about, um, what those names should be, and I could try to think of a good example. But instead of just adding more you know, resident has many payments, or whatever trying to include you know a module or a concern that's called makes payments or something like that, and try to put some of those relationships into those concerns. Now, you can still that'll get you, I think, pretty far, as long as you're able to read the domain and click around and you have good IDE support for like okay, where is this coming from? I think it's okay to have some records that have a lot of different behaviors on them. But if you talk to smart people, smarter than me, I think the key really isn't about code sharing so much as it is modeling your domain in the schema and I think, out of all the challenges that we've faced as a code base, I think data architecture has been the biggest one.

Speaker 3:

I think data architecture has been the biggest one because we are very report heavy and what that means is a lot of reads, a lot of complicated queries and it's not necessarily one plus ones, it's bizarre joins or other times where you have like data freshness guarantees that become really hard to meet at scale. And so splitting up the domain into as many not going crazy, but smaller models, is better because it allows your data access patterns to be, I would say, more flexible. So instead of maybe having resident has payments, rent payments or something like that, um, maybe resident has you know accounting entity and that thing has payments, and in those contexts where you're only concerned about you know the ledger or accounting things, you don't even necessarily have to pull in that tenant record or even necessarily know that that's a tenant or a resident record. Instead, you can just look at that one piece.

Speaker 1:

That can help. Sorry to interrupt, but I wanna go deeper into some of this stuff. So first of all, just like, really broadly, um, I've seen a lot of different applications as a consultant, as and as an employee, um, and I definitely think it's true that, like, if your database design is sound but your application code is a mess, then that's bad, but if your application code somehow is great but your data model is a mess in the database, then you're just like completely fucked, like it's such a harder problem to fix.

Speaker 3:

Yep, I agree, I've often kind of said I don't know if I've said this out loud, but internally I would say your schema is your most valuable IP, I would say. And it's hard to get right and it gets scary too, because Postgres can handle seemingly anything almost that. I just don't know. Sometimes it's what I've noticed can handle like seemingly anything almost um, but I just don't know. Sometimes, right, like um, it's what I've noticed and I'm not a dba I wish I was, because that would help me every once in a while.

Speaker 3:

Um, but there's queries that take like 30 milliseconds and you're like, okay, good, right, because, like you know, ruby's kind of slow 30 milliseconds is pretty fast for for a ruby land kind of slow 30 milliseconds is pretty fast for for a ruby land, um, and then you kind of move on, but then all of a sudden your database will be under load for some reason. Right, high traffic moment, or somebody's doing too much at the same time, or something else is happening um could even be a backup is happening. Suddenly those 30 millisecond queries, um can balloon by like two orders of magnitude and suddenly you have a query that's taking 30 seconds, right, and now you're having timeouts and um. So those are the kind of problems that keep me up at night a little bit. Um is making sure that I understand and how how that schema is going to perform. And I would say, to add to that, the thing that's been really scary for me, I think at scale we're not even really at scale yet, but we have customers using the product every day.

Speaker 3:

There are certain guarantees that become impossible In a small Rails app. Everything is always up to date and it's always possible to just run a query to get the most recent data. But at a certain point that actually becomes impossible and you need to have caching strategies or even secondary data stores that are out of date, even beyond read replicas, just other tables that are out of date. You know, even beyond read replicas, just other tables that are actually just only exist to store computed data. Right, and it's a very uncomfortable feeling knowing that, like this, data is out of date.

Speaker 1:

Okay, I wanna come back to that, because that's a really interesting problem and I know that that's really hard.

Speaker 1:

First, I wanna mention a couple other things about about database design and stuff like that.

Speaker 1:

Um, even before you get to like performance issues, I feel like it's really obviously it's really beneficial to be familiar with like normalization and just like good database design practices and like it kind of seems sometimes like for any particular thing, there's like one way to model it in the database. But it's surprisingly like, even though when I look at something and a lot of times it's like, okay, well, there's like a single, obvious way to model this, a lot of times I come into a project and I see that it's modeled in a much different way than I would have, and not necessarily that it's like worse or better or anything like that. It's just two different people, given a problem area, might design the database totally differently. And I've also found that, sadly, a lot of developers aren't really familiar with these database design principles and so the designs end up being. I think the worst thing is when the designs are subject to data anomalies are subject to data anomalies, so like sure, when your designs let orphaned rows exist or duplicate data, stuff like that. That's the worst.

Speaker 1:

And then like having it be awkward to work with is maybe the next one. Like obviously it's better for your data be data to be perfectly normalized but awkward to work with, than convenient to work with and like accidentally denormalized. Yeah, um, and then like I think the the concern after that is like the performance we were talking about like it should be normalized and as convenient as possible to work with but also performs well under load, which obviously can compete with those first two, because sometimes you have to denormalize and sometimes you have to make compromises on how easy things are to work with. Yeah, but obviously like those choices should be made as conscious trade-offs rather than just like out of ignorance because you don't know how to do the normalization and that kind of stuff yeah, yeah, I think there's a lot there.

Speaker 3:

I think, um, when I first started with rails, I think my instinct would have been to, like you know, try to understand the world as completely as possible and model the world as closely as possible.

Speaker 3:

And I think that turns out to be sort of incomplete, um, for a couple reasons. One is like um, it oftentimes people, uh, are sort of lying to themselves about how things even even really are, like there's a lot of things that happen in the real world that we could be modeling, that are actually like wrong or subtly wrong, or you know, we may talk about like a patient, but that may not be a real thing, right, it may be contextually real. There may be other things happening behind the scenes. You know, with everything you can always sort of dig a little bit deeper, and we use a lot of sort of convenience language in english to sort of gloss over the technical details that would come up when you're trying to model something in the database so that's important to look out for, and I think also it's hard to know how something is going to be used.

Speaker 3:

Yeah, wait, sorry. I want to give an example of that.

Speaker 1:

I've talked about this on the show before. But, like in that medical app, we had faxing capabilities and at first I called a fax a fax because, like you should call things what they are, it should match how people talk about it, and so I called it a fax. But then I realized that fax is kind of like you mentioned, in the English language we have like these ways of speaking and fax is sloppy language and it's like it makes sense to be sloppy in that way. When you're just talking, because you can afford to be sloppy, nobody doesn't know what you mean by a fax and rarely do you need to talk about the fine details of a fax. But when you're creating a system that works with faxes, you can't afford to be that sloppy. And I realize that like this thing we're calling a fax is really there's no such thing like there's a document and there's, yeah, a transmission but like where's the fax?

Speaker 1:

you can't. You know, there's no such thing. So that's an example of like a domain concept that seems obvious, but it's not even real.

Speaker 3:

I think we also like flatten things sometimes, Like if I'm sending an email, you know we got to, we got CC and we got BCC, and then that's you know from somebody and to somebody, and there's a body and a subject, but often the CCC-ness or the BCC-ness, CC-ness, whatever that really lives on that unnamed join table right which doesn't come up in English. You don't really think about the association between the recipient, the email, Then what's in between is maybe some delivery which may be a BCC or a CC, but sometimes those concepts are kind of hiding in those join models that are, you know, not said out loud.

Speaker 1:

Hmm, I actually don't understand that one. Can you Sorry?

Speaker 3:

Like I guess you know, like when I'm, when you send an email, there's like cc and bcc, right like um, but probably between the sender and the recipient and the email there's probably a join table that like associates that person with the email and whether or not you are a bcc or cc kind of like lives on that join table. That makes sense. I don't know, maybe that doesn't make sense.

Speaker 1:

Well, no, yeah, I, I, I get that part. Um, I guess it's maybe the the overall point that I'm trying to understand. Tell me if I have this part right or not kind of my initial guess at what you were saying was like we we say that like I send an email, but maybe that that email which we're talking about as though it's a single email, it has three different recipients, and so it's like hang on is this like one email or is this three emails?

Speaker 1:

it's when we talk about an email that's like kind of imprecise. Is that the?

Speaker 3:

point you were making yeah and I think that brings up even more, which is like is that three emails, right? You sent one email, but like, three people got it right, is that three emails? Is that recipient the same? If I send that same person another email, is that the same recipient, right?

Speaker 1:

I think that might be the same exact thing as a fax, like there's no such thing as an email. There's an email body and there's an email transmission but or an email delivery, whatever, but email is like too sloppy so I think, that's tough, um.

Speaker 3:

And then I think, going to the other point, modeling is good for sanity, but when you're on a team, especially in a monolith context where there's like multiple people consuming the same likely data source probably most monoliths, one database, one app code building for convenience can be helpful. You don't want people misusing your data sources, but that's, I think, less likely to happen. If you have a more denormalized, I would say, or normalized rather more normalized design where there's more smaller domain concepts, you're less likely for people to start building stuff on top of these big models, right? It probably is one of those sort of runaway things. It's like this model gets so big, now it's everywhere, people see it more. I will just throw it on that one, and you know I'm seeing this thing get used. I'll this thing, right, and now it's everywhere. Right, um? Versus if you have smaller, smaller things, they might be more useful in specific contexts and you're less likely to have a bunch of stuff get built up on the same same table yeah, that is such a big one.

Speaker 1:

Um, yeah, and when you have a table with like a million columns, it's like a signal that, like this is how we do things when we have a new thing that we need to add, we just put a new column on the same table.

Speaker 1:

So you should do that too, because that's how we do it, um, and I want to mention something that I think is really important and like maybe not that widely acknowledged is like there's, it's. It's really easy to have a case where you have a very, a very central, important table and it gets all these columns hung on it like a Christmas tree, and these columns are only there. Each column might only support a tiny peripheral feature.

Speaker 3:

Yeah.

Speaker 1:

But each time you do that, you're invoking a cost, and you can think of it as this table, and you can think of it as this table like. It's like footing the bill for this tiny feature that's just in some corner somewhere and then you have like 20 of those and it's like to me it feels really inappropriate, like it's not appropriate for that central model to be footing the bill for all these distant tiny features and so yeah I think it's better to like you know there's like factors to and stuff like that, but if you can, it's often better to like make a new table for that kind of stuff yeah, I agree with that.

Speaker 3:

I think there can be some apprehension for would call like naked models. Right, you have these 500 models now in your app, but every once in a while you have something that's called like car. Okay, what is that? Or I don't know. That's not a good example, but there's ones that actually could come up in multiple contexts. But anyway, so namespace. But if you think about it, I think Postgres organizes tables kind of as like files on disk loosely. I don't know if that's an exact metaphor, but you will have performance benefits if you're able to have more smaller models generally, because it's just less likely that particular table is going to be contested and it'll be easier to bring into memory because it'll likely be smaller, um, so that's, that's less likely to be contested?

Speaker 1:

do you mean like there are fewer things trying to read from it or write right?

Speaker 3:

to it. Yeah, generally. I mean, I don't know, I'm not again, I'm not a dba, so I probably shouldn't be talking about database design, but in my experience, yes, you're less likely to if you have less centralized models. It's just you know, you can be more at your particular call site for whatever feature you're building. If you can pull smaller sets of data right, more specific to what you're working on, rather than oh, I guess I have to pull in customer here that has 70 columns just because I need name or something, generally speaking, you're gonna get, I think, better performance. And also, I think Ruby devs try not to think about this.

Speaker 3:

Rails is very into select star, which is good mostly, but you really have to go out of your way to select less columns than you need and I think most of the time this isn't a problem.

Speaker 3:

But if you are in the context of reporting where you're pulling, all of those records are getting instantiated. Mostly it's usually string data. All that string is coming into memory. And if you're pulling 1,000 records, one extra column is like 1, is coming into memory, and if you're pulling a thousand records, one extra column is like a thousand strings in memory. So if you ever see like Rails console in dev mode. You load a page and it says finished in 30 milliseconds, 79,500 allocations. Right, that should kind of scare you a little bit because like, think about how much work the Ruby VM is doing to like allocate and deallocate all of those strings that are probably not even used. Um, so I think your memory performance will be better too with smaller tables, just because you're less likely to select star on that 70 wide, you know table stuff you're not using, committee-wide table stuff you might be using.

Speaker 1:

Yeah, I've never, ever had to deal with that kind of stuff until a couple months ago when I started working on a new project where performance concerns are really present. And, yeah, if you like, select star is just like not an option, like we have to just pluck a couple of columns, because if you try to load more than that into memory, like you just can't afford it. Like, if there's I mean in our case there might be like millions of records that we're like iterating through, and so we can we have to just like take the bare minimum that we can yeah it's not a fun place to be, but yeah, yeah yeah, so, um, how much do you guys use, like um views for that kind of stuff?

Speaker 1:

because the first thing that came to my mind was like it's going to be really annoying. Potentially, if you like, have this group of three columns, for example, that you're always needing to get your hands on but you don't want to like, do pluck for those three columns and have it repeated all over the code base and stuff like that, and so in that scenario, maybe you could put a view over top of that table, so it's like more convenient to just get what you want. Um how much do you use that technique?

Speaker 3:

uh, a lot. So actually, my rails conf talk was on views, but it wasn't recorded because we were in a weird room, um. So I'm uh, this is good. Somebody actually just emailed me too about my experience with views, so so I can point them here. We use a lot of views. We have maybe, I would say probably, 10% of our active record is views, and I found them to be invaluable for a number of reasons. There are pitfalls which I can get into, but in general I'll just explain what.

Speaker 3:

It is real quick for those who maybe don't know, because it's an overloaded term. Like rails, views you mean like the view layer and now. So in in sequel and I guess we'll just talk about Postgres, because it's simple you can basically treat a query as if it was a table, and so the neat thing about ActiveRecord is that it doesn't actually know where the result set is coming from, right, so you can load any table you want into any Rails model and you'll get those attributes. Right. So you can load users. You can do userfrom blog posts, right, right, and you'll get blog post data in the user models, which is really confusing but just illustrates that, like, rails doesn't care where data is coming from, and you can leverage that by basically treating a query as if it were a table and putting a active record model on top of that, and so for us, a good example of that might be vacancy. So that's the example I used in my talk.

Speaker 3:

So we deal with apartments and you might want to report on vacancy. How many vacancies do I have? If you were designing that schema for an apartment building, it's pretty unlikely that you would naturally sort of build a table for vacancies. You probably have units and you probably have leases. You probably aren't maintaining a table of vacancy, right, because it's kind of like the negative space between leases, right, it's just not something, something that we think about as like a concept, right.

Speaker 3:

So those things are often missed, I would say, by database design. But views can be a great great place to do that. So you can write a query that says all right, select, you know, end date of the previous lease, start date of the next lease, group it by unit and get a really nice API basically from your database of like. Here are the start date, end date and unit numbers of these vacancies, and you can really conveniently access that in Rails just by making an ActiveRecord model with the same name as the view and you can just say vacancyall, vacancywhere, start date, you know some range, and so we use that pretty heavily and we use the scenic gem to manage that. So if you haven't heard of scenic, definitely go look up scenic because it makes it like real painless. But I'll stop rambling.

Speaker 1:

No, that all is really helpful, especially the idea of putting a, an active record model, on top of a view, because it's maybe not super obvious that you can do that. But rails doesn't know the difference between a view and a table. And the first time I did that, I was like wow, this like for some reason doesn't feel like it should work. But it works perfectly like, literally perfectly like there's. No, you don't have to do anything special at all.

Speaker 3:

I would think that's one of those places. Um, and my own understanding too, it's like people have an approximate understanding of what rails is doing. Um, like, if you say blog post dot, all right, like, what is that doing? Oh well, it's loading the blog posts from the blog post table. Um, but really, if you actually look at the console, what's happening is Rails is issuing a select star from blog posts and that comes back as a 2D array and then Rails is just taking that and stuffing it onto the model. It's actually not that sophisticated. The model, right, it's actually not that sophisticated. And you know, postgres doesn't really have like a concept of a table per se, right, I mean, there's obviously tables, but what you're interacting with is like the results set, which is just data. Right, it could be from a query you know, even that like select star from blog posts.

Speaker 3:

we think about that as like load the blog post table, but really that's actually a query. It just happens to be loading the blog posts. You know, I don't know if that makes any sense, but it's something you probably don't ever think about until you have to.

Speaker 1:

Yeah, yeah. But then when you have a problem where that is the solution, it like such a great solution in in my feeling. Um, so I said I wanted to come back to this problem that that sometimes comes up where there's like two competing optimizations. Um, you need a query to be performant. And often the answer to that is caching, but you also need it to be very fresh. And so the answer to it can't be caching, so how do you deal with that?

Speaker 3:

Yep. So this is really annoying. And this just back to views for a second. This is where we ended up at some point was our views weren't fast enough to be real time, and then you can materialize them and other things. But where this comes up, I think the place to look for this is if you're building a workflow. That workflow uses some complicated data, and that workflow uses some complicated data, and during that workflow you need to observe the data changing. Then you can really run into a problem. And by that I mean here's like an example, right? Like let's say that we want to lease some apartments and we see here's my list of vacancies, right? And let's say it's actually pretty complicated to pull that list of vacancies, so we cache it, right, maybe it takes 45 seconds to load vacancies and so we maybe refresh that hourly. If we have a workflow in our application, that's like all right, I'm going to click on a vacancy. All right, now I'm going to lease this unit. All right, finish my lease, go back to my vacancies table. I'm going to lease this unit. All right, finish my lease, go back to my vacancies table. Oh, it's still vacant, right?

Speaker 3:

That is where you get into the headache, because you have this data set that takes a long time to populate but you have a workflow that expects that value to change right and that I would say there's a number of prescriptions to that. One is make it faster. Often in SQL there's actually a pretty quick way to get one to two orders of magnitude faster, I've found, if you just like, actually spend the time to do your query better, but that's not always possible. Actually spend the time to do your query better, but that's not always possible. Two is something that I really don't like, but it's basically copying that data into a table. Right Now you have a physical vacancies table and you maintain it right. So every time you make a lease to an apartment unit, you go and update that unit's vacancies table right In some background job or even maybe in line. So now you're keeping that up to date at the cost of, like every call site where potentially a lease could change, like we have to now, like make sure that we update vacancies and that one has a particular problem where, like you know, at midnight that might change right Because, like, the date changed right, so the data hasn't changed, the time has changed. Now my vacancies table should have changed um, but you know. So that's option two, um. Option three might be like a bit of both.

Speaker 3:

Right, you have some vacancies data that's cached and up-to-date. That's maybe not as accurate or detailed and you're maybe okay showing out-of-date data. But at the time that you actually go to make a new lease of a unit, you check like okay, well, it said it was vacant on that table. But is it really let's do some function of that expensive part right here at this call site and block the unintended behavior which is like double leasing a unit or something, right? So there's not a lot of good solutions and they're all kind of scary and a lot of them involve maybe a second data source or like an event bus. Right, that's something we haven't done yet. I hope we don't have to do that us, right, that's something we haven't done yet. I hope we don't have to do that. And but you know, having certain things subscribe to events, like, okay, leases have changed now have some code somewhere that subscribes to that and updates the vacancies table like reasonably quickly, but yeah, it's. I don't know what the solution is like.

Speaker 3:

There's not a lot of good ones, typically other than hopefully like your data is split up enough that you actually can build more performant queries on like subsets of the of the data Right and yeah, it can be a house of cards. It really can.

Speaker 1:

Yeah, wow, yeah, I've I've heard the expression there are no solutions, only trade-offs, and this sounds like a case where that applies. Um, yeah, yeah, I find all that stuff really fascinating, um, and really difficult, because, like some of that stuff is like there are things in programming where you can kind of follow the beaten path and there are other things where you kind of have to blaze your own trail, and I think that kind of stuff is kind of a mix, and sometimes you don't know which you should do. Like, sometimes you're like, well, if there's a beaten path for this, then I definitely want to do that, but like you can't necessarily know whether that exists or not and you just have to kind of come up with your own solution from first principles, not even knowing if that's the right thing to do.

Speaker 3:

Yeah, a lot of times it actually goes into human space, I would say, where you actually just need to communicate and either change the requirements, ask for different requirements, maybe make some trade-offs where it's like, okay, the user knows that this isn't maybe out of date, past an hour, or maybe we make a different workflow that doesn't depend on the specific thing exactly performing this way.

Speaker 3:

So a lot of times you can get around that in human space. But, yeah, at a certain point I've experienced that now, not like I'm doing something, other people haven't it because I know there's like so many giant rails code bases out there and there's so many people behind the scenes doing all this insane work and probably at a much more sophisticated level. But I have found at times now that it's like, oh, there is no blog post for this problem, like we're in a new place now and like people aren't writing about this. Um, I just got uh in the mail today high performance postgres rails applications. Oh, yeah, finally came off the press. So there are people out there that know these answers and, yeah, did that just come in for you as well?

Speaker 3:

yep, I have two copies actually um well, I just have to brag I don't know which one it is.

Speaker 1:

Bear with me a second while I look. Okay, it's on one of the first. Oh yeah, here it is. Here it is. I have a signed copy, signed by the author himself yeah, he was also at RailsConf and got stuck.

Speaker 3:

What's his name? Sorry?

Speaker 1:

Andy Atkinson.

Speaker 3:

Atkinson yeah, yeah, he seems like he actually has a lot of these answers, so he's a good resource. Read the book. I assume it's good. I'm excited to take a look at that today.

Speaker 1:

Yeah, I haven't read any of it yet. It's now on my ever-growing to read list, yeah I see you have quite the library back there.

Speaker 1:

I recognize some of those, even blurry, pixelated oh, yeah, yeah, like domain driven design is pretty easy to recognize some of those. Uh, addison wesley books code complete. Yeah, every time I get on a call and the other person has books in the background, I try to like see, I try to look for any of the same ones, any specific ones that you recognize I see what I believe to be the rail something way, probably one of the obi fernandez ones.

Speaker 1:

I recognize that red red gradient yeah yeah, I can't even find it by looking just now, but yeah, I definitely have that one. Um, okay, completely unrelated question.

Speaker 1:

it's it's getting close to time to wrap up here, but, um, when I first met you, you and I talked about phones because I absolutely hate, with a burning passion, the direction that mobile phones have gone in and like they're so gigantic and I don't remember if we talked about this specific thing, but like I'm holding my phone in my hand right now, like my thumb can't reach to the opposite side of the phone, like my thumb can't reach the entire screen, which is just so dumb, and when you and I were talking about phones, I remember and it's not like this was 20 years ago or something, this was like the 20 teens or something like that you pulled a flip phone out of your pocket yep.

Speaker 3:

So, yeah, you're talking to the right person. I'd say, shamefully, right now I'm using an iPhone here, but it's the mini right, because I agree. And then there was even a commercial by Apple like your thumb goes from here to here, the screen goes from here to here. That was the commercial for the 5, I think, which was the right size for a phone in my opinion. So right now, yeah, I'm on an iPhonehone, but I did for a while um use a moto razor for a variety of reasons.

Speaker 3:

I'm I'm huge into nostalgia for computing, I would say because I feel like um, as a kid you know, it was like okay, download nopics off the internet, put it in your computer, and all of a sudden text is flying by your screen and like you have kde and like you click on something and the little bouncing ball happens to your mouse. And I felt like so bewildered by that because it was like this is all amazing, but I can't understand any of it. Um, now I feel like I can understand it, but I missed out on decades of stuff. So I bought a DEC VT420 terminal just to see what it was like to get a terminal going. I have an Apple II. I like the Moto Razr Recently I just bought. Can you picture the intro to Lara Croft tomb raider where she's fighting that robot?

Speaker 1:

I don't do.

Speaker 3:

I don't do video games the movie oh but, um the robot has like a, a, uh, like one of the first sony bio laptops, since like a really tiny one like that was like the first netbook or whatever. So I picked one of those up. I just like old stuff. So it's not so much, um, not wanting to have a phone, which is a big part of it, it's about wanting to sort of understand and use and figure out, like older tech I would say yeah, that's really interesting.

Speaker 1:

Um, I myself am kind of a luddite. Um, and I like have a love love hate relationship with computers and technology. Um, and I like old stuff too. Um, you know, time serves as a filter and it's like only the good stuff makes it through, in a way.

Speaker 1:

Um and so, like I really like old cars, old books, just a lot of old stuff, and, for whatever reason, a lot of it tends to be better. Like, for example, classical architecture is just like way better than postmodern architecture. Like architecture now is just shit. Buildings look like shit. They're just so boring and ugly yeah, there's a funny one.

Speaker 3:

You probably would recognize this. Now there's uh, I know this, I guess because, being real estate adjacent, there's something that's, I think, called a five-on-one or maybe a four-on-one and it's due to some sort of legal restriction about how much wood there can be and how much concrete there can be and how many floors of each you can have, and so you'll see a lot of these buildings that are the first floor is like the retail space and that's like concrete, and then it's like four stories of wood on top with the gross siding. If you Google, like four on one or five on one or something, construction, you'd probably see a bunch of these pictures that every town has a bunch of these apartment buildings that look like that now and it could be survivorship bias, right, like well-made buildings are still here. But I agree, everything is a little bit boring now. Yeah, yeah.

Speaker 1:

Not a little bit boring now? Yeah, yeah, yeah, not a little bit boring, a lot boring, and it just looks terrible detroit's very good for that.

Speaker 3:

um, I don't know if we were just lucky or what, but we have, uh, albert khan. If you google him, you'll see a lot of his buildings, and most of the cool buildings in Detroit were in some way Albert Kahn related. Um, during the twenties thirties I'm not a historian, don't fact check that, but Albert Kahn made a lot of good marks on the on the skyline, um, so I'm happy that we'd still have some of that.

Speaker 1:

Yeah. Yeah.

Speaker 1:

Um, let's see. Yeah, and and and I'll. I'll plug this also. You know, this luddite spirit in me is also one of the things that prompted me to start my snail mail programming newsletter, which, john, I know you subscribe to. So thanks for that. Um, I think I just sent your first issue in the mail the other day and now I have your second issue almost ready to go out. But, dear listener, if you haven't heard about that, every month I send a snail mail programming newsletter called nonsense, monthly, and I guess, like these days, like I grew up in the nineties I was born in the eighties, grew up in the nineties, and so snail mail is like a term that I, I I kind of grew up when people first starting started saying snail mail because it was the only kind of mail there was, and then there was email, and so we needed a way to distinguish.

Speaker 3:

But I don't think people really say that anymore, like younger people like have never heard that term snail mail yeah, um, that's happening and now, well, one thing that we're coming full circle now is, uh, people are buying house phones, again, house cell phones. So I've noticed, um, certain people in our demographic who don't want their kids necessarily to have a cell phone or maybe they do, but they still want like a centralized phone and no one has a landline anymore they're buying like another cell phone plan that they just leave on the counter and that's like the house phone and is there like a physical device that stays in?

Speaker 1:

yeah, it's like a it's a.

Speaker 3:

It's like an iphone that sits on a counter forever right but like is it just like?

Speaker 1:

they buy a regular iphone, that's just like every other iphone and they use that at? Home or do they buy like a specific device that's, like you know, has a receiver and stuff like that?

Speaker 3:

no, I think people are just buying cell phones now and leaving them in the kitchen.

Speaker 1:

Okay, because that would be an interesting idea to have a phone mounted on the wall like it's the 90s, but it's just connected to it Right.

Speaker 3:

we're almost right back.

Speaker 1:

Yeah, I think some of these things, like some of these newer technologies, people are realizing that they have costs and benefits and maybe it's not a net gain realizing that they have costs and benefits and maybe it's not a net gain. Um, like you mentioned, pre-show that you have a physical office there in Detroit. Um, do people work in the office, or remotely or hybrid or what?

Speaker 3:

Yep. So this is um, yeah, it's a little bit different. Um, we, yeah, we have like an in-person in office culture which has been, I think, very positive but also challenging. And so, yeah, we, I'm in here every day just because I I have not gotten around to setting up a desk at home, so I'm here every day. Most of our team is here like three or four days a week and some people we interview are like no, I'm only doing remote um, and that's fine, I understand it. Um, the other half of people are pretty much like oh, you know what um covid was kind of, you know a good period away, but like, now I'm ready to come back and be in the office and talk to people.

Speaker 3:

So it's a mixed bag, right, I think our team size. It's helpful to have in-person communication At a larger team size. I could see how it wouldn't be as important if you have good async workflows. But for me personally, I'm async work challenged, I would say I'm not a good like emailer, right, I prefer to talk to people. Um, so you do have to be really focused, I think, to have a successful remote team. I'm sure people know that, but same goes for in person. It's just trade-offs, but it's been positive, I would say yeah, yeah, like um, everybody went remote during the pandemic.

Speaker 1:

And there are a lot of people who seem to believe that like remote is just 100% upsides and no downsides. And they're like, why would you have somebody pay for office space and then have people drive to work every day? You idiots, why don't you just be remote? But it's really like, not that black and white. There's trade-offs to it and, quite frankly, most of the organizations that I've seen that are remote in fact, 100% of them do it really poorly and so, like every single person feels isolated. And so, like every single person feels isolated, like everybody feels alone because the organization isn't doing anything to foster a sense of togetherness and cohesion.

Speaker 1:

And it's not just like an emotional thing, but it has real material impacts on the work that's done.

Speaker 1:

Because if you want to, for example, like tell everybody that, like here's how we're gonna, here's how we're gonna um do testing or something like that, like it's really hard to make a broad scale change in a remote culture where it's just like that's done via slack message or something like that, there's there's something to really be gained from in person in that way and like the, the strength of the relationships among the team members acts like kind of a lubricant for the machine.

Speaker 1:

Like you can afford to be like less tactful and stuff like that if you have a strong relationship with everybody and just like get down to business and make decisions, whereas when everything's written you have to worry a lot more, there's a lot more room to go wrong and stuff like that. You do have to be tactful and diplomatic and stuff like that. There's just so much less like money in the bank metaphorically in the relationship bank account and so you can't afford to withdraw as much because you're not making the constant deposits um yeah, so I think people are coming back the other way now yeah, I would say you definitely.

Speaker 3:

Um, yeah, I agree that. Well, you still have to focus on those culture and cohesiveness things in person too. It helps being in person, but there's still like active work that needs to happen to foster like that environment. Like you still have to be the person that champions and says, hey, this group of people were all going out to lunch today. Right, because otherwise, like it still can be isolating. Right, because otherwise, like it still can be isolating.

Speaker 3:

But I would say, like, when I started this, my hope was that eventually, like we would get to a point where I could like come into work and kind of like code with my friends. Right, and you know it's still work, and so that doesn't always play out and we could probably do a better job of like sharing knowledge and pairing and things like that. But it is sort of like that there's at least some moments where it's like, oh, this is, this is fun, right, like we're in the same room together doing something that we like um, and you know, so I'm happy about that. But I can understand why people hate it too, and especially so I'm.

Speaker 3:

I live physically the closest to the office, so I'm blessed by the three minute commute I probably could walk, so it's good for me. For the other people that are driving a little bit longer, I can understand that, but I mean that's why we do the hybrid. Right Like people need to be able to take a day off, they need to be able to go to the dry cleaner. The sort of paradox of, like every essential thing you need to do being only open during business hours when you're at work. Right, like the bank, you know. So giving people flexibility to do that, I think, is important. But, yeah, definitely not black and white.

Speaker 1:

Yeah, yeah, okay. Well, this has been a really fun conversation, um, and, I think, educational um and such uh. Before we go, john, um, where can people go to find more about ravella and anything else you want to share?

Speaker 3:

Yeah. So let's see. I think, yeah, ravella is R-E-V-E-L-Aco or a co. We can't afford the com. Maybe we could, I don't know. And then I am. I don't know if you may be seeing me. I'm the orange rabbit, my username. I'm on rubysocial, which I think is a very positive place. If you're not on rubysocial, I would highly recommend going and looking. My username is really annoying. I'll just spell it A-E-S-T-H-E-T-I-K-X aesthetics. I think rubysocial is really positive and I think that's a good place to see the meetups that are happening. I also purchased rubymeetupsorg, which is right now pointing at Marco's website. Rubyconferencesorg slash meetups because that's a new section on that website, which is already a good website. Now it's a better website. So if you're looking for meetups, definitely go to rubyconferencesorg or rubymeetupsorg.

Speaker 1:

Nice, We'll put all that stuff in the show notes and John thanks so much for coming on the show.

Speaker 3:

Yep. Thanks, jason, thank you.