

The Bike Shed
thoughtbot
On The Bike Shed, hosts Joël Quenneville, Sally Hall, and Aji Slater discuss development experiences and challenges at thoughtbot with Ruby, Rails, JavaScript, and whatever else is drawing their attention, admiration, or ire this week.
Episodes
Mentioned books

Sep 14, 2021 • 48min
308: That’s Picante
You know what really grinds Chris' gears? (Spoiler Alert: It's Single-Page Applications.)
Steph needs some consulting help. So much to do, so little time.
Sarah Drasner tweet about shared element transitions
Article about Page Transitions API
Svelte Crossfade layout demo
Svelte Crossfade tutorial page (Note - click "Show Me" on the bottom left)
Transcript:
CHRIS: I have restarted my recording, and we are now recording. And we are off on the golden roads. Isn't software fun?
STEPH: Podcast battle. Here we go!
Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari.
CHRIS: And I'm Chris Toomey.
STEPH: And together, we're here to share a bit of what we've learned along the way. Hey, Chris, happy Friday. How's your week been?
CHRIS: Happy Friday to you as well. My week's been good with the exception of right before we started this recording, I had one of those experiences. You know the thing where software is bad and software is just terrible overall? I had one of those. And very briefly to describe it, I started recording, but I could hear some feedback in my headphones. So I was like, oh no, is that feedback going to show up on the final recording? Which I really hope it doesn't. Spoiler alert - listener, if I sound off, sorry about that. But so I stopped recording and then I went to go listen to the file, and I have our audio software configured to record directly to the desktop. And it does that normally quite well. But for some reason, the file wasn't there. But I remember this recently because I ran into it another time.
For some reason, this is Finder failing me. So the thing that shows me the files in a graphical format, at least on my operating system. Although I think it also messes up in the terminal maybe. That feels like it shouldn't be true, but maybe it is. Anyway, I had to kill all Finder from the terminal to aggressively restart that process. And then suddenly, Finder was like, oh yeah, there's totally files there, absolutely. They were there the whole time. Why do you even ask?
And I know that state management is a hard problem, I am aware. I have felt this pain. I have been the person who has introduced some bugs related to it, but that's not where I want to experience it. Finder is one of those applications that I want to just implicitly trust, never question whether or not it's just sneakily telling me that there are files that are not there or vice versa. So anyway, software.
STEPH: I'm worried for your OS. I feel like there's a theme lately [chuckles] in the struggles of your computer.
CHRIS: On a related note, I had to turn off transparency in my terminal because it was making my computer get very hot. [chuckles]
STEPH: Oh no, you're not a hacker any more.
CHRIS: I'm not. [chuckles] I just have a weird screen that's just dark. And jellybeans is my color scheme, so there's that going on. That's in Vim specifically. Pure is my prompt. That's a lovely little prompt. But lots of Day-Glo colors on just a black background, not the cool hacker transparency. I have lost some street cred.
STEPH: What is your prompt? What did you say it is?
CHRIS: Pure.
STEPH: Pure, I don't know that one.
CHRIS: It is by Sindre Sorhus; I think is his name. That's his Twitter handle, GitHub name. He is a prolific open-source creator in the Node world, particularly. But he created this...I think it's a Bash and a Zsh prompt. It might be for others as well. It's got a bunch of features. It's pretty fast. It's minimal. It got me to stop messing around with my prompt, which was mostly what I was going for. And it has a nice benefit that occasionally now I'll be pairing with someone, and I'll be like, "Your prompt looks like my prompt. Everything is familiar. This is great."
STEPH: Well, if you get back in the waters of messing around with your prompts again, I'm using Starship. And I hadn't heard of Pure before, but I really like Starship. That's been my new favorite.
CHRIS: Wow.
STEPH: Wow.
CHRIS: I mean, on the one hand…
STEPH: You're welcome. [laughs]
CHRIS: On the one hand, thank you. On the other hand, again, let me lead in with the goal was to stop messing around with my prompt. So you're like, oh, cool. Here's another prompt for you, though. [chuckles]
STEPH: [laughs] But my goal is to nerd snipe you into trying more things because it's fun.
CHRIS: I don't know if you know this, but I am impervious to nerd sniping.
STEPH: [laughs]
CHRIS: So try as you might, I shall remain steady in my course of action.
STEPH: Are we playing two truths and a lie? Is that what we're doing today? [laughs]
CHRIS: Nah, just one lie. It's easier. Everybody wins one lie.
STEPH: [laughs]
CHRIS: But anyway, in other news, we're going to do a segment called this really grinds my gears. That's today's segment, which is much like when I do a good idea, terrible idea. But this is one that I'm sure I've talked about before. But there's been some stuff that I saw moving around on the internet as one does, and it got these ideas back into my head. And it's around the phrase single-page application. I am not a fan of that phrase or SPA as the initialism. Thank you, Edward Loveall, for teaching me the difference between an initialism and an acronym. I really hope I'm getting it right, by the way, [laughs] SPA as people call them these days.
I feel weird because of how much I care about this thing, how much I care about this idea, and how much whenever I hear this acronym, I get a little bit unhappy. And so there's a part of it that's I really do think our words shape our thinking. And I think single-page application has some deeply problematic ideas. Most notably, I think one of the most important things about building web applications is the URL. And those are different pages, at least in my head. I don't know of a different way to think about this.
But if you are not emphasizing the URL and the fact that the URL is a way to address different pages or resources within your application, then you are throwing away one of the greatest advancements that humankind has made, in my mind. I care a lot about URLs; it turns out. And it's not inherent to an SPA that you will not be thinking about URLs. But again, in that idea that our words shape our thinking, by calling it an SPA, by leaning into that idea, I think you are starting down a path that leads to bad outcomes. I'm going to pause there because I'm getting kind of ranty. I got more to say on the topic. But what do you think?
STEPH: Yeah, these are hot takes. I'm into it. I'm pretty sure that I know why URLs are so important to you and more of your feelings around why they're important. But would you dive in a bit deeper as to why you really cherish URLs, and why they're so important, and why they're one of the greatest advancements of humanity?
CHRIS: [laughs] It sounds lofty when you say it back to me, but yeah. It's interesting that as you put into a question, it is a little bit hard to name. So there are certain aspects that are somewhat obvious. I love the idea that I can bookmark or share a given resource or representation of a resource very simply. Like the URL, it's this known thing. We can put hyperlinks in a document. It's this shared way to communicate, frankly, very complex things.
And when I think of a URL, it's not just the domain and the path, but it's also any query parameters. So if you imagine faceted search on a website, you can be like, oh, filter down to these and only ones that are more than $10, and only ones that have a future start date and all those kinds of nuance. If you serialize that into the URL as part of the query param, then that even more nuanced view of this resource is shareable is bookmarkable is revisitable.
I end up making Alfred Workflows that take advantage of the fact that, like, oh, I can look at this URL scheme, and I can see where different parts are interpolated. And so I can navigate directly to any given thing so fast. And that's deeply valuable, and it just falls naturally out of the idea that we have URLs. And so to not deeply embrace that, to not really wrap your arms around it and give that idea a big hug feels weird to me.
STEPH: Yeah, I agree. I remember we've had this conversation in the past, and it really frustrates me when I can't share specific resources with folks because I don't know how to link to it. So then I can send you a link to the application itself to the top URL. But then I have to tell you how to find the information that I thought was really helpful. And that feels like a step backward.
CHRIS: Yeah. That ability to say, "Follow this link, and then it will be obvious," versus "Go to this page, click on this thing, click on the dropdown, click on this other thing." Like, that's just a fundamentally different experience. So one of the things that I saw that got me thinking about this was I saw folks referring to single-page applications but then contrasting them with MPAs, which are multiple-page applications.
STEPH: So the normal application? [laughs]
CHRIS: And I was like, whoa, whoa, everybody. You mean like a website or a web app? As much as I was angry at the first initialism, this second one's really getting me going. But it really does speak to what are we doing? What are we trying to build? And as with anything, you could treat this as a binary as just like there are two options. There are either websites which, yeah, those have got a bunch of URLs, and that's all the stuff. And then there are web apps, and they're different. And it's a bundle of JavaScript that comes down, boots up on the client, and then it's an app thing. And who cares about URLs? I think very few people would actually fall in that camp.
So I don't really believe that there is a dichotomy here. I think, as always, it's a continuum; it’s a spectrum. But leaning into the nomenclature of single-page application, I think pushes you more towards that latter end of the spectrum. I think there are other things that fall out of it. Like, I believe deeply in having the server know more, have more of the logic, own more of the logic, own more authorization and routing, and all of those things because really great stuff falls out of that. And that one has more of a trade-off, I'd say.
But I won't name any names, but there is a multiple billion-dollar company whose website I had to interact with recently. And you land on their page on their marketing site. And then, if you click log in, it navigates you to the application, so a separate domain or a separate subdomain, the application subdomain, and the login page there. And the login page renders, and then I go to fill in my username and password. Like, my mouse makes it all the way to click on the little box or whatever I'm doing if I'm using keyboard things. But I have enough time to actually start to interact with this page.
And then suddenly, it rips away, and it actually just renders the authenticated application because it turns out I was already logged in. But behind the scenes, they're doing some JWT dance around that they're checking; oh no, no, you're already logged in, so never mind. We don't need to show you the login page, but I was already on the login page.
And my feeling is this sort of brittle UI; this sort of inconsistency erodes my trust in that application, particularly when I'm on the login page. That is a page that matters. I don't believe that they're doing anything fundamentally insecure. But I do have the question in my head now. I'm like, wait, what's going on there, everybody? Is it fine? Was that okay? Or if you see something that you shouldn't see and then suddenly it's ripped away from you, if you see half of a layout that's rendered on a page and then suddenly you see, no, no, no, you actually don't have access to that page, that experience erodes my trust.
And so, I would rather wait for the server to fully resolve, determine what's going to happen, and then we get a response that is holistically consistent. You either have access, or you don't, that sort of thing. Give me a loading indicator; give me those sorts of things. I'm fine with that. But don't render half of a layout and then redirect me back away.
STEPH: I feel like that's one of the problems with knowing too much because most people are not going to pick up on a lot of the things that you're noticing and caring deeply about where they would just see like, oh, I was logged in and be like, huh, okay, that was a little weird, but I'm in and just continue on. Versus other folks who work very closely to this who may recognize and say, "That was weird." And the fact that you asked me to log in, but then I was already logged in, did you actually log me in correctly? What's happening? And then it makes you nervous.
CHRIS: Maybe. Probably. But I wonder…the way you just said that sounds like another dichotomy. And I would say it's probably more of a continuum of an average not terribly tech-savvy user would still have a feeling of huh, that was weird. And that's enough. That's a little tickle in the back of your brain. It's like, huh, that was weird.
And if that happens enough times or if you've seen someone who uses an application and uses it consistently, if that application is reasonably fast and somewhat intuitive and consistent, then they can move through it very quickly and very confidently. But if you have an app that half loads and then swaps you to another page and other things like that, it's very hard to move confidently through an application like that. I do think you're right in saying that I am over-indexed on this, and I probably care more than the average person, but I do care a lot.
I do think one of the reasons that I think this happens is mobile applications came along, and they showed us a different experience that can happen and also desktop apps for some amount of time this was true. But I think iOS apps, in particular really great ones, have super high fidelity interactions. And so you're like, you're looking at a list view, and then you click on the cell for that list view. And there's this animated transition where the title floats up to the top and grows just a little bit. And the icon that was in the corner moves up to the corner, and it gets a little bigger. And it's this animated transition to the detailed view for that item. And then if you go back, it sort of deanimates back down.
And that very consistent experience is kind of lovely when you get it right, but it's really, really hard. And people, I think, have tried to bring that to the web, but it's been such a struggle. And it necessitates client-side routing and some other things, or it's probably easiest to do if you have those sorts of technologies at play, but it's been a struggle. I can't think of an application that I think really pulls that off. And I think the trade-offs have been very costly.
On the one positive note, there was a tweet that I saw by Sarah Drasner that was talking about smooth and simple page transitions with the shared element transition API. So this is a new API that I think is hoping to bring some of this functionality to the web platform natively so that web applications can provide that higher fidelity experience. Exactly how it'll work whether or not it requires embracing more of the single-page application, client-side routing, et cetera, I'm not sure on that. But it is a glimmer of hope because I think this is one of the things that drives folks in this direction. And if we have a better answer to it, then maybe we can start to rethink the conversation.
STEPH: So I think you just said shared element transitions. I don't know what that is. Can you talk more about that?
CHRIS: I can try, or I can make a guess. So my understanding is that would be that sort of experience where you have a version of a certain piece of content on the page. And then, as you transition to a new page, that piece of content is still represented on the new page, but perhaps the font size is larger, or it's expanded, or the box around it has grown or something like that. And so on mobile, you'll often see that animate change. On the web, you'll often see the one page is just completely replaced with the other. And so it's a way to have continuity between, say, a detailed view, and then when you click on an item in it, that item sort of grows to become the new page. And now you're on the detail page from the list page prior.
There's actually a functionality in Svelte natively for this, which is really fancy; it's called crossfade. And so it allows you to say, "This item in the component hierarchy in the first state of the application is the same as this item in the second state of the application." And then, Svelte will take care of transitioning any of the properties that are necessary between those two.
So if you have a small circle that is green, and then in the next state of the application, it's a blue rectangle, it will interpolate between those two colors. It will interpolate the shape and grow and expand it. It will float it to its new location. There is a really great version of it in the Svelte tutorial showing a to-do list. And so it's got a list on the left, which is undone things, and a list on the right that is done things. And when you click on something to complete it, it will animate it, sort of fly across to the other list. And if you click on it to uncomplete, it will animate it and fly back.
And what's great is within Svelte because they have this crossfade as a native idea; all you need to say is like, "It was on this list, now it's on this list." And as long as it's identifiable, Svelte handles that crossfade and all the animations. So it's that kind of high-fidelity experience that I think we want. And that leads us to somewhat more complex applications, and I totally get that. I want those experiences as well. But I want to ask some questions, and I want to do away with the phrasing single-page application entirely. I don't want to say that anymore. I want to say URLs are one honking good idea. Let's have more of those.
And also, just to name it, Inertia is a framework that allows me to build using some of the newer technologies but not have to give up on URLs, give up on server-side logic as the primary thing. So I will continue to shout my deep affection for Inertia in this moment once again.
STEPH: Cool. Thanks. That was really helpful. That does sound really neat. So in the ideal world, we have URLs. We also have high fidelity and cool interactions and transitions on our pages. We don't have to give it a fancy name like single-page application or then multi-page application. I do wonder, with our grumpiness or our complaint about the URLs, is that fair to call it grumpy?
CHRIS: It's fair to call it grumpy, although you don’t need to loop yourself in with me. I'm the grump today.
STEPH: [laughs]
CHRIS: You're welcome to come along for the ride if you'd like. And I'm trying to find a positive way to talk about it. But yeah, it's my grumpytude.
STEPH: Well, I do feel similarly where I really value URLs, and I value the ability to bookmark and share, like you said earlier. And I do wonder if there is a way to still have that even if we don't have the URL. So one of the things that I do is I'll inspect the source code. And if I can find an ID that's for a particular header or section on the page, then I will link someone to a section of that page by then adding the ID into the URL, and that works. It's not always great because then I have to rely on that being there. But it's a fix, it's a workaround.
So I wonder if we could still have something like that, that as people are building content that can't be bookmarked or the URL doesn't change explicitly, or reference that content, to add more thoughtful bookmark links, essentially, or add an ID and then add a user-facing link that says, "Hey, if you want to link someone to this content, here you go." And under the hood, it's just an ID. But most people aren't going to know how to do that, so then you're helping people be able to reference content because we're used to URLs, so just thinking outside the box. I wonder if there are ways that we can still bookmark this content, share it with people. But it's okay if the URL isn't the only way that we can bookmark or reference that content.
CHRIS: It's interesting that you bring that up, so the anchor being the thing after the hash symbol in the URL. I actually use that a ton as well. I think I built a Chrome extension a while back to try what you're saying of I'll inspect the DOM. I did that enough times that I was like, what if the DOM were to just tell me if there were an ID here and I could click on a thing? Some people's blogs...I think the thoughtbot blog has this at this point. All headers are clickable. So they are hyperlinks that append that anchor to the URL.
So I wouldn't want to take that and use that functionality as our way to get back to URLs that are addressing resources because that's a way to then navigate even further, which I absolutely love, to a portion of the page. So thinking of Wikipedia, you're on an article, but it's a nice, long article. So you go down to the section, which is a third of the way down the page. And it's, again, a very big page, so you can link directly to that. And when someone opens that in their browser, the browsers know how to do this because it's part of the web platform, and it's wonderful.
So we've got domains, we've got paths, we've got anchors, we've got query params. I want to use them all. I want to embrace them. I want that to be top of mind. I want to really think about it and care about that as part of the interface to the application, even though most users like you said, are not thinking about the shape of a URL. But that addressability of content is a thing that even if people aren't thinking of it as a primary concern, I think they know it when they...it's one of those like, yeah, no, that app's great because I can bookmark anything, and I can get to anything, and I can share stuff with people.
And I do like the idea of making the ID-driven anchor deep links into a page more accessible to people because you and I would go into the DOM and slice it out. Your average web user may not be doing that, or that's much impossible to do on mobile, so yes, but only more so in my mind. [laughs] I don't want to take anchors and make them the way we do this. I want to just have all the URL stuff, please.
Mid-roll Ad
Now we're going to take a quick break to tell you about today's sponsor, Orbit. Orbit is mission control for community builders. Orbit offers data analytics, reporting, and insights across all the places your community exists in a single location. Orbit's origins are in the open-source and developer relations communities. And that continues today with an active open-source culture in an accessible and documented API.
With thousands of communities currently relying on Orbit, they are rapidly growing their engineering team. The company is entirely remote-first with team members around the world. You can work from home, from an Orbit outpost in San Francisco or Paris, or find yourself a coworking spot in your city. The tech stack of the main orbit app is Ruby on Rails with JavaScript on the front end.
If you're looking for your next role with an empathetic product-driven team that prides itself on work-life balance, professional development, and giving back to the larger community, then consider checking out the Orbit careers page for more information. Bonus points if working in a Ruby codebase with a Ruby-oriented team gives you a lot of joy. Find out more at orbit.love/weloveruby.
STEPH: I have a confession from earlier when you were talking about the examples for those transitions. And you were describing where you take an action, and then the page does a certain motion to let you know that new content is coming onto the page and the old content is fading away. And I was like, oh, like a page reload? We're just reimplementing a page reload? [laughs] That's what we have?
CHRIS: You have a fancy, though.
STEPH: Fancy, okay. [laughs] But that felt a little sassy. And then you provided the other really great example with the to-do list. So what are some good examples of a SPA? Do you have any in mind? I think there are some use cases where...so Google Maps, that's the one that comes to mind for me where URLs feel less important. Are there other applications that fit that mold in your mind?
CHRIS: Well, so again, it's sort of getting at the nomenclature, and how much does the acronym actually inform what we're thinking about? But taking Google Maps as an example, or Trello is a pretty canonical one in my mind, most people say those are single-page applications. And they are probably in terms of what the tech actually is, but there are other pages in those apps. There's a settings page, and there's a search page, and there's this and that. And there's like the board list in Trello.
And so when we think about Trello, there is the board view where you're seeing the lists, and you can move cards, and you can drag and drop and do all the fancy stuff. That is a very rich client-side application that happens to be one page of the Trello web app and that one being higher fidelity, that one being more stateful. Stateful is probably the thing that I would care about more than anything. And so for that page, I would be fine with the portion of the JavaScript that comes down to the client being a larger payload, being more complex, and probably having some client-side state management for that. But fundamentally, I would not want to implement those as a true client-side application, as a true SPA. And I think client-side routing is really the definition point for me on this.
So with Trello, I would probably build that as an Inertia-type application. But that one page, the board page, I'd be like, yeah, sorry, this is not going to be the normal Inertia thing. I'm going to have to be hitting JSON endpoints that are specifically built for this page. I'm going to have a Redux store that's local. I'm going to lean into all of that complex state management and do that within the client-side app but not use client-side routing for actual page-level transitions, the same being true for Google Maps. The page where you're looking at the map, and you can do all sorts of stuff, that's a big application. But it is one page within the broader website, if you will. And so, I still wouldn't want client-side routing if I can avoid it because I think that is where I run into the most problems.
And that thing I was talking about where I was on the login page for a second, and then I wasn't; I do not like that thing. So if I can avoid that thing, which I have now found a way to avoid it, and I don't feel like I'm trading off on that, I feel like it's just a better experience but still reserving the right to this part of the application is so complex. This is our Wiziwig drag and drop graphical editor thing, cool. That's going to have Redux. That's going to have client-side state management, all that stuff. But at no point does single-page application feel like the right way to describe the thing that we're building because I still want to think about it as holistically part of the full web app. Like the Trello board view is part of the Trello web app. And I want it all to feel the same and move around the same.
STEPH: Yeah, that makes sense. And it's funny, as you were mentioning this, I pulled up Google Maps because I definitely only interact with that heavy JavaScript portion, same for Trello. And I wasn't even thinking about the fact that there are settings. By the way, Google Maps does a lot. I don't use hardly any of this. But you make a great point. There's a lot here that still doesn't need such heavy JavaScript interaction and doesn't really fit that mold of where it needs to be a single-page app or even needs to have that amount of interactivity. And frankly, you may want URLs to be able to go specifically to these pages.
CHRIS: That actually is an interesting, perhaps counterpoint to what I'm saying. So if you do have that complex part of one of your applications and you still want URL addressability, maybe you need client-side routing, and so that becomes a really difficult thing to answer in my mind. And I don't necessarily have a great answer for that. I'm also preemptively preparing myself for anyone on the internet that's listening to this and loves the idea of single-page applications and feels like I'm just building a straw man here, and none of what I'm saying is actually real and whatnot.
And although I try to...I think we generally try and stay in the positive space of like what's good on the internet. This is a rare case where I'm like, these are things that are not great. And so I think in this particular case, leaning into things that I don't like is the way to properly capture this. And giant JavaScript bundles where the entirety of the application logic comes down in 15-megabyte download, even if you're on 3G on a train; I don't like that.
I don't like if we have flashes of a layout that they can get ripped away b; it’secause it turns out we actually aren't authorized to view that page, that sort of thing. So there are certain experiences from an end client perspective that I really don't like, and that's mostly what I take issue with. Oh, also, I care deeply about URLs, and if you don't use the URL, then I'm going to be sad. Those are my things.
Hopefully, that list is perhaps a better summary of it than like...I don't want it to seem like I'm just coming after SPA as a phrase or a way of thinking because that's not as real of a conversation. But those particular things that I just highlighted don't feel great. And so I would rather build applications that don't have those going on. And so if there's a way to do that that still fits any other mold or is called whatever, but largely what I see called an SPA often has those sorts of edge cases. And I do not like those edge cases.
STEPH: Yeah, I like how you're breaking it down where it's less of this whole thing like I can't get on board with any of it. You are focusing on the things that you do have concerns with. So there can be just more interesting, productive conversations around those concerns versus someone feels like they have to defend their view of the world.
I have found that I think I'm a bit unique in this area where when people have a really differing opinion than mine, that gets me really excited because then I want to know. Because if I believe very strongly in something and I just think this is the way and then someone very strongly says like, "No, that's not," I'm like, "Oh yeah. Okay, we should talk because I'm interested in why you would have such a different opinion than mine." And so, I typically find those conversations really interesting. As long as everybody's coming forward to be productive and kind, then I really enjoy those conversations.
CHRIS: That is, I think, an interesting frame that you have there. But I think I'm similar, and hopefully, my reframing there puts it in the way that can be a productive conversation starter as opposed to a person griping on a podcast. But with that said, that's probably enough of me griping on a podcast. [chuckles] So what's up in your world, Steph?
STEPH: Oh, there are a couple of things going on. So I am in that pre-vacation chaotic zone where I'm just trying to get everything done. And I heard someone refer to it recently as going into a superman or superwoman mode where you're just trying to do all the things before you go, which is totally unreasonable. So that has been interesting. And the name of the game this week has been delegate, delegate, delegate, and it seems to be going fairly well. [chuckles] So I'm very excited for the downtime that I'm about to have.
And some other news, some personal news, Utah, my dog, turns one. I'm very excited. I'm pretty sure we'll have a dog birthday party and everything. It's going to be a thing. I'll share pictures on Twitter, I promise.
CHRIS: So he's basically out of the puppy phase then.
STEPH: Yeah, the definition for being a puppy seems to be if you're a year or younger, so he will not be an adult. Teenager? I don't know. [laughs]
CHRIS: What about according to your lived experience?
STEPH: He has calmed down a good bit.
CHRIS: Okay, that's good.
STEPH: He has gotten so much better. Back when we first got him, I swear I couldn't get 15 minutes of focus where he just needed all the attention. Or it was either constant playtime, or I had to put him in his kennel since we're using that. That was the only way I was really ever getting maker’s time. And now he will just lounge on the couch for like an hour or two at a time. It's glorious. And so he has definitely calmed down, and he is maturing, becoming such a big boy.
CHRIS: Well, that is wonderful. Astute listeners, if you go back to previous episodes over the past year, you can certainly find little bits of Utah sprinkled throughout, subtle sounds in the background.
STEPH: He is definitely an important part of the show. And in some other news, I have a question for you. I'm in need of some consulting help, and I would love to run something by you and get your thoughts. So specifically, the project that I'm working on, we are always in a state where there's too much to do. And even though we have a fairly large team, I want to say there's probably somewhere between 7 and 10 of us. And so, even though we have a fairly...for thoughtbot, that's a large team to have on one project. So even though there's a fair number of us, there's always too much to do. Everything always feels like it's urgent. I can't remember if I've told you this or not, but in fact, we had so many tickets marked as high priority that we had to introduce another status to then indicate they're really, really high, and that is called Picante. [chuckles]
CHRIS: Well, the first part of that is complicated; the actual word that you chose, though, fantastic.
STEPH: I think that was CTO Joe Ferris. I think he's the one that came up with Picante. So that's a thing that we have, and that really represents like, the app is down. So something major is happening. That's like a PagerDuty alert when we get to that status where people can't access a page or access the application. So there's always a lot to juggle, and it feels a lot like priority whiplash in terms that you are working on something that is important, but then you suddenly get dragged away to something else. And then you have to build context on it and get that done. And then you go back to the thing that you're working on.
And that's a really draining experience to constantly be in that mode where you're having to pivot from one type of work to the other. And so my question to you (And I'll be happy to fill in some details and answer questions.) is how do you calm things down? When you're in that state where everything feels so urgent and busy, and there's too much to do, how do you start to chip away at calming things down where then you feel like you're in a good state of making progress versus you feel like you're just always putting out fires or adding a band-aid to something? Yeah, that's where I’m at. What thoughts might you have, or what questions do you have?
CHRIS: Cool. I'm glad you brought an easy question that I can just very quickly answer, and we'll just run with that. It is frankly...what you're describing is a nuanced outcome of any number of possible inputs. And frankly, some of them may just be like; this is just the nature of the thing. Like, we could talk about adding more people to the project, but the mythical man-month and that idea that you can't just throw additional humans at the work and suddenly have that makes sense because now you have to coordinate between those humans. And there's that wonderful image of two people; there's one line of communication. Three people, suddenly there are a lot more lines of communication. Four people, wow. The exponential increase as you add new people to a network graph, that whole idea.
And so I think one of the first questions I would ask is, and again, this is probably not either/or. But if you would try and categorize it, is it just a question of there's just a ton of work to do and we're just not getting it done as quickly as we would want? Or is it that things are broken, that we're having to fix things, that there are constant tweaks and updates, that the system doesn't support the types of changes that we want, so any little thing that we want to do actually takes longer? Is it the system resisting, or is it just that there's too much to do? If you were to try and put it into one camp or the other.
STEPH: It is both, my friend. It is both of those camps. [chuckles]
CHRIS: Cool. That makes it way easier.
STEPH: Totally. [laughs] To add some more context to that, it is both where the system is resistant to change. So we are trying to make improvements as we go but then also being respectful of the fact if it is something that we need to move quickly on, it doesn't feel great where you never really get to go back and address the system in a way that feels like it's going to help you later. But then, frankly, it's one of those tools that we can use. So if we are in the state where there's too much to do, and the system is resisting us, we can continue to punt on that, and we can address things as we go.
But then, at some point, as we keep having work that has slowed down because we haven't addressed the underlying issues, then we can start to have that conversation around okay; we’ve done this twice now. This is the third time that this is going to take a lot longer than it should because we haven't really fixed this. Now we should talk about slowing things down so we can address this underlying issue first and then, from now on, pay the tax upfront. So from now on, it's going to be easier, but then we pay that tax now. So it is a helpful tool. It's something that we can essentially defer that tax to a later point. But then we just have to have those conversations later on when things are painful. Or it often leads to scope creep is another way that that creeps up.
So we take on a ticket that we think, okay, this is fairly straightforward; I don't think there's too much here. But then we're suddenly getting into the codebase, and we realize, oh, this is a lot more work. And suddenly, a ticket will become an epic, and you really have one ticket that's spiraled or grown into five or six tickets. And then suddenly, you have a person that's really leading like a mini project in terms of the scope of the work that they are doing.
So then that manifests in some interesting ways where then you have the person that feels a bit like a silo because they are the ones that are making all these big changes and working on this mini-project. And then there's the other one where there's a lot to do. There are a lot of customers, and there's a lot of customization for these customers. So then there are folks that are working really hard to keep the customers happy to give them what they need. And that's where we have too much to do. And we're prioritizing aggressively and trying to make sure that we're always working on the top priority. So like you said, it's super easy stuff.
CHRIS: Yeah. To say it sincerely and realistically, you're just playing the game on hard mode right now. I don't think there is any singular or even multiple easy answers to this. I think one question I would have particularly as you started to talk about that, there are multiple customers each with individualized needs, so that's one of many surface areas that I might look t say, "Can we sort of choke things off there?"
So I've often been in organizations where there is this constant cycle of the sales team is going out. They're demoing against an InVision mock. They're selling things that don't exist. They're making promises that are ungrounded and, frankly, technically infeasible or incredibly complicated, but it's part of the deal. They just sold it, and now we have to implement it as a team. I've been on teams where that was just a continuing theme. And so the engineering team was just like, "We can never catch up because the goalpost just keeps moving."
And so to whatever degree that might be true in this case, if there are ten different customers and each of them right now feels like they have an open line to make feature requests or other things like that, I would try to have the conversation of like, we've got to cut that off right now because we're struggling. We're not making the forward progress that we need to, and so we need to buy ourselves some time. And so that's one area that I would look at.
Another would be scope, anywhere that you can, go into an aggressive scope cutting mode. And so things like, well, we could build our own modal dialogue for this, but we could also use alert just like the JavaScript alert API. And what are all of the versions of that where we can say, "This is not going to be as nice, and as refined, and as fitting with the brand and feel and polish of the website. But ways that we can make an application that will be robust, that will work well on all of the devices that our users might be using but saves us a bunch of development time"? That's definitely something that I would look to.
What you described about refactoring is interesting. So I agree with we're not in a position where we can just gently refactor as we find any little mess. We have to be somewhat ruthless in our prioritization there. But like you said, when you get to that third time that a thing is working way harder, then take the time to do it. But really, like just every facet of the work, you just have to be a little better. If you're an individual developer and you're feeling stuck, raise your hand all the earlier because that being stuck, we don't have spare cycles right now. We need everybody to be working at maximum efficiency. And so if you've hit a wall, then raise your hand and grab somebody else, get a pair, rubber duck, whatever it is that will help you get unstuck. Because we're in a position where we need everybody moving as fast as they can.
But also to say all of those aren't free. Every one of those where you're just like, yeah, do it the best you can. Dial it up to 11 on every front. That's going to drain the team, and so we have to also be mindful of that. This can't be forever. And so maybe it is bringing some new people onto the team or trying to restructure things so that we can have smaller communication channels. So it's only four people working together on this portion of the application, and therefore their communication lines are a bit simpler. That's one way that we can maybe save a little bit. But yeah, none of these are free. And so, we also need to be mindful that we can't just try harder forever. [laughs] That's a way to burn out the team. But what you're describing is like the perfect storm of every facet of this is difficult, and there's no singular answer.
There's the theory of constraints (I think I'm saying that right.) where it's like, what's the part of our process that is introducing the most slowdowns? And so you go, and you tackle that. So if you imagine a website and the app is slow is the report that you're getting, and you're like, okay, what does that mean? And you instrument it, and you log some stuff out. And you're like, all right, turns out we have tons of N+1s. So frankly, everything else doesn't matter. I don't care if we've got a 3 megabyte JavaScript bundle right now; the 45 N+1s on the dashboard that's the thing that we need to tackle. So you start, and you focus on that.
And now you've removed that constraint. And suddenly, the three megabyte JavaScript bundle is the new thing that is the most complicated. So you're like, okay, cool, let's look into tree shaking or whatever it is, but you move from one focus to another. And so that's another thing that could come to play here is like, which part of this is introducing the most pain? Is it feature churn? Is it unrealistic sales expectations? Is it developers getting stuck? And find the first of those and tackle it. But yeah, this is hard.
STEPH: Yeah, it is. That's all really helpful, though. And then, I can share some of the things that we are experimenting with right now and then provide an update on how it's going. And one of the things that we're trying; I think it's similar to the theory of constraints. I'm not familiar with that, but based on the way you described it, I think they're related.
One of the things that we are trying is breaking the group into smaller teams because there are between 7 and 10 of us. And so, trying to jump from one issue to the next you may have to really level up on different portions of the application to be able to make an impact. And there are areas that we really need infrastructure improvements and then essentially paving the way for other people to be able to move more quickly. We do have to prioritize some of that work as well.
So if we break up into smaller teams, it addresses a couple of areas, or at least that's the goal is to address a couple of areas. One is we avoid having silos so that people aren't a bottleneck, or they're the only ones that are really running this mini-project and the only one that has context. Because then when that person realizes the scope has grown, bringing somebody on to help feels painful because then you're in an urgent state, but now you have to spend time leveling someone else up just so that they can help you, and that's tough.
So the goal is that by having smaller teams, we will reduce that from happening because at least everything that feels like a small project...and by feels like a small project, I mean if we have more than one ticket that's associated with the same theme, that's going to start hinting at maybe this is more than just one ticket itself, and it might actually belong to an epic. Or there's a theme here, and maybe we should have two people working on this. And breaking people into groups, then we can focus on some people are focused more on the day-to-day activity. Some people are focused on another important portion of the codebase as we have what may be extracted. I'm going to say this, but we're going to move on, maybe extracted into its own service. [laughs] I know that's a hot one for us, so I'm just going to say it.
CHRIS: I told you I can't be nerd sniped. This is fine. Let's continue on. [laughs]
STEPH: [laughs] And then a small group can also focus on some of those infrastructure improvements that I was alluding to. So smaller teams is something that we are trying.
We are also doing a really great job. I've been really happy and just proud of the team where folks are constantly reaching out to each other to say, "Hey, I'm done with my ticket. Who can I help?" So instead of immediately going to the backlog and grabbing the next thing. Because we recognize that because of this structure where some people are some silos, they have their own little mini backlog, which we are working to remove that to make sure everything is properly prioritized instead of getting assigned to one particular person. But we are reaching out to each other to say, "Hey, what can I do to help? What do you need to get done with your work before I go pick something else up?"
The other two things that come to mind is who's setting the deadlines? I think you touched on this one as well. It's just understanding why is it urgent? Does it need to be urgent? What is the deadline? Is this something that internally we are driving? Is this something that was communicated without talking to the rest of the team? Is this just a really demanding customer? Are they setting unrealistic expectations? But having more communication around what is the sense of urgency? What happens if we miss this deadline? What happens if we don't get to this for a week, a month? What does that look like?
And then also, my favorite are retros because then we can vote on what feels like the highest priority in terms of pain points or run these types of experiments like the smaller teams. So those are the current strategies that we have. And I'm very interested to see how they turn out because it is a tough way. Like you said, it's challenge mode, and it is going to burn people out. And it does make people feel fatigued when they have to jump from one priority to the next. So I'm very interested. It's a very interesting problem to me too. It just feels like something that I imagine a lot of teams may be facing. So I'm really excited if anybody else is facing a similar issue or has gone through a similar challenge mode; I’d love to hear how your team tackled it.
CHRIS: Yeah, I'm super interested to hear the outcome of those experiments. As a slightly pointed question there, is there any semi-formal version of tracking the experiments? And is it just retro to retro that you're using for feedback on that? I've often been on teams where we have retro. We come up with it, and we're like, oh, this is a pain point. All right, let's try this. And then two weeks later, we're like, oh, did anyone actually do that? And then we just forget. And it's one of those things that I've tried to come up with better ways to actually manage, make slightly more explicit the experiments, and then have a timeline, have an almost scientific process of what's the hypothesis? What's the procedure? What are the results? Write up an executive summary. How'd it go?
STEPH: We are currently using retro, but I like that idea of having something that's a bit more concrete. So we have action items. And typically, going through retro, I tend to revisit the action items first as a way to kick off retro. So then that highlights what did we do? What did we not do? What do we not want to do anymore? What needs to roll over to the current iteration? And I think that could be just a way that we chat about this. We try something new, and we see how it's going each week in retro. But I do like the idea of stating upfront this is what we're looking to achieve because I think that's not captured in the retro action item. We have the thing that we're doing, but we haven't captured this is what we hope to achieve by taking this experiment on.
Mid-roll Ad
And now a quick break to hear from today's sponsor, Scout APM.
Scout APM is leading-edge application performance monitoring that's designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve those performance abnormalities like N+1 queries, slow database queries, memory bloat, and much more.
Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform.
See for yourself why developers call Scout their best friend and try our error monitoring and APM free for 14 days; no credit card needed. And as an added-on bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed. That's scoutapm.com/bikeshed.
STEPH: As for the other thing that you mentioned, I do have an idea for that because a former client that I worked with where we had experiments or things that we wanted to do, we were using Trello. And so we would often take those action items…or it was even more of a theme. It wasn't something that could be one-and-done. It was more of a daily reminder of, hey; we are trying this new thing. And so, we want to remind you each day to embrace this experiment and this practice. And so we would turn it into a Trello ticket, and then we would just leave it at the top of the board. So then, each day, as we were walking the board, it was a nice reminder to be like, hey, this is an ongoing experiment. Don't forget to do this.
CHRIS: I do like the idea of bringing it into a stand-up potentially as like that's just a recurring point that we all have. So we can sort of revisit it, keep it top of mind, and discard it at some point if it's not useful. And if we're saying we're doing a thing, then let's do the thing and see how it goes. So yeah, very interested to hear the outcomes of the experiment and also the meta experiment framework that you're going to build here. Very interested to hear more about that.
And just to say it again, this sounds like your perfect storm is not quite right because it doesn't sound like there's a ton of organizational dysfunction here. It sounds like this is just like, nah, it's hard. The code's not in perfect shape, but no code is. And there's just a lot of work to be done. And there are priorities because frankly, sometimes in the world, there are priorities, and you're sort of at the intersection of that.
And I've been in plenty of teams where it was hard because of humans. In fact, that's often the reason of we're sort of making up problems, or we're poorly communicating or things like that. But it sounds like you're in the like, nope, this is just hard. And so, in a way, it sounds like you're thinking about it like, I don't know, it's kind of the challenge that I signed up for. Like, if we can win this, then there's going to be some good learnings that come out of that, and we're going to be all the better. And so, I wish you all the best of luck on that and would love to hear more about it in the future.
STEPH: Thank you. And yeah, it has been such an interesting project with so many different challenges. And as you've mentioned, that is one area that is going really well where the people are wonderful. Everybody is doing their best and working hard. So that is not one of the competing challenges. And it is one of those; it’s hard. There are a lot of external factors that are influencing the priority of our work. And then also, some external areas that we don't have control over that are forcing some of those deadlines where customers need something and not because they're being fussy, but they are themselves reacting to external deadlines that they don't have control over.
So it is one of those where the people are great, and the challenges are just real, and we're working through them together. But it's also hard. But it's helpful chatting through all the different challenges with you. So I appreciate all of your thoughts on the matter. And I'll report some updates once I have some more information.
On that note, shall we wrap up?
CHRIS: Let's wrap up.
STEPH: The show notes for this episode can be found at bikeshed.fm.
CHRIS: This show is produced and edited by Mandy Moore.
STEPH: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or a review in iTunes as it helps other people find the show.
CHRIS: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed on Twitter. And I'm @christoomey.
STEPH: And I'm @SViccari.
CHRIS: Or you can email us at hosts@bikeshed.fm.
STEPH: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeee!
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Sponsored By:Orbit: Orbit is mission control for community builders. Orbit offers data analytics, reporting, and insights across all the places your community exists in a single location. Orbit’s origins are in the open-source and developer relations communities, and that continues today with an active open-source culture and an accessible and documented API.
With thousands of communities currently relying on Orbit, they are rapidly growing their engineering team. The company is entirely remote-first with team members around the world. You can work from home, from an Orbit “outpost” in San Francisco or Paris, or find yourself a co-working spot in your city.
The tech stack of the main Orbit app is Ruby on Rails with JavaScript on the frontend. If you are looking for your next role with an empathetic, product-driven team that prides itself on work-life balance, professional development, and giving back to the larger community then consider checking out the Orbit careers page for more information. Bonus points if working in a Ruby codebase with a Ruby-oriented team gives you a lot of joy.
Find out more at orbit.love/weloveruby.Scout: Scout APM is leading-edge application performance monitoring designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise-platform feature bloat.
With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve performance abnormalities -- like N+1 queries, slow database queries, memory bloat, and more.
Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them.
Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform.
See for yourself why developers worldwide call Scout their best friend and try our error monitoring and APM free for 14-days, no credit card needed!
And as an added bonus for Bikeshed listeners: Scout will donate $5 to the open-source project of your choice when you deploy.
Learn more at scoutapm.com/bikeshed.Support The Bike Shed

Sep 7, 2021 • 37min
307: Walking Contradictions
On this episode, Chris talks about testing external services and dissects a tweet on refinements for Result. Steph talks about thoughbot's recent improvement to their feature flag system.
Links:
refinements For Result
Faking External Services in Tests with Adapters by German Velasco
Testing Interaction with 3rd-party APIs
Transcript:
CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey.
STEPH: And I'm Steph Viccari.
CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new with you?
STEPH: Hey, Chris. Well, today is Summit Day at thoughtbot, and it's the day where all the bots gather, and we hang out, and we chat, and we play games. And it's a lot of fun. We're actually taking more of a respite this year just because life has been taxing. And so we decided to give people more of the day off. So we still had some fun events, but most of it is everybody gets a chill day. Do something that brings you joy is the theme of the day.
But we had Lightning Talks, which is my favorite thing that we do on Summit Day because I realize that I just work with the coolest people, and they have such interesting things to talk about. And we had such a variety of topics. So one of them, Alex Chen taught us acronyms in K-pop. And Sam Kapila, our resident foodie, taught us about a variety of spices. And one of my favorite talks was by Akshith Yellapragada, and it's the top 10 best limo entrances by The Bachelor, and it was phenomenal. And I really want to share some stuff that I learned with you.
CHRIS: The Bachelor like the TV show?
STEPH: Yeah, like the TV show. Are you familiar with it? Have you seen it before?
CHRIS: I am familiar with it. I know it exists. I know that there's a spinoff, The Bachelorette. And I believe we have now exhausted my information on the matter.
STEPH: [laughs] That's fair. For anyone that hasn't seen the show, the show revolves around a single person. For the bachelor, it's a single bachelor who dates a number of people over several weeks, and then they narrow down the people. There are elimination rounds, and the whole goal is for them to find their true love. So each week, someone is eliminated, and I think the show ends with a marriage proposal. So it's a wild show. It's something. [chuckles]
And in Akshith's talk, I learned some really fun terminology. The first one is the Crown, and this is actually an important building block because we're going to get to the rest of the terminology that uses this word, so we got to start here. So the first one is the Crown, and this is the person that everyone's competing for. So they're the star of the show. They're the one that everybody is hoping to fall in love with or will fall in love with them so they get a marriage proposal.
So then the other stuff that I've learned is all about the entrance because again, we're talking about the top 10 best entrances. And one of them is the sidecar entrance. So this is where the player, because yes, this is totally a game, has someone assist them in meeting the crown. So it could be like a family member, maybe it's like your grandma.
And then there's TOT, T-O-T, which is short for Trick Or Treat. And this person exits the limo wearing a costume. So it's someone wearing a shark costume. There was someone wearing a sloth costume where they really dedicated to the role, and they climbed a tree and hung from a branch. I don't know for how long but for long enough to really vibe with the role.
And then there's the Kringle, and this person brings a prop or a present to the Crown. And there's the Grandy, and this player arrives in something other than a limo. So the example that Akshith provided is someone arrived in a motorized cupcake.
CHRIS: Was the cupcake edible?
STEPH: I don't think so, fair question. [laughs]
CHRIS: So really just like a go-kart that looked like a cupcake, not really a motorized cupcake, if I'm going to meet pedantic about the thing, [chuckles] which I think is my job.
STEPH: Yes, it is a motorized non-edible cupcake, but that seems like something a next player should do. They should really up the game, and they should bring an edible motorized cupcake.
CHRIS: Yeah, because you get the visual novelty, but then you layer on top of it that it's actually something that you can now eat, and it's a double win.
STEPH: Ooh, and then you're a Grandy, and you're a Kringle because you arrived in something other than a limo, and it's a present.
CHRIS: I love how you have so deeply internalized this now that you're like, ooh, okay. I can remix here. I'm going to bring together the pieces. Yeah, all right. Yeah, this all makes sense.
STEPH: Yeah, it was a lot of fun. Those are most of my notes for today. I have some tech stuff too, but this felt like the most important thing to start the show with.
CHRIS: We use the phrase tech talk and nonsense to describe the show often, but I think nonsense and tech talk is the correct orientation.
STEPH: [chuckles]
CHRIS: Correct in terms of importance and chronological order, and whatnot. But yeah.
STEPH: I love that we start with a bit of nonsense. So I do have some tech stuff. But first, before I share any of that, what's going on in your world?
CHRIS: I'm sure there's plenty of nonsense in my world, but at the top of my list is some tech stuff. So someone on Twitter, Adam Lassek, reached out and he suggested related to the conversation and the back and forth that I've been having with myself around some of the data structures within the app that I'm building…So I've talked about the dry-monads result object, and there's this success and failure. And I wanted to introduce this new method called bimap, but I wanted to do it in a reasonable way. So I wrapped, and then I wrapped, and I wrapped things.
As an aside, former colleague and friend of the show, Joel Oliveira, sent a wonderful tweet which was a reference to the SNL video where they make a taco and put it inside of a pizza and put it inside of a bag. And that was his joke about it, which I really liked. That was an excellent reference. But in this case, Adam Lassek reached out and suggested if I'm that squeamish about monkey patching, which I am, have I considered refinements? And so he sent an image of a code sample, which is so kind of him to send that much detail over, but it was interesting because I know of refinements in Ruby. I know of that as an alternative to monkey patching, a more refined way, but a safer way, a more controlled way to alter code, but I've not actually used them.
STEPH: I'm not familiar with refinements. What is that?
CHRIS: Refinements are a way...so similar to monkey patching, where you say like, I'm going to reopen this class or this module and define a new method or redefine a method or do something like that, a refinement is a way to do that in a scoped manner. So I'll be honest, I'm not super familiar with them. I think I came into Ruby at a time where the community was moving away from monkey patching. And the dogmatic swing of the pendulum was like, that's a bad thing to do. And so even the refinements were introduced, as far as I understand it, to be a more controlled way to do it. So it's not just like, hey, cool. This module is redefined now in your app in a magical way that's really hard to figure out and hard for folks to debug refinements. You have to explicitly opt into within a certain lexical scope.
I'll be honest; I know that at the headline level. I don't actually know the ramifications or where and when you can use them and how you can. But I know that that was the idea is refinements are a way to do monkey patching but in a more controlled, more understandable manner, and so the code sample that Adam shared does that. And it's very interesting. As I'm looking at it, I'm like, okay, that's cool because I think it'll be a little bit safer.
But at the end of the day, my concern wasn't safety in this case because I was introducing a method that would be new, that would be additive to the API of this module that I'm working with, and so that I think of as a relatively safe operation. My hesitation was more around how does someone figure it out if they're working with this? And particularly, the name of the method that I was introducing was bimap so, B-I-M-A-P. And if someone sees that in our codebase and is like, "Bimap, where is this coming from?" Well, this is one of those dry-monad result objects. And they go to the code, and they try and look it up in the docs, and they're just not going to find anything.
And I can imagine losing a lot of time to try and chase that down. There are ways to figure it out. There's the method in Ruby, which is a wonderful trick for chasing things down. Or if you grep the codebase, you'd find it. But I think I'm possibly over-indexed on worrying about that lost time, that moment. But I've lost that time so many times in my life where I'm like, I can't grep for this. I can't Google for this. And so I have so strongly moved in the direction of being like, everything should be grepable, everything should be googleable. Those are the two of the things that I believe about software. I think I believe a bunch of stuff.
STEPH: I think we have a full episode that talks about what we believe in software.
CHRIS: I believe we do.
STEPH: Cool. Thanks. Yeah, I have not heard of refinements. That sounds really interesting. I really like that bit about everything should be grepable, and everything should be googleable, googling everything. I kind of agree with that one. We live in a world where we're always doing bespoke things so that one feels a little bit harder that we're always going to be able to Google it. But then that encourages people to constantly publish the bespoke work that they're doing so then others can benefit from that work. But the grepable, I absolutely agree with that one. It's so frustrating where I see a method, but I cannot find its definition. And then having the ways to figure out where that method is defined to then find its definition is crucial.
CHRIS: Yeah, it's interesting. I definitely feel that way very strongly. And it's in such stark contrast to Rails. Rails is like, hey, don't worry. There's going to be a lot of methods. You don't need to worry about where they come from, or why they exist, or what they are, or what they do. Well, probably what they do. But all of the magic inflections on database tables,, and suddenly you have methods named after every column. That's both very magical and hard to grep for or impossible to grep for, but it also leaks the entire structure of your database into your application in a way that I've always felt a little bit complicated about. And so explicitness, grepability, those are things that I care about.
There's another one, delegates in Rails, that I sometimes pause around using especially when it's like delegates 19 methods to user prefix user. And so you end up with methods that are like username. And that's a delegation to the user object to get the name method off of it, but it creates the method user_name. And you're never going to be able to grep for that. And it saves like a little bit of code, definitely, but it saves this very obvious, very knowable code. So this one I actually shy away from using delegates in most cases, and I'll just write out the methods manually because sometimes I like to hear the clackety of my keyboard. There's a reason I have a clackety keyboard.
STEPH: You want to get your money's worth. You want to clackety as much as possible. Yeah, I'm also not a fan of delegates. This may be a lie, but I don't know that I've actually ever used it. I've worked with it, but I can't think of a time that I've implemented delegates. Maybe that's a lie, but I'm going to say it anyways because that feels true, at least in the last couple of years.
CHRIS: I feel like that could be true for the last couple of years. I would be surprised if you have never even added to a delegates line. Because that's the thing, you can just keep shoveling stuff into them as well. So I would put money on you having used it at some point and then just forgotten about it. But who knows, maybe not.
STEPH: This is where we play two truths and a lie and that one's my lie. [laughs] Yeah, that's also fair about adding to it because if that's already defined and it's easier to add to it, I don't know. Who knows what past Stephanie has done, probably some wild stuff.
CHRIS: It's unknowable at this point. It's lost to the sands of time. But looping back to the core thing of this refinement and the module, I think I'm leaning in the direction of doing that and unwinding my wrapping and wrapping layer thing. Because obviously, as I talked about...I think it was the previous episode or maybe two episodes ago. There was conceptual complexity to the additional wrapping layer. Even as I was fully in the context of working on that, I was still getting myself confused in either triple wrapping or then unwrapping too much or whatever. And these are the concerns with this type of code. So moving away from that feels better, having just a single layer of context wrapping around a given value.
And then the other thing it's actually just a lot less code, and it's less prone to error, I think. That's my hope. I have to look into exactly how refinements get used, but I noticed in a couple of places that sometimes we were wrapping with this local value object that gave us the bimap method, and sometimes we were forgetting to. And so, I could see that being a very subtle, easy way to introduce failures into the app that would be hard to catch just by looking at it.
So I think having a more global refinement...although I think that's sort of a contradiction, a global refinement because I think refinements are meant to be local. But anyway, I'm going to look into it because it's a much more concise code sample than what I have. Yeah, I'm going to poke at that a little bit. But it was an interesting exploration of some different things. And then it forced me to consider why am I so resistant to monkey patching at this point, especially in this particular case where I think it's okay-ish?
STEPH: That's a good question. Do you have any insights? I am also resistant to monkey patching. I feel that pain and also that timidness of diving into that space. But I'm curious, have you figured out any other reasons that you really prefer to avoid it?
CHRIS: I think this one falls into that sort of...what's the word? Like tribal knowledge of we've been burned by it in the past and therefore we build almost a...religious is too strong of a word but that sort of cultural belief. This is a thing that we do not do because of the bad things that we've experienced in the past. And there are a lot of things that fall into that experiential negative space.
So with monkey patching, things that I know we can run into is if I introduced this bimap method, but I introduce it subtly differently than the library will eventually, then they could eventually introduce it themselves. And suddenly, I have this fork of my code expects it to work this way, but you've now implemented it that way. I no longer can upgrade. This is a critical piece of infrastructure in my app. I've just painted myself into a corner by doing this. Whereas if I do this wrapping layer, that's my code. I own that. It's not going to be a problem in that same way.
There's also the subtlety, the grepability that sort of thing is a concern in my mind. Like, is this our code? Is this their code? Is this an engine? Being able to find code within a codebase, I think, is a critical thing. And so that's a part of the hesitation. I also know longer ago prototypes...I want to say Prototype JS was the name of the project, but it was one that was just like, yeah, JavaScript doesn't have enough stuff in the standard library. So we're just going to override everything and add all of these wonderful methods sort of in the way that Active Support does, which is an interesting comparison.
But the JavaScript community definitely moved away from Prototype. And now JavaScript is a language or the standard runtime that's available in most JavaScript engines. It has a lot of the methods, but there are conflicts, and stuff gets weird, and it's all complicated. But again, as I thought of it, Active Support is a complete contradiction to everything I'm saying. Active Support just adds whatever to anything, 2.days.ago. Why does the number 2 have a days method? Because it's great, that's why. But I'm just a walking contradiction, I guess.
STEPH: Everything you said really resonates with me. And I'm just trying to reason with myself like yes, Active Support uses a lot of this, a lot of metaprogramming, and adds everything it wants to. So why does that feel okay? And I wonder if it comes down to one is more almost like an agreed standard. It's built by a team, and it's maintained by a team, and then it's used by a large number of people, and then you get that feedback. Or maybe it's not even just a team, but it's a larger community versus if it's internal to your software team, maybe that doesn't feel like a big enough group or if it just needs...Rails is also documented. So maybe that's part of it, too, is if you are going to dive into that space, it's easy to discover, and it's well-documented as if you are building an open-source project that other people are going to use. Like, you designed for the intent of people to use this pattern that you've introduced, then perhaps that's when it starts to feel okay. ,
But the experiences I have had is where people basically will add some dynamic programming or monkey patch an existing feature. And then that's very hard to find and has surprising results, or it gets outdated. So I guess it comes down to who are you designing for? Are you designing for more of an open-source community, or you're at least designing for the people behind you that are going to be using this? Or is this a one-off adventure that you have chosen for yourself and future developers to discover? [chuckles]
CHRIS: Yeah, I think that's a good summary, although I'm open to the fact that I exist in a state of contradiction. I'm also fine with that, to be clear. [chuckles] But I think what you said is true, and I think there is subtlety and nuance and reasons that it's okay in one context and less okay in others. And that idea of just like, I don't know, this is one of those things that I got in my head that I've done the thinking a long time ago to decide this is a thing I don't do.
So now, in order to override that, I would have to do so much thinking. I would have to be like, all right, well, my brain tells me, no, but I'm going to go reread everything about monkey patching right now to convince myself that it's okay or to fully get the context and the subtlety and the nuance. And so sometimes we have to rely on that heuristic knowledge of monkey patching, nope, don't do that. That's not a thing, but other stuff is fine. And well, Active Support is fine because it's Rails. But it is interesting to observe contradictions and be like, huh, look at me go. All right. Well, moving on.
STEPH: It's our lizard brain that's saying, "Hey, there's danger here." [laughs]
CHRIS: Exactly.
STEPH: I rather like living in a world of contradictions, or at least I find it that I'm drawn to them. And maybe that's also one of the things that I really like about consulting is because then I join all these different teams, and I hear all these different opinions. So as I'm forming these opinions around something like tests are great, I really like tests, and then someone's like, "I really hate tests." I'm like, "Cool. Let's talk. I want to understand why you don't like this thing that I think is wonderful because then I'm really interested." So I find that I'm often really drawn to contradictions as I like hearing opinions that are very different than mine and finding out why people have a different opinion than mine.
CHRIS: Yeah, the world is full of contradictions. So it's, I think, at least a useful way to exist in the world, to be open to them and to enjoy exploring them. But yeah, I'll update in future weeks if I do end up going the refinements route. I'll let you know if anything interesting falls out of that.
And now we're going to take a quick break to tell you about today's sponsor, Orbit. Orbit is mission control for community builders. Orbit offers data analytics, reporting, and insights across all the places your community exists in a single location. Orbit's origins are in the open-source and developer relations communities. And that continues today with an active open source culture in an accessible and documented API.
With thousands of communities currently relying on Orbit, they are rapidly growing their engineering team. The company is entirely remote-first with team members around the world. You can work from home, from an Orbit outpost in San Francisco or Paris, or find yourself a coworking spot in your city
The tech stack of the main orbit app is Ruby on Rails with JavaScript on the front end. If you're looking for your next role with an empathetic product-driven team that prides itself on work-life balance, professional development, and giving back to the larger community, then consider checking out the Orbit careers page for more information. Bonus points if working in a Ruby codebase with a Ruby-oriented team gives you a lot of joy. Find out more at orbit.love/weloveruby.
STEPH: So we made a recent improvement to our feature flag system, which I'm really excited about, that we have found a way to improve that workflow because it felt really great that we're...well, okay, I should say that with a caveat. It felt really great that we're using feature flags to ensure that the main branch is always in a deployable state. But it did not feel great around how tedious it was becoming to add all of the feature flags specifically because each time we're adding a feature flag, we're having to add a migration. So we're having to run a migration, add the feature flag column, and then we can interact with that feature flag. And that part's okay. It was more removing that feature flag once we're done with it, that that part was starting to feel tedious because then that's becoming a two-deploy process.
So one change is to remove the code that's relying on that feature flag. And then the second deploy was to actually drop that column because we wanted it to be safe to make sure that the code wasn't trying to reference a database column that didn't exist anymore, which is what happened at one point at first when we weren't doing the two-deploy process.
So the improvement that Chris White came up with is where we're now using a Postgres JSONB column. And it's here that we actually have a feature flag YAML file. And we can have the name of the feature flag. We have a description of the purpose of the feature flag. And we have an enabled property on there, so then we can turn it on and off. The benefit of this is now we don't have to do that two-deploy process. And we also don't have to run a migration for when we're adding a new feature flag. So we can add it to the feature flag file, we can load it in, and then we can set that property to say, "Yes, this is enabled," or "No, it's not." And that has just simplified our feature flag process.
One tricky bit that I believe the team ran into is around enabling this with Active Admin because Active Admin was just relying on those database columns to then turn something on or off. But then we've added some methods that work well with Active Admin that then say, "Read from here when you're checking to see if something is enabled," or "Look at this list to see which feature flags can be turned on and off." So it's been a really nice improvement, and everybody on the team seems to be in favor of the ways that we've improved this. So it's been really nice. So I wanted to come back and bring an update on how we've simplified our feature flag system.
CHRIS: That definitely sounds like a nice improvement, the ability to just more regularly iterate around that or taking away the pain, any pain associated with using feature flags. Because they are such a nice thing to have, but there's that overhead. Then you start to have that voice in your head that's like, do I really need a feature flag for this? Could I just sneak this one in? And we always regret that.
I had a similar thing this week where I wrote some code. I didn't quite write as many tests as I should have. And it was wildly broken, just like all of the connection points through everything were broken. But then it pushed me in an interesting direction where I was like, well, what I'm going to do is write an integrated test. It was basically an event coming in from a webhook that then enqueued a job, which did a thing, which then spit out an email. But it was broken at like three layers, and I was very embarrassed, if we're being honest. But, I don't know, I was just having a low energy afternoon, and I did not write the test, which I know I'm supposed to do.
So similarly, any pain that we can take out of these things that we're supposed to do, any way that we can pave the happy path, I'm all about those. I'm intrigued because I think we've talked about this before, but it sounds like you guys have a very home-grown feature flag system. Is that true?
STEPH: We do.
CHRIS: Is there something about it that makes it unique to your situation, or was it just like that's what happened? Someone early on was like, "We need feature flags. I can just do the simplest thing that works," and then that's where you're at now or?
STEPH: You're asking a very good question. And I'm trying to recall what led us to the state that we're in because I feel like we had this same discussion several episodes back when we were introducing the home-grown feature flag system. And I was like, there are reasons, but I didn't really dive into those reasons because it felt very custom to the application. But now I've forgotten what those reasons were. So I think you ask a great question where it'd be worth revisiting to confirm that yes, there's a reason for this home-grown version versus using something like Flipper.
CHRIS: I'm glad I'm at least consistent over time in the questions that I ask and the heuristics that I have. This does feel like one of those things. It's not quite like crypto where I'd be like, we can never write our own crypto. But a feature flag system, I would be really intrigued if there are things that they are just workflows or functionality that you really need that are not supported by any of the existing solutions that are out there. I think audit trails is an interesting one. I think Flipper has a hosted product at this point that does that, but the local version wouldn't necessarily. So maybe that's a thing that you want to get. Again, I'd just be really interested. It sounds like the current state of the world that you have is enabled or disabled; just broadly, that's it. Those are the two states for any given flag. Is that true?
STEPH: It is. There's nothing complex with the flags in that nature. And then we use naming to indicate if something is more for beta, so if it's a change that we're making to the codebase, but it's a feature flag that we plan on removing, versus maybe it's a feature flag for enterprise customers.
CHRIS: Oh, interesting. I wouldn't think of using a feature flag in that context where it's going to be like a persistent, long-lived; this is conditional logic around some state or some property of the viewer. I think of feature flags as a way to gate code conditionally based on a point in time. And the reason I asked about the enabled-disabled basically like the Boolean state for your flags is when I've worked with feature flags in the past, I've liked having the ability to say, for this user or these users, or this group of users, which we've named this is our beta list…and it's the ten people that just really love the product and are happy to bump into some rough edges. And so we'll put things on for them first or even like percentages, so roll it out to 10% and then 50% and so on. And I think the larger an application and user base gets, the more that sort of thing starts to feel right.
STEPH: Yeah, we certainly have some complexity around where each customer can really specify which features that they want. And then the features also differ a bit for each customer. So we are in a world where we're pretty customized or configurable for different customers. And whether that's something that we could simplify, that would certainly be a good question or something to pursue.
But part of this also feels like our decision may have been based around what the system was already doing, and we're looking for ways to make slow improvements versus trying to redesign the whole thing. Because initially, the way we were customizing all of these different features for customers was in a YAML file. And that part was painful because then, anytime we wanted to make a change, it required a deploy. So the introduction of feature flags is really to get away from having to deploy to then make a small change like that.
But now that we're in the space that we can easily configure that change and do that on the fly and not have to issue a deploy, I think we're now in a good space to reassess. And the team may have some really good answers. Perhaps I'm just not recalling as to why we've chosen the more home-grown feature flags. But yeah, I'll visit that topic and report back. Because I've been coasting along on our new system and enjoying it, but you're asking some really good questions.
CHRIS: I mean, as an aside, if you're coasting along and really enjoying it, then maybe you don't need to ask any questions. It's still interesting. I would be intrigued to know. But if it's not causing you any pain, then you probably shouldn't change it. Because frankly, changing out the feature flag system is going to be non-trivial, I'm pretty sure. You could feature flag the feature flag system, and then you can transition from one to the other. You need a third feature flag system for that. But anyway, I digress. [chuckles]
STEPH: You referenced crypto earlier. So I think I like the feature flag, the feature flag system. We should have some crypto flags in there somewhere. I think that's a thing too. But I think the main goal if I'm looking into changing it would be, circling back to what we were talking about earlier, is discoverability, so having a home-grown feature flag system. How easy is it for…if nobody was around on the team and there was someone new working with it, how easy would it be for them to turn something on or off? And if that's easy, then that's great. Then I think we've got a great home-grown system. If that's challenging, then I definitely think it's worth reassessing.
And now a quick break to hear from today's sponsor, Scout APM.
Scout APM is leading-edge application performance monitoring that's designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve those performance abnormalities like N+1 queries, slow database queries, memory bloat, and much more.
Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform.
See for yourself why developers call Scout their best friend and try our error monitoring and APM free for 14 days; no credit card needed. And as an added-on bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed. That's scoutapm.com/bikeshed.
CHRIS: One of the things that's been interesting working lately in the app that I'm building is thinking about testing. We have a number of interactions with third-party services. Frankly, a lot of the app is that at this point. We have a handful of different external data providers systems that we're interacting with, webhooks and flows and things like that. And so we had to make that decision that you always have to make in these sorts of situations which is, how are we going to test this?
And there's a wonderful blog post on the thoughtbot blog called Faking External Services in Tests with Adapters. It's by the one and only German Velasco. And it is a beautiful summary of the different approaches that you can take, but it really dials into one, which is the adapter pattern. There's also a weekly iteration episode on Upcase with Joël Quenneville, which discusses a little bit more of an exploration of the different options. There are sort of a handful of different options that we can consider your whereas the blog post by German talks specifically about the adapters approach.
But to talk about them briefly, there's one where you can go all the way outside your app, spin up a fake service. Typically, we would do this with Capybara Discoball, which is a wonderfully named project. But it allows you to spin up a little Sinatra app type thing such that your web application is still making quote, unquote "real HTTP requests." This external service is going to catch that and respond with whatever canned data or structured responses that you want.
But you still have the ability in that to, say, tell it to create data beforehand or be in a certain state or respond with certain data or have any stateful persistence. So if you create a record in that external system, and then later you query for it, that system can do that. But it has the complexities of now, your test suite is running different systems. And do you have thread-safety or all that kind of stuff? So that's a particularly complex end of the spectrum. At the lowest end would be stubbing and mocking. You just take whatever external clients you have, and you're mocking the API calls in them. That's the lowest end. And that's the one, especially for feature specs, those I try and avoid. Then there's a middle ground of like WebMock or VCR, those sort of things where you're saying whenever you see an HTTP request that looks like this, respond in this way. You record the cassettes, all that kind of stuff.
And then there's the one that we've settled on, which is the adapters. So the client that we've introduced in our local codebase to interact with any of these third-party systems internally has a class attribute, a cattr_accessor in the Rails parlance, I believe. And that allows us to switch out the backend. And so we have a real HTTP backend, and that's the one that actually runs in production and a test in-memory backend. And that in-memory backend can implement whatever logic. We're ending up with one of them almost recreating this external service, sort of re-coding some of their inconsistencies or oddities but also features and whatnot.
But it feels like it has struck just the right balance, and it allows our feature specs to be very rich, very real. We start up the world, and we say, "Hey, external service be in this state." And then I'm going to go visit the page. I'm going to see the data. But we are almost making real HTTP requests. It's very close. It's always an interesting choice to make here. I'm very happy with the one that we've made, but it's still not perfect. There are always going to be trade-offs between the different options here. But it's always interesting revisiting this and being like, which one am I going to choose today?
STEPH: I feel like my natural progression when testing external services; I always start with WebMock, and then I progress to using adapters. And then from there, I go to actually replacing the HTTP service that is receiving and then returning a response, like you mentioned to Capybara Discoball earlier. So I can certainly see what you like about the adapter pattern. You mentioned that you're coding some of the inconsistencies. That feels very real. I'm curious if you have an example of how you've had to manage that recently.
CHRIS: A specific example would be the external API responds with certain error codes or error structures. So it's an error. It has a status of a number and then a reason, or sometimes instead of a key that is reason; it’s the message. So it's like, oh, okay, I see that in this endpoint, you respond with reason, and then this endpoint you respond with message. So now, do I encode that into my fake? I guess I do. So my adapter now implements things like that. There are cases where it's inconsistency where I'm like, well, this is the way they behave. So I would like our test suite to exist in the context of that because then our app is getting exercise in a real way.
But in some cases, it's like little bits of logic validation that an external system might do if that's an important part of the flow. The app that we're building has a lot of forms and a lot of data validation and things like that. And so, we want to make sure that we have robust handling around that robust messaging to the user so that it's very clear what they need to do and how they need to respond to things. And so putting in little bits of that like, oh, that's how you format a phone number, okay, cool. Our fake will also format phone numbers in that way, things like that.
STEPH: Every time the topic of testing external services comes up, I really, really want VCR to be the answer. I really like the idea of being able to validate that...because you'd mentioned that we're programming the expected return from this other service. And it's very easy to get out of sync with those actual responses. And then we don't really have a great way to stay up to date other than we wait for production or staging environment to fail. And then we realize something has changed, and we have to go and update either our mock or our adapter. And maybe that doesn't happen often if you're working with an external service that is very good about broadcasting when they have a breaking change.
But if you're working with a less stable endpoint, then I always want VCR to really work. But it's just one of those areas where I'm like, yes, that's the thing that I want. I want this idea where I can rerun my tests in a way that they actually hit that service and record the response. But then I have felt pain [chuckles] from working with VCR and how it's configured, and how people have used it. It's one of those where I don't blame the library. I like the library. But the way people have implemented it and test I have felt a lot of pain from that.
CHRIS: Yeah, I definitely agree with that. It feels like it's nice if you can push the mocking all the way out to that layer. Because like right now, our codebase has code in it that is subtly changing the behavior for a test, and I don't like that. It's only the swapping out of the adapter, so it's a very minimal thing. And we try and push all logic away from that such that the test adapter is as similar as possible to the real production situation. But it's enough difference that I agree I would like if VCR would just like, I catch the HTTP requests, and I respond with the same thing and sometimes we can pass through.
I do think one of the fundamental limitations, or at least very hard to get right things, would be sequential requests. So I post to this endpoint in the external service, which creates some data. And then later, when I make a GET request to their endpoint, I should get back that data that I just created. That's, I guess, doable because you can have sequential requests, have cassettes that are first this request, then that request, then that request. And it knows that, like scope them to a given spec. But that feels extra difficult. And it does, again to your comment, the maintainers of that project do a wonderful job, but it's a really hard target to hit.
STEPH: Well, and one of the other hard requirements with using a tool like VCR is then that external service really needs that sandbox staging environment that you can use. So that way you can create this data, you can rerun your test. So they're actually going to hit this real environment. They're going to create this data and that not have any harmful effects. And then you can record fetching that data. So it requires a lot of pieces to fall into place for it to work well. But then I was just thinking as you're talking about adapters, I'm like, yeah, I love the adapter pattern. I've really enjoyed that one for testing as well. But then I immediately start to think, oh, well, what happens when it gets out of sync, and how do we know that it got out of sync? And I don't have a great answer to that.
CHRIS: Production blows up, obviously.
STEPH: Production blows up, and then we go update our adapter. That's very calm. [laughs]
CHRIS: It would be great if CI could more proactively catch that or...yeah, I agree. I would love if VCR would work because that facet of it is so attractive. But [chuckles] I've never gotten to walk exclusively the happy path with VCR. So here we are. This is a classic case of here's four options as to how we can think about this hard and important thing that we do in our codebases, and they all have trade-offs much like everything else in software.
STEPH: I'm going to add this to my developer bucket list to live in a world where I can easily validate if an external API has changed or not and then also have tests that know when something has broken before production does.
CHRIS: Ooph, dare to dream. I like it.
STEPH: I'm a dreamer.
CHRIS: I want to live in that world. Well, with that wonderful dream to take us out, should we wrap up?
STEPH: Let's wrap up. The show notes for this episode can be found at bikeshed.fm.
CHRIS: This show is produced and edited by Mandy Moore.
STEPH: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or a review in iTunes as it helps other people find the show.
CHRIS: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed on Twitter. And I'm @christoomey.
STEPH: And I'm @SViccari.
CHRIS: Or you can email us at hosts@bikeshed.fm.
STEPH: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeeee.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Sponsored By:Orbit: Orbit is mission control for community builders. Orbit offers data analytics, reporting, and insights across all the places your community exists in a single location. Orbit’s origins are in the open-source and developer relations communities, and that continues today with an active open-source culture and an accessible and documented API.
With thousands of communities currently relying on Orbit, they are rapidly growing their engineering team. The company is entirely remote-first with team members around the world. You can work from home, from an Orbit “outpost” in San Francisco or Paris, or find yourself a co-working spot in your city.
The tech stack of the main Orbit app is Ruby on Rails with JavaScript on the frontend. If you are looking for your next role with an empathetic, product-driven team that prides itself on work-life balance, professional development, and giving back to the larger community then consider checking out the Orbit careers page for more information. Bonus points if working in a Ruby codebase with a Ruby-oriented team gives you a lot of joy.
Find out more at orbit.love/weloveruby.Scout: Scout APM is leading-edge application performance monitoring designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise-platform feature bloat.
With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve performance abnormalities -- like N+1 queries, slow database queries, memory bloat, and more.
Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them.
Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform.
See for yourself why developers worldwide call Scout their best friend and try our error monitoring and APM free for 14-days, no credit card needed!
And as an added bonus for Bikeshed listeners: Scout will donate $5 to the open-source project of your choice when you deploy.
Learn more at scoutapm.com/bikeshed.Support The Bike Shed

Aug 31, 2021 • 45min
306: If You Want To Go Far, Go Together
In this episode, Steph and Chris talk about things they've changed their minds about over the course of their careers as software developers. Steph talks about as it turns out, arm chair rests are good, feature flags and comments are also good, she's changed her mind about how teams structure the work that each person is doing at once, and believes strongly in representation in the field.
Chris is not a fan up upgrading his operating system and when he first started out, he gravitated towards learning dynamic languages, and since then, much prefers functional languages, static typing or more broadly, static analysis. He also no longer believes in the 10x engineer, and also very much believes that URLs matter on the internet. So basically, don't call them single-page applications; call them client-side applications instead!
Arq
Karabiner-Elements
Kent C. Dodd’s Epic React Course
The Art of Code Comments by Sarah Drasner
Gary Bernhardt: Functional Core, Imperative Shell
Steph's Standing Desk - curved top - 55x28
Transcript:
CHRIS: I still have dreams that I missed an entire semester of math class, and now it's time for the final. I don't know that I'm ever going to grow out of that.
STEPH: That's wild.
CHRIS: You don't experience that? It's a mixture of I'm in elementary school, but it's a college final. Like, the physical school that I'm in is my elementary school, but it's a calculus college course that I missed. And now it's time for the final, and I won't graduate college as a result. But it's also high school at the same time. Just every part of education sort of melded together into this nightmare scenario. Do you not experience that? I thought this was normal.
STEPH: [chuckles] Not in a very long time, not since I was in college. But I'm imagining this very cute, young Chris showing up with a backpack to the calculus final like, "Oh no." [laughs]
CHRIS: Yeah, pretty much, yeah. I really thought I would grow out of it at some point. But it shows...I think it manifests when I have anxiety about something else in the world, and then I have a math terror dream.
STEPH: That's your stress sign. That's your terror dream.
CHRIS: Apparently.
STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari.
CHRIS: And I'm Chris Toomey.
STEPH: And together, we're here to share a bit of what we've learned along the way. Hey, Chris, how's your week going?
CHRIS: Oh, it's going fine. Yeah, I'll go with fine. I had to upgrade my operating system. Enough things had stopped working or seemed to be pestering me about it regularly, which normally I'm going to ignore that for as long as I can. That's sort of where I'm at in the world these days. Like, I don't want to upgrade because I don't know what's going to break and whatnot, but then things had broken already.
Text messages were no longer showing up on my computer. And it turns out that the primary way that I interact with text messages is by replying to them through my computer. I don't want to type on my phone, that's not a thing. I'm already grumpy enough about text messages, to begin with, that I will regularly respond switching to email, and then I'll go off from there. But yeah, they stopped working, it stopped connecting.
And then I got this really weird message from Apple when I tried to sign in. And I was like, I feel like I should at least try to upgrade to the new operating system, which I think has been out for a long time, and I've just been ignoring it. But then I had the added problem of I didn't have enough space on my computer to install it, which I tried once before.
So I downloaded the installer, but the installer downloader doesn't check whether or not you have enough space to do the install. So it's just like, hey, so you know how you didn't have enough space? Well, we took up the remainder of it, and now you can't do anything about it. And the installer is hidden somewhere in the computer. So at one point, it just went away, and then suddenly had a lot of space on my computer. But finally, I decided to bite the bullet.
I found a bunch of caches on my computer. So there was a cache for my backup utility, which is called Arq, A-R-Q, which was a lot of space. It was like 20 gigs or something like that. So it was like, sorry, you have no more cache. I'm pretty sure my computer's going to light on fire the next time it tries to do a backup because it has no cache to rely on, and it's got to try a lot harder, pull a lot more data down. I don't know what it does, but whatever. It's going to do that.
And then, I found the more general application caches on the computer. Spotify had like six gigs of cache. Well, what are you doing? Aren't you streaming from the internet? Stop it. That's not okay. That is not acceptable. Yarn had three gigs. I was like, what is everybody doing? And I busted all of these. I threw away everything, and my computer seems to be doing fine after the fact. So, were the caches even doing anything? I ask.
Anyway, so I upgraded, and then some stuff didn't work. And so then I had to find the versions to make stuff work. The particular one that stood out was Karabiner-Elements, which I used to make my mechanical keyboard do the right things for the function keys. That stopped working. And I tried to upgrade it to the newer version because I figured okay; they probably hopefully released a new version, but it failed in the upgrade process.
And it turns out the secret was I had to upgrade to an intermediate version. I was on 12.3, and I needed to go to 13.4. But in between, I had to go to 12.10. And if I went to 12.10, then the upgrade to 13...everything about it was everything that I hate about upgrading software. It's like, I just know it's working right now, and I feel like if I even just look at it wrong, this whole tower of software is going to fall over.
The worst thing, the thing that I have not been able to fix, is now I use iTerm as my terminal, my terminal emulator as it were. And I typically run with transparency mode on which some people look at and say, "Wow, that's a choice." And I say, "I kind of like it. I don't know; it makes me feel like a hacker or something." I don't know, whatever. [chuckles] Let me live my life. But for some reason, switching to Big Sur, the version of OS X that I'm on now, iTerm doesn't have transparency anymore. And I just haven't been bothered to fix it yet.
But, man, I got rambly. I clearly have some feelings about upgrading software.
STEPH: You have so many feelings. The fact that you kept going...People can't see me, but I'm just dying because of that whole story. [laughs]
CHRIS: I kind of felt like I had to get through it. I had to exorcise the demons, tell my tale, and then be done with it, which I think I'm at now.
STEPH: When I start laughing that hard, [laughs] I try to hide from the camera view because I want you to keep going for people to listen.
CHRIS: But what's fun is you bob and weave. You'll hide for a minute, and then you'll come back and be like, okay, I'm composed, never mind. And then you'll just fade off to the side again. So yeah, but I powered through. [laughs]
STEPH: Oh, all right, there is so much there. [laughs] Upgrading is the worst. I agree with that. That was actually something I ran into earlier this week. Well, it was a mix of where upgrading presented a problem and then upgrading something else resolved that problem. And so that was an adventure where I shared a tweet. I can link to it in the show notes as well.
But Ruby was just taking up 100%, a full core, just all the time, and I couldn't figure out why. I wasn't doing anything with Ruby. We weren't talking at the moment, but it was just turning up one of those 100% CPU or higher. And so then I did some searching. And I did find the resolution, which was to upgrade the Listen gem because there was something in the Listen gem that didn't fully support Big Sur. Is that the name of the thing that I am on?
CHRIS: That's the new one, yeah. I know because I've just upgraded to it. I have thoughts on the matter. [chuckles]
STEPH: Cool. [chuckles] Yeah, when I upgraded to Big Sur. But then someone had kindly marched in to fix it, then upgrading resolved that problem. And Ruby is back to a peaceful level as to the amount of process, the amount of CPU that it should be taking up. Transparency mode, I'm thumbs up on it. I like how you called that out, how that's a choice. And I'm with you on that choice, although I didn't realize that's broken. I guess I just hadn't...I guess I don't care deeply enough that I've tried to restore my transparency, but you're telling me to hold on.
CHRIS: We're going to get realer now in this moment. So I have a very old version of iTerm because it has a different way of going fullscreen than the default operating system level fullscreen. I really hate that it animates to fullscreen, and it doesn't quite fill the full screen. Like, it still had a border around it or something. So I have a very old version of iTerm that I've been running with forever, and I refuse to upgrade in any way as a result of I want to cling to this old version of things working. But as a result, I think I finally hit the end of the road on that. This is like years running now too.
I remember I kept it in a Dropbox folder so that each time I upgrade or get a new computer, I'm like, okay, good. I still have my old special version [chuckles] of iTerm. But I think that time is over and I got to find...I feel like there are new terminal emulators out there. It's like Alacritty and other stuff that people talk about. So maybe it's time for me to try and find something new as long as I can get that transparency because I want to feel like an uber lead hacksaw.
STEPH: You have such a brand of new-new that I'm now discovering that you are also a software hoarder, so you have both in your personality. [chuckles]
CHRIS: There was a period early on in my software career that was like, oh, I got to find all this stuff. I got to figure things out and configure it. And then I was like, wow, that's taking up a lot of my time, I should stop it. And I think since then, I haven't upgraded anything. If you go look at my .files, I don't know the last time I pushed to them, but it's been a while. I'm still doing things, of course, but not as much. I know the cost of it, and I know the cost of maintenance.
And really, this is an allegory for software overall. This isn't just about our local development environments, but entropy exists in software. Software does not exist at rest, and it will decay over time. And so the idea of we've worked with so many clients where they're like, yeah, we're on Ruby 1.8, and it's Rails 0.9. So okay, all right, well, we're going to have to deal with that, it turns out. We can't just keep ignoring that. So really, it's the same story played out but in my local hoarder cavern.
STEPH: There was a part of the saga, the story that you shared with the installer and that you don't have enough space, and it took up the rest of the space, and you can't do anything. I'm very nervous; what happened to your stuff, your space? How did that resolve? [chuckles]
CHRIS: I finally bit the bullet. And so I have a bunch of...I've tried a bunch of the different pieces of software that will visually analyze your disk space. So they crawl the whole directory starting from the very root of your computer, and it will be like, all right, applications has this much, and the library directory in your home directory has this much. Here are all of the different places that stuff might be hiding on your computer. And then you can visualize and be like, okay, that's where the most of it is.
Node modules, as an aside, we did not choose an efficient way to approach how to put code on my computer because Node modules take up a lot of space on my computer, but they're so spread out. Multiple times I've seen people share a version of rm -rf, and then it's some subshell that does find every Node modules directory underneath a code folder. So you can find every single Node module and just blow them away. That will regain you some space. But that was not the solution this time.
I've tried lots of piecemeal solutions over time. But eventually, the thing that got me there was just busting all of those caches. So I cleared the backup utility, Arq's cache. I cleared a bunch of them, Spotify Yarn, et cetera. And that cleared enough space for the installer to actually run. And then, once that was done, the installer program itself was no longer around, so I reclaimed that space. But it was this weird chicken and egg thing where I had to have enough space to complete the installation such that the installer could go away.
And now...actually, let me see what my hard drive looks like now. So somehow, according to the Macintosh hard drive info, I have 50 gigabytes of available space, which is really frustrating because there were a number of weeks where we went into a Bike Shed recording, and I was like, I have one gigabyte. I'm not safe right now because this audio is going to be more than that. And so I don't know how now I'm sitting at 50. I guess all those caches that I cleared and the installer being gone probably puts me in a good spot.
But anyway, I'm living in an upgraded, wonderful world. As an aside, Big Sur is ridiculously rounded and colorful and almost cartoonish. They're really leaning into the iOS vibes. And I'm not sure it's my personal aesthetic, but that's fine. I spend most of my time in the terminal anyway. But I think that's enough of me ranting about upgrading my operating system, which apparently I had a lot to say about. But what else is up in your world, Steph?
STEPH: I do appreciate the ranting, though. You're not often grumpy, and when you are, it's quite humorous. [laughs] I really enjoy the grumpiness. And it's often a painful process. So I appreciate all of that story.
Something that I really need to share with you and get off my chest is a couple; I don't know, x number of episodes back, you and I were talking about computer chairs. And I bragged about the fact that I have a computer chair that has no armrest, and I love it. I love my chairs like this, and it's wonderful. And I just think it's the best way to live.
And it turns out that that's bad because I happened to go see a massage therapist who's also very well-skilled in physical therapy and other areas. And they were talking to me about my desk setup. And I mentioned the fact that I get these typical headaches, and I have my chair, but there's no armrest. And they're like, "Oh, that would do it." I was like, "Why? I like my setup. What's wrong with it?" And they're like, "Well, if you don't have armrests, then your back is having to compensate and to hold up your arms and your shoulders all day. So while you're typing, you're using more muscles to then hold that. And then they eventually tighten and contract, and then that can cause headaches."
So in case, I have led anyone astray into having no armrest, they are apparently very important to not having headaches or having your back overworked to the point that you have headaches, which I'm a bit sad about. But on that front, I have ordered a new chair, and we'll see how it goes. I will have to assimilate into the world of chairs with armrests.
CHRIS: We welcome you with open armrests. [laughs] Sorry, I saw it, and then I went with it. Anyway, I'm realizing now I actually don't use the armrests on my chair per se. I actually end up putting my arms on the desk, which is probably not ideal either. I have a little wrist pad so that my wrists are brought up and so that I don't have the upward breaking of the wrist thing going on. I think that matters a lot. And then my arms are supported by the desk, but it is just right on the desk, and I wonder if that's worse. But I've never...I don't know, getting the armrests just right and then also having the wrist pad.
But I can't adjust my desk is probably the main problem. If I could bring my desk down a little bit, and if it were a thinner top, then I'd have more flexibility. The chair that I have is wonderful and has flexibility. The arms can go up and forward into the side and lumbar and this and that. And so I'm able to make the chair work to the desk. But I do wish I had more of an adjustable...ideally, like a stand-sit desk. But I haven't made that jump just yet.
STEPH: When you're ready to make that jump, I'm going to share with you where I bought my desk because I'm really happy with it. And it's also not nearly as expensive as most of the other desks that will go up and down.
CHRIS: Presumably, we can include it in the show notes as well so that we share it with everyone.
STEPH: Definitely, yeah.
CHRIS: Otherwise, that's just kind of mean. [laughs] You and I have a weird back channel that we talk about on the show, but they're not actually put in the show notes.
STEPH: We're not mean. We wouldn't do that. I love my desk. And it was from someone else. They're the ones that shared it with me, so I'm happy to pass it along because it has served me well. And yeah, I'm also not sure about how this is going to work with the chair and the armrest because I'm just worried they're going to be too wide, and they're not going to actually offer support. I have doubts. I have lots of doubts, but I'm willing to investigate. And we'll see how this goes because I would like for the headaches to stop.
CHRIS: Good luck on that front. That definitely seems like an indication of worth putting in some effort there.
STEPH: Agreed. I also have some other exciting news. Stephen Hanson at thoughtbot has organized a number of other thoughtboters to get together who are interested in really diving into leveling up, learning React, and specifically focusing on purchasing the Kent C. Dodd’s Epic React course. And it's for anyone that is comfortable writing code, whether you know React really well or if you're new to it. Everyone's welcome to join.
So we just kicked that off today where we're going to go through the course together and then meet every Friday. I think the cadence is probably three hours, three and a half hours every Friday, that then we're going to commit to working through the course together.
And I have to admit, I always nerd out a bit over how does someone build a course? Like, I'm really excited about the content as well, but I just want to know how did someone go about producing this content and then sharing it with everyone? And then what's their outline? How do they help people that are getting stuck because they can't be there in the same room? How do they record their videos?
So I'm really excited to see all the ways that Kent has crafted this workshop. And so far, there's so much content, but I'll have more to report as we really start to dive in. But I'm excited to revisit React because I haven't been in React land for at least a year and a half; it’s been a while. And so it's one of those areas that I know some bits, but a lot has also changed. And I would like to just revisit that world. So I'm really excited to dive into the course.
And so far, I really like the structure that Kent has taken with the curriculum where we're focusing first on what exactly is happening and all the effort that goes into if you wanted to actually write HTML and then layer on JavaScript on top of that. But then here's how React makes that easier for you. Here is how JSX makes it even easier on top of the React API. I really liked that. Here's some pain; feel a little bit of pain, let's get a little bit better. And then let's get even better on top of that. And that has been a really nice reminder and progression into the course.
CHRIS: I'm definitely a fan of the way you're describing it like, feel some pain, and then let's get better. But then, like, what's the hook? With any educational content, this is the sort of structure where there can be full education. But this is the thing that I feel very deeply about conference talks is my goal isn't to teach you everything if I'm giving a conference talk; it is just to get your attention just to say, "Here's the thing, here's why you might care." And starting from the problem, starting from the pain is always such a good way to do that. Because you know how this stuff is hard? What if I had an option that was easier? And then building from that totally makes sense.
I want to say that course, Kent's course was built in conjunction with the egghead team, egghead.io. And it's a distinctly branded course. But it was built on top of the framework in the platform that's there and all of that, and then some of the editing support. I don't know this for certain, but I think there was some teamwork there.
And I love just pushing forward the envelope of how we do educational content in the world of development because it is such an interesting world that has, frankly, such a need for ongoing development. The world is changing out from underneath us every two days. And therefore, having great educational content is so important. So yeah, definitely interested to hear how your experience goes both with the course and then also diving deeper into React.
Well, switching gears just a little bit, I had a topic that I wanted to dig into with you today. And so to give some context, the topic, the thing that we're going to be talking about today is what have we changed our mind about? So you and I have both done a little bit of thinking and tried to come up with some answers to this. The background, this was actually inspired by a tweet that I saw between Shawn Wang, aka "Swyx" on the internet, and Charity Majors, a recent guest here on this podcast.
And Charity is someone who is known for having strong opinions. But Shawn asked the question of what are some opinions that you've changed your mind about? And Charity actually had a wonderful list, which we'll link to her tweet thread where she shared some of her both technical and then also more personal ones, but really talking about the sort of evolution of thinking and the way someone's thoughts can change over time.
And I thought it was just such an interesting thing because, for most points in time, we experience someone's sort of snapshot of where are you at now? What do you believe to be true? But I think there's such an interesting story and sort of the arc there of what did you believe to be true that you don't anymore? What have you softened your beliefs on? What have you strengthened your beliefs on? So yeah, with that as the context, what have you changed your mind about, Steph?
STEPH: Yeah, this one really got me thinking, and I feel a little stumped on it. I have a few that I'm excited to share. But I'm very excited to hear your list to see if that also helps me reflect more on some of the things that I have changed my mind about. And I have found that there's only a couple maybe that I feel like I've really solidly changed my mind about. The others, I've either dialed up the strictness, or I've dialed it down. So the ones where I've really changed my mind about are feature flags and comments. Those are two of them. Well, there's a third one, but I'll get to that in a moment.
So starting with the first one, feature flags I was more in the camp where I very much appreciate feature flags, but I use them sparingly because then there is a tedious nature of introducing them and then having to clean them up, and then having to maintain two states of code. But now I've really seen the value of feature flags and how we can make sure that we have calm releases and ensuring that main is always in a deployable state. So feature flags is one for me. I'm very invested in having more of a robust feature flag system because I see the benefit to that.
The other one was comments. I used to be very rigid about comments are bad. We should never have comments in our code. They are just waiting to go out of date, and they're not going to be helpful. But I have since dialed down that strictness where I have certainly seen moments where comments do feel very helpful, and I can see how people use them. I still want to avoid them for the most part, but I am less strict now in regards to people who really find value in comments. I'm more open to that discussion. I want to understand what it is they find helpful about that comment, and if it is something that we can't capture with code or a test, where does that live?
CHRIS: Those are both interesting. Feature flags, for me, I think I actually was more strongly opposed in the beginning. Earlier on in my career, I saw them as added complexity, as noise. I often would encounter them left behind in a codebase. And so, I had this negative association with them. And I didn't see the value; I hadn't yet felt that pain. And over time, I've definitely shifted to where you're at where I'm like, I love feature flags. This is a critical tool in our toolset of how we actually…like you said, calm deploys, being able to always deploy main, making sure that we don't have long-running feature branches. There are so many benefits that come out of it that I'm now very strongly in favor of them. But it's interesting; I think I would say that I started in a more strongly opposed place. So that wasn't on my list, but it's an interesting one that you've brought up and probably one that I've moved more on.
Code comments, I think, actually started in my career being like, obviously, you comment your code. It's the thing that I read about and stuff. And slowly, over time, I think I've just dialed in on I don't think we should be doing that. There are, of course, going to be exceptions.
And actually, one of the things that I discovered about myself as I was trying to go through this exercise is there are very few things that I believe are black and white. If anything, that maybe is one of the things that I've leaned into over time. It's like, nothing is binary. Nothing is black and white. Everything is on a continuum or shades of gray. There are things that I believe a little more seriously. But there's almost nothing that I can be like, nope, absolutely I will not equivocate on this beyond how we interact with other humans and being reasonable, kind people. And in terms of software practices, not really. Comments, though, are one that I still am pretty strongly not going to lean into. So it's interesting that you're like, eh, I've kind of opened up to that one.
STEPH: There's a particular talk, The Art of Code Comments by Sarah Drasner, and that's the one that really shifted some of my opinions around comments, and then how we talk about them, and what benefits they can play. But I will admit, if I see a PR that has code comments, I still immediately have a negative reaction to that. And I want to have a conversation around why that comment was added and if we can remove it, and how we can remove it. But even with that negative perspective, I still find that I'm more open to that discussion versus before, where I would have been like, no, that's just unequivocally bad.
CHRIS: I do like that you always bring up that talk whenever we talk about comments. This is a great talk. And in the background, I just looked up Sarah's Twitter profile because every time you bring it up, then I mention that she has a still from the movie Labyrinth in her Twitter background, but she actually changed it. And so now that's not true anymore. It's now something from The Force Awakens. Well, it's actually a joke, but I'm still going to suggest that you watch the movie Labyrinth at some point. That's the thing that I feel actually kind of weird about. It's a weird movie.
STEPH: I'm going to take your suggestion, but not watch it. But thank you. [laughs] To share my truth today.
CHRIS: That's fair, that's fair.
STEPH: What are some of the things on your list?
CHRIS: Okay, I have a couple, some more on the technical. Let's lean into one of the technical ones. Early on, I started with dynamic languages. I think I started with Python primarily and a little bit of JavaScript. I eventually found my way to Ruby and felt very at home there. And then, I started to explore functional languages. And I started to lean into them really hard and felt that immutability and functional programming and true pure functional programming was the thing. It was the answer, and I just needed to figure out how to do it. And so I would say that is the belief that I have since changed my mind on and decided, you know what? Actually, it feels like a bit of a force fit. I have tried. And maybe for others, it is actually a really fantastic way to build software. But having worked with a number of other people in more functional contexts, I find that it is a bit of a force fit. It's a bit rough.
And in particular, of late, I've been working with Svelte as opposed to React, and React does sort of lean into the functional paradigm, especially with Hooks and all those sorts of things. And it's a little bit rough because it turns out UIs are these deeply mutable things. We're changing values or typing things in. There are actions that are changing the state over time, and having a system that just more directly models that feels very natural.
I still love functional programming for the more core of an application. So again, I reference this talk often, but Gary Bernhardt's Functional Core, Imperative Shell. Gary has really formed some of my thinkings on this. And now I've started to find the examples in the work that I'm doing of like, oh, okay, I see that pattern actually applied here. But much as I would love to use them, the functional languages I find just aren't quite landing for me. And additionally, the mutability, particularly in the front end right at the edge of the UI, is not quite as good of a fit.
STEPH: So I think that resonates with me although I do still get very excited about following more patterns that represent more immutable state just because I felt so much pain and found bugs from the fact that we have mutated state in surprising ways. I'm honestly not quite sure how I feel about it. I'm going to have to think on that one. That's a very interesting one that you've changed your mind on.
CHRIS: Yeah, similarly, my feelings are lukewarm, whereas before, they were stronger. I was like, oh, okay, I think I found something here. And then, in attempting to use it across a wide variety of applications, it just didn't quite feel right. I felt like I was swimming upstream sort of thing.
Actually, there is an interesting counterpoint. One thing that I have leaned into and definitely changed my mind on and embraced is static typing or, broadly, static analysis. But I think static typing being the most pointed version of that. Early on, like I said, I got my start in very dynamic languages in Ruby, and Python, and JavaScript. And so that dynamic duck typing runtime can be anything. We just make our systems respond to the messages, and all of that sounded great.
But it turns out I really love having a compiler that can tell me some truths about my program before it ever reaches runtime. And the idea that a typo can make it to production feels absurd at this point. And actually, as I'm working in Ruby, I'm like, man, I really got to go look at that whole Ruby typing thing we got going on. I don't know what the state of it is. I've looked at it in the past, and I need to revisit it soon. But like TypeScript, I've definitely embraced that very strongly. And I would not work without TypeScript in a JavaScript project at this point.
I've loved the work that I've done in Elm, although that also sort of blends into the functional stuff where it's like, it was a little bit noisy, though, I'll say that. But the type system and the fact that the compiler can give you so much rich information about your program, I would not trade that at this point. And I don't see myself going back on that front, which is an interesting place for me to be on of actually, I'm not that into the functional programming as the core way that I build my applications.
But I do like static typing. And I feel like functional programming and static typing actually go together incredibly well. And functional programming and, more imperative, whatever it is that I'm doing with my day-to-day life these days is a more interesting fit. But it is interesting to me to observe that sort of combination of opinions where I really like static typing, and having a compiler, and something that can tell me about my program before I get to runtime. But also saying that I don't quite want the functional programming thing, or at least not as the entire way that I modeled my application because I found it a bit difficult to work with. Because I think static typing or compilers and functional programming go really well together.
But I think generally, what I'm finding is a more middle ground dynamic optimization of a bunch of different things. And the answer is like, well, it depends which I guess if you've listened to the show before, you'll have heard those words said, so I guess it makes sense.
STEPH: Yeah. All of that makes sense to me. And I can see why you might have a favor for types or why that feels more valuable initially because that is giving us so much feedback right off the bat versus following a more functional paradigm is something that could feel like more of a force fit and doesn't provide that same immediate feedback. But it has a longer-term or a longer cycle of that reward system. So I can see why you might favor one over the other or why I myself would favor one over the other.
CHRIS: How do you feel about types?
STEPH: I'm a big fan, although I say that, but I work in Ruby. [laughs] I don't have them. But when I have worked with types, I very much enjoyed it because it makes me think more about the design of my code in a way that I don't as much with Ruby. And working with types has heavy influence than when I am working in Ruby and thinking about the design of my code. So I think working with types is a wonderful thing that, frankly, all of us should do as developers at some point because it is so influential. So I'm for types, but I'm not using types in my day-to-day.
Another thing that I have changed my mind about is how we structure the work that each person is doing. So I used to be more in the camp of everybody can work on their own very complicated piece of codebase, their own complicated feature. We can have a bunch of complicated things in the sprint, and everything will just be great; it’ll be fine. And we'll get a bunch of work done, and we'll ship it. And then we're an even more productive team.
And I very much disagree with that now where I have found where everybody is working in their own silo on a complicated feature has slowed down the progress of then being able to ship that feature. Because we often want to collaborate with someone, we need to collaborate with someone. Then the PR review process is tough if I really have no idea what you're working on, and I don't have a context that then when I look at your code, not only am I evaluating at the code level, but then I'm also trying to understand the feature and gain all of that context. And that's a heavy cost for me to have to pay to then pick all of that up and then for you to have to reintroduce me to what's happening. Or I might make the bigger mistake, and I may look at your code and just evaluate it from the code perspective but not really understand the feature, the value that's being delivered. And that doesn't feel useful.
And I have a recent example where that happened where someone was working on a very complicated feature that I didn't have any insight into. So then, when I was looking at the PR, it was easier for me to just look at the code and get feedback on that. But then it was probably a day or two later. It wasn't until then that I finally started asking, what are we building? Like, what purpose is this serving? And that opened up a much larger discussion where we realized what was being built didn't actually really deliver what we needed to deliver. So I no longer agree with the idea that everybody should be working on their own complicated features independently, and there should be some collaboration. And, you know, it's the buddy system; we all need a buddy.
CHRIS: Well, I like that one. I feel like I've shared similar ideas where it made sense. It was just the efficient thing to do, to split the work up and have everybody very independent. I also feel like earlier on in my career; I was more scared of Git conflicts and things like that or people interacting with the same parts of the code. And so in my mind, it made sense to really strongly separate like, oh, you shouldn't even be touching the controller for this. I'll handle the views, and you handle the controller; it'll be separate. And I care less about that now. And I think what you're saying of like, it's actually better if we have some shared context, and we understand what we're working on, and it's more of a collaborative process. Yeah, I like that one. I think I followed a similar arc, and I'm at a similar place now as well.
Interestingly, to go into another one of mine that I think you'll probably be most surprised by on my list is I think I used to believe in 10x engineers. I used to believe in the idea of that one developer just off in the corner fueled entirely by Mountain Dew that would just produce the perfect code. They would just solve it. Over the weekend, they would write the entire billing system, and it would be great. And I think it was predicated on the idea that the coding is the hard part, which I no longer believe. I think coding at its core is communication. It's taking this thing that we want to be true in the world and then communicating it to a computer but also ideally communicating it to our teammates, and to future versions of ourselves, such that we can revisit that code, we can maintain it over time, other people can add to or augment it.
And so the idea of this loner that can just do incredible volumes of work and have that be a good outcome that just doesn't make sense to me anymore. I've worked with incredibly talented developers, to be clear, folks that I was sort of in awe of. I've worked with people who have, I think, just truly photographic memories. They seem to remember every single bug that they've ever had and exactly where they can look it up. Or from the top of their head, they can just intuitively know, oh, this bug means this. Go look at this line of code. I'm like, how did you do that? How did you do that magic trick? And they're incredibly capable developers. But at the end of the day, the folks that I see being most impactful on a team are the folks that are able to communicate and collaborate most effectively and make the whole team more effective.
STEPH: Maybe it's the Mountain Dew; maybe that's actually the secret sauce here. That's what I'm missing from my life to take me into that status.
CHRIS: I'm now imagining Mountain Dew but in a more viscous form, like a barbecue sauce, but it's Mountain Dew flavored. That's the secret sauce because it's a very…anyway, moving on. [laughs]
STEPH: It's a terrible product. We should make it and sell it.
[laughter]
CHRIS: Career pivot, we now sell Mountain Dew sauce.
STEPH: [laughs]
CHRIS: But yeah, I do not believe in 10x engineers anymore. If anything, I believe that that is a huge warning sign if you have anyone that's behaving in something close to that space.
STEPH: Yeah, I'm super interested in that you've shared because I don't think...We've talked about 10xers, but we haven't talked about the fact that you used to think that they were more of a thing and that they existed. And now it's all I'm sorry, but it's all crap. [chuckles] That's super interesting to me. Do you remember what changed your mind? Do you remember that pivotal moment of where you were like, oh, maybe this is all bullshit?
CHRIS: I think it was just an amalgamation of experience over time. I've encountered people who fit the archetype. But if anything, I would say they're deeply problematic in teams. They're that individual who refuses to collaborate, who just goes off and heads down, writes a bunch of code, but then it doesn't integrate with the other pieces, or no one else knows how to use it, or they won't let anyone contribute to it. And yeah, I've seen that just be very, very problematic.
So the folks that most fit, I think the imagined version of this, actually end up, in my experience, leading things astray. And the folks that are actually most productive and really cause teams to improve in a drastic way behave very differently. They're much more collaborative; they’re much more engaged with the team. It's less about their individual contributions and it's more about building a system together, collaborating, communicating, engaging external stakeholders, et cetera, et cetera. It's all that stuff that matters. And so, it's very much in contrast to what the 10x engineer ethos is about. But there's no one day where suddenly this idea that I had in my head crumbled when I saw that behind the pile of Mountain Dew cans, there was nothing there. [laughs]
STEPH: It's all a mirage. [laughs] I do like what you just said around that there are very impressive people out there. And those impressive people often focus less on their individual contributions and more at a higher level around communication. And then they are the powerhouses that then is helping facilitate everybody else be their best and have high levels of individual contribution. Those are the ones that...I'm still not going to endorse a 10xer, but they are the ones who, to me, embody the idea of someone that is incredibly efficient and really good at their job.
CHRIS: There's an adage that comes to mind here that "If you want to go fast, go alone. If you want to go far, go together." And that does ring true to me. I think an individual can have their individual productivity be higher if they're working entirely on their own, if they understand every line of code because they wrote every single line of code if they know where every feature of the platform is integrated because they wrote the whole thing. But they're going to be fundamentally limited. And in order to do bigger, more complex things, fundamentally, we have to work as a team. And then the way you have to interact just fundamentally changes.
So I think it started from that, like, one person on their own I think can be individually more effective. But the minute you start to have a team, that one person acting on their own is actually dragging the team down because other people can't then work in that space, and that's a problem.
STEPH: I really like that adage that you just shared where, "If you want to go fast, go alone. If you want to go far, go together." And that touches on something else that I have really changed my mind about, and that's representation. And this is more specific to me. So when I joined engineering and became a web developer, and I joined a team, and I was the only female engineer on that team, my initial feelings were I am the only female engineer, and that is fine. We're all just a group of engineers. We're here to solve problems together. It really doesn't matter if there's anyone here on this team that's like me. It's fine if there's no one that I can see myself in that's in leadership because we're all just people, is what I was coming down to. And I've completely changed my mind and realized that that's not true.
And I've experienced this where I've worked on other engineering teams with female engineers, and it's fucking awesome, and it does make a difference. And then when I can see someone that I can see myself in, in a leadership position, that is also inspiring. So that is something that I went in where I think it was more of I was trying to shield myself from the idea that I am different from everybody else in this room, and that could be a problem. And instead, I just tried to neutralize it by saying it's not.
But I think representation is incredibly important. People are not just people. We all have very important social and racial, and cultural identities. And it's very important that we get to feel that we can express all of those identities and see people that represent those identities in spaces where we would like to go. That's a big one that I've changed my mind on.
CHRIS: Yeah, I certainly agree that representation certainly matters, and being able to bring your full authentic self to work and seeing others around you that reflect that. And frankly, having teams that are made up of people that represent the users of the software that we're building feels so critically important. And it's very interesting to hear about the arc that you've had on that where initially, you tried to downplay it, but then you found a little more truth in it. And so yeah, thank you for sharing.
STEPH: You're welcome. It feels good to say that, too, because that's something that I've admitted and realized on my own, that that is something that has changed and shifted. But it's nice to be able to share that here with you as we're going through the things that we've changed our mind about. What else is on your list?
CHRIS: Well, to round us off with one more very technical version because, of course, that's where I'm going to take us after a much deeper and more nuanced topic that you led us on, single-page applications. Broadly, I'm opposed to the name; that’s a side conversation. But, man, URLs matter on the internet. So don't call them single-page applications, but client-side applications or whatever. Broadly, the idea of a bundle of JavaScript, and so you send down an empty HTML document, and then you reference a bundle of JavaScript, which that thing boots up and it then makes a bunch of API requests to the backend, and then it starts to fill in the page.
I was convinced for a while that this is a reasonable and perhaps even necessary way to build software. We need APIs for our mobile apps anyway. So if we're doing that, then let's have that be the consistent way that we are accessing information. This is going to be fine; it's not a problem. And then eventually, we found some problems. So then we got GraphQL, and we tried to solve it that way. But overall…and I have spent a lot of time trying to make this thing work, trying to find a version of this that I'm happy with that I find the end outcome of the software to be as pleasant to work with from an end-user perspective as a server-driven application, and I can't find it.
And so, to be clear, I'm still doing client-rendered applications these days. But Inertia.js is the framework that I've leaned into that helps me bridge that gap. And the idea that the server owns routing, that the server owns statefulness, things like that, not having to think about client-side routing, not having to think about client-side state management, being able to use traditional auth mechanisms built into cookies, all of these familiar things that we've had. Leveraging the fact that the server is the more privileged in terms of the information it has access to, the more secure, the more powerful environment, all of these things feel right to me. And the nature of the application that I can build just feels more robust, more consistent, easier to evolve.
There were a lot of promises that I heard when we started building applications in these ways. And I just haven't seen an example or have not worked on an example, at least of an application that is built as a client-side bundle that boots up and does some stuff and had a good experience with that. So Inertia, as an aside, is my answer to this. And I continue to be extremely happy with that as a solution, as really a middle-ground solution. Because going all the way back to true HTML server-side rendering is limiting in other ways that I didn't like. But I find that Inertia really strikes an ideal balance in the middle there.
STEPH: I feel like I completely agree with everything you're saying. But I also feel like I have a developer secret to share where I really haven't worked on single-page applications, and I am okay with that. [laughs]
CHRIS: It's fine, skip it. Just go straight to Inertia. It's better.
STEPH: Cool, cool, cool. I am working on leveling up React, and then the plan is to go to Svelte and Inertia. So I'll just completely...I'll skip that. I'll skip that part of my career.
CHRIS: I actually want to back up just a little bit as I'm saying this because I really try to avoid being in a more negative space. And I think this space, this architecture for building applications, is complex, and there are things that will warrant it. So things like Google Maps, it makes sense to have a lot of Dynamic JavaScript and to be doing complex things on the client-side. Trello is another example of an application that that as a server-rendered thing, doesn't really make sense. And frankly, using a tool like Inertia wouldn't quite work there. That said, that is, in my mind, truly a single page within the broader application. So the Trello board page is a very, very complex stateful application, and I think modeling it as such makes sense. Google Maps, similar. But there's still the profile page, and the login page, and all of these other things.
I think routing is probably where it breaks down for me. I think client-side routing is the thing that I feel the most pain on. Because at the end of the day, the server still needs to know the answer. And if we do client-side routing, we end up with this duplication of logic across the client and the server-side. We end up with disagreements from time to time. We end up with the weird flashes of half-rendered layout, and then we go to the login page because we get an API response that is different. And so, I think that is probably the kernel of the thing that I struggle with. And, of course, it is possible to build great things using any of these technologies.
But I think my summary is I've really tried on that front, and I've just not been able to make the fidelity of application that I want using…primarily; I’d say it's client-side routing is the thing that I struggle with the most.
STEPH: Yeah, it sounds like you're saying there are very valid use cases for using a single-page app or following that structure. But we haven't really gotten there in terms of our web development expertise, where we've made that easier to maintain and easier to implement. And there's still enough pain points around it that even though it seems like a very valid idea and approach, it still feels painful enough that you actively avoid it until it feels like something that you have to then invest in at that point to then really deliver the user experience that you want to provide.
CHRIS: Yeah, I think that's an accurate summary. And I think adding on to that, I’m noticing it becoming more and more of the standard approach; this is the way we build applications, and I don't agree with that. That is probably the thing that is the kernel of what I don't believe in. I think actually server rendering is a great way to start, and then you can slowly augment or move more things into complex client-side behavior. But starting with this as the mode that we're building our applications just feels like a less stable foundation than I would want. So it's perhaps an architecture that you want to evolve to at some point as the complexity necessitates it, but I definitely wouldn't be starting there. Similar to service-oriented architecture, not going to start there. Client-side routing, I'm not going to start there.
STEPH: Ooph. I feel like I've been holding my breath this episode. I feel like this was a very interesting topic that has been challenging to reflect on what we believe and what we've changed our mind about.
CHRIS: I think it's perhaps more nuanced than a lot of our episodes where often we're saying this is what we did, and this is how we felt in the moment. And that can be very experiential and true. But this, yeah, we had to draw the line in the sand and say what do we believe? I similarly definitely feel more tension in this episode than other ones. But hopefully, it was useful. Hopefully, folks found some value in the things, and hearing our story, also, the idea that we have singular formed opinions. Hopefully, this episode has broken that idea in anyone's head. And we're all on a journey.
STEPH: I really like how this has prompted me to reflect on the things that I used to hold dear and really cherish or follow strictly to then reflect on what are things that I used to believe versus what I believe now? Because that transition often happens so seamlessly for me that I don't really stop to think about it to be like, oh, something just happened that is really changing how I approach things, how I build, how I work with teams. And I really like this reflection point to be like, oh, what did I used to believe, and what's different today? I'd like to keep this practice going and just try to track the things...I'll have to make a list of all the things I believe. That seems like an easy list. [laughs]
CHRIS: Just the easiest list to write.
STEPH: The easiest list to write. And then I'll just check in with it every so often, scratch stuff out, or update it with the things that have changed my mind about. This is the good idea, terrible idea where you go, "Stephanie, that's a terrible idea." [laughs]
CHRIS: I don't know, write it down on a list, and then look at it in six months and see if it sounds like a good idea, and then we'll be able to close the loop on the whole thing. But with that, should we wrap up?
STEPH: Let's wrap up. I've got a list to write.
CHRIS: The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us @bikeshedor reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeee!
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Support The Bike Shed

Aug 17, 2021 • 50min
305: Burnout & Bugs
This week Chris talks about Bifunctor optics and introduces an app he's been liking recently called CleanShot X, which is a replacement for the built-in screenshot utilities on OSX.
Steph talks about her experience using New Relic Browser Stats to troubleshoot a slow page and burnout. Who's feeling it? (Raise your hand.) How do we identify it? What do we do about it?
Svelte Is Beloved! - Stack Overflow Survey
Bifunctors
CleanShot X
Next.js Image
Transcript:
CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. And we're off the rails already, everybody. It's going to be a good one. Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey.
STEPH: And I'm Steph Viccari.
CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, how's your week going?
STEPH: Hey, Chris, it's going really well. We talked recently that I have a new laptop. So I have been migrating the things that I'm accustomed to over to my new laptop, but I also love that clean, fresh start. So as part of that fresh start, I was like, what if I use Safari? What if I just switch? I'm a Chrome user, for the record. I'm pretty sure you know that, but just to share that. I was like, well, what if I just switched and I try out Safari for a while? So that was the thing.
CHRIS: So I heard the words try and the phrase that was the thing, but I'm going to probe a little deeper. How'd that go? Was it good, great, not so great?
STEPH: Honestly, it was fine. I did enjoy being in a new environment to see how Safari handles bookmarks and then also the inspector. So it was novel to be in a different browser where I really don't spend much time in a different browser other than when I need to test this specific UI bug or things like that.
But the reason that I ended up migrating back to Chrome was frankly for Chrome profiles because I really like that I can have this clear separation now between my work life and my personal life, and then it also keeps me signed in. So my personal email versus my thoughtbot one versus before the Chrome profiles, which I'm not sure how recent of an addition that is where Chrome introduced that feature. But before, I just always had to be signed into both, and it was just all together in one spot. But now I really like that I can separate. And it's more intentional where I'm like, oh, I'm going into work mode, so I just want that profile versus I do need to hop over to my personal side for a while. So that was the thing that brought me back.
CHRIS: Interesting. I don't take advantage of that at all. I know of the feature, but it's never really called to me. And if anything, I do the opposite. So specifically, this doesn't work in the browser, but on my phone, I use the iOS Gmail client, and I use the unified inbox. So I just have everything come together. And I subscribe to the idea of, I don't know, it's all work and stuff. And hopefully, people aren't sending me a lot on the weekends, and I will defer and snooze and all of that. But that holistic view pulls me in. And so it's interesting that you're just on the other side of that. It totally makes sense. I actually think I'm wrong here. I think I'm doing the wrong, bad thing. But it's interesting just the way we're on the two sides of that.
STEPH: I can see the merits for your approach where it all goes to one place. So you have one place to go and triage, and I think that makes total sense. I haven't triaged my personal life well enough that I want it to come into my work life. And that's the one that needs the more immediate response typically. So I want to prioritize all of my work emails and focus on that and then have my personal ones more like, okay, I've got some time, and I want to check on this. But I don't want to blend those together. Because frankly, I need to do some more triage on the personal side if I'm just going to bring it all into one space.
CHRIS: Interesting. Yeah, I would almost view it from the other point of view of I want to protect my personal space, and this is obviously not what I do based on what I just said but protect my personal time so that when it's evenings or weekends or whatever, that I'm not seeing work emails in there. I do my best to snooze them and get them out of the way. But if they are coming in, maybe there's something I need to respond to or, I don't know, maybe it's FOMO in a certain way, FOMO but professional FOMO. I don't really know. It's interesting that that's the feature that brought you back. But overall, how was your experience using Safari?
I have heard loosely that now most of the browsers are evergreen; even Edge has really caught up and is now implementing features in a similar way. And so Chrome, Firefox, and Edge are very similar. And my understanding is Safari is the one that actually lags behind or even holds back web standards and implementations and things like that. So, did you find any rough edges of that sort, or was it otherwise just fine, and it was mostly the profile stuff that made you switch?
STEPH: It was honestly just fine. I also may have not used it long enough to run into any of those rough edges. But overall, it was just fine. It worked. I just got to that point where I've run into this situation before where I'm signed into my personal email, and then I'm signed into my work email. And then I'm going to Google Hangouts, and Google Hangouts gets confused, and it's like, which person are you? And then I have that moment of where I have to sign out of one, or sometimes it just gets complicated. And what I found with profiles is that that's just never an issue. I don't have to worry about it anymore.
So yeah, overall, Safari was fine. I wouldn't mind going back to using it. I just really like the profile feature. This was one of those moments where it helped me notice how much I really liked that feature because I had just opted into it a while back. But this was that moment where I was like, oh yeah, I really miss that. So I'm going to go back to it.
CHRIS: The thing you said a minute ago about which person am I? [chuckles] There's a deep philosophical underpinning there, but I've definitely struggled with that and trying to trick the browser into it. So Trello is the one that I'm struggling with that right now. I am one human in the world, I assure you. But GitHub gets this; GitHub plays the game correctly where I'm one human, but I have multiple internet identities. I am the work person. I am the open-source person. And I'm able to route notifications and things to the different inboxes based on the organization that they're part of, et cetera. And I really liked that, that GitHub seems to understand that I am a human that is multifaceted, whereas Trello does not. And so I use Trello in a professional context a lot, but it's my personal...like, I would have to create a distinct account on Trello. And I'm like, Trello, that's not true; I'm still one person. Just understand this Trello organization is a separate facet of my existence. Got on my soapbox on that part.
The other thing I want to say is I do feel bad about the fact that I'm just on Chrome. Because increasingly, Chrome has got so much of the market share, and it's becoming the new deeply dominant thing. And so I want to be the agent of change or like, no, we should use different browsers, and we should support them and make sure that we're testing against them and all of that. And then I'm just on Chrome all the time, and I feel bad about it. But it's one of those like; I have so much muscle memory and built-up knowledge around how to use Chrome. And I've just used it for so long now that the switching cost would be pretty high, I assume. I actually haven't even really tried, but I feel bad about it. I'm now saying two things which are I feel bad about it, and I've never even really tried. So I don't feel great in this moment, but these are my truths.
STEPH: [laughs] Well, I can plus-one your truths. Those resonate with me. Well, there's always stuff that I am trying that's new all the time. So I feel like I need some constant in my life until I'm ready for other things to be the constant in my life. And then I can muck around with which browser I'm using and change other things. And you have to be in that moment. You have to be ready for it.
So going back to a thing that you said a minute ago about separating your work life and your personal life, I very much like that framing, and that's a nice segue, frankly. And it's something that I've been thinking about where you and I often start with technical topics. But I have a very people-centric topic that I'd love to chat with you about today, and it is emphasis on burnout. And who's feeling it? How do we identify it? What do we do about it?
And that's been very much on my mind because I have noticed a lot of people around me, including myself; I just feel like we are more inclined to experience burnout right now or are going through it actively. And it feels even more important to have those conversations with each other and with ourselves to talk about what does it look like when we're burned out? How do we recognize when we're there? Because often, when we are burned out, it's not something that happens gradually, or at least it's not something that we notice happening gradually. It's like, okay, I'm fine. And then suddenly, okay, I'm burned out. And I'm at a place where then I can't really focus. I feel overwhelmed. I'm drained.
For anyone that is less familiar with burnout, one, hooray, and then two, burnout is a state of emotional, physical, and mental exhaustion that can be caused by excessive and prolonged stress. So then that's what leads to us feeling very overwhelmed, emotionally drained, unable to meet constant demands, or those are the things that are causing our burnout.
So I have been doing what I typically do when I'm thinking about a particular topic, and then I'm looking to gather knowledge and information is I try to go pretty wide where I start looking for podcasts, books, just people that are having similar conversations and trying to synthesize a lot of the information that they're sharing. And I have found some really good stuff. The question is now, what does one do once one has that content, and then how do you bring it back and help apply that content to yourself and then people that are around you? So I have some thoughts there, but before I go further, I'm curious, what's your experience with burnout?
CHRIS: I think for me, I've been somewhat lucky in that I don't think I've ever really got into an acute period of burnout, but I've definitely had periods where I just felt weighed down. And there are ebbs and flows of life, and of work, all of those things. There is something that I've been thinking about recently, which is the inherent nature of the work that we do where consistently we're working on something where we don't quite know how to do it, and we're struggling, and we're struggling. And finally, we figure out how to do the thing, how to trick the computer into doing what we want. And then the minute we do that, in trying to encode, ideally, we're automating that away. And we take that solved problem, and we just ship it off. And then, we pick up the next unsolved problem from the list. This isn't entirely true, but it feels like sometimes unspecificity in sort of I'm just working on things that are underdefined, underspecified, and I'm trying to solve little puzzles constantly. And, I don't know, I was feeling that recently of the nature of the work was burning me out.
And I think earlier on in my career; I definitely experienced this in a certain way. And then, in the middle of my career, there was this perfect inflection point of my skills and the level of tasks that I was going for. But then, the further I got into my career, the more I tend to take the weird underspecified stuff and anything that's relatively clear I'm giving to other folks on the team. I'm like, "Oh, here's this well-defined piece of work here. Can you go implement this admin page?" Whereas I am doing the investigate integrating with third-party platform XYZ that uses a SOAP API that isn't documented. I'm like, okay, cool. Let me roll up my sleeves and figure out what that means. And I noticed in my work that that was starting to weigh on me, and I was able to shake that off and shift around some of the tasks that I was doing.
But that was a particular form where the work itself was weighing on me. And I took a step back, and I was like, why do we do the things that we do as developers? Because there's something just fundamental like, you have to enjoy that nature of challenge and constantly escalating challenge to a certain degree, I think, to really like this work, but it can be a lot sometimes. So I feel like maybe that's a slight digression from the topic, but it was a thing that I was feeling in this space. And that's a little bit of my story.
STEPH: Well, the beautiful thing about that is it highlights everybody experiences burnout differently. So that could really be how someone is experiencing burnout where they're taking on all these very complicated, different tasks, and they're feeling just worn down by that and that they're not able to meet demand. And they get to that point where maybe they lose their interest in tech and coding because they have pressed too hard in one direction. And so then they need to take a step back.
As for me, I've been thinking back over the last couple of months because there was once or twice where you and I had, I think a conversation here on The Bike Shed where I shared that things were okay, but I didn't feel like my normal self. I was losing some of my interest and energy for technology and coding. And I'm very fortunate; I love what I do. So the fact that I wasn't feeling that interest was a really big sign to me that something's different; something feels off. And it does vary depending on the client that I'm working with. And I think feeling that burnout then was a mix of some of those client pressures that I was feeling and that I was working perhaps too many hours as I was very interested in that client's success.
And then the other stuff was more personal because we only have, to borrow from the spoon theory, we only have so many spoons to give. And so if you have a lot going on in your personal life as well, that's going to detract from the energy that you also have to give to work. Are you familiar with the spoon theory?
CHRIS: I am not.
STEPH: I recently heard about it, and I can't stop using it now because I really like it. But it essentially...and there's a really great article that we can link to so others can read about it because I'm not going to remember exactly who came up with this theory. But the idea is that each spoon represents a unit of energy. And let's say if you start each day with only ten units of energy and you use spoons to represent that, as someone needs energy from you, maybe it's work, maybe it's a personal commitment, maybe you're dealing with a chronic illness, then you are giving a spoon away to each of those. So at some point, you're going to run out of spoons. And you want to also be mindful of who you're giving these spoons to because you are giving that energy away.
CHRIS: I definitely liked the idea of we start each day with a certain amount of energy, and different things can pull from that pool and whatnot. I'm intrigued by spoons as the unit. It just feels like a weird...I got this little bag of spoons that I walk around with, [chuckles], and I give them out throughout the day. I guess it could be anything in there, you know, objects. But, I don't know, spoons are interesting to me.
STEPH: I think it's because this person who came up with the idea was literally having a conversation with their friend in a cafe. And so that was just something that was in front of them. And they're like, oh, I can use spoons to represent. Well, we'll have to double-check the article to make sure, but I think that's why spoons became the representation.
So circling back to once you're in burnout, what do you do with it? And that is one of my questions right now. And that's what I'm trying to synthesize a lot of information around. Because once you're in that state, I don't know of a lot of great ways to help other than take time off because, at that point, you're in a crisis state. And you need to step away, and you need to find out how you can recover from having entered this state of crisis. So that feels really important to identify ways that once someone is in that state, that then we can help them. And that feels good. We can advise someone to take PTO. I still don't feel great about it in terms that then, as a manager myself, I don't really know of other helpful ways to then help someone through that period.
So then I really started thinking about the fact that once someone is in that burnout stage, frankly, it's too late. We have let someone get to that point that now they are in that crisis instead of addressing it early on. So that is the other thing that's on my mind is one, how do we help people that are already in that crisis state? But then two, how do we start identifying that someone is starting to go in that direction? And then how do we help them tell us? How do we then triage those situations? How do we prevent them from getting to that burnout state? And that's where I've also found some really good content.
And specifically, there is a podcast that I've started listening to called The Burnout Show. They essentially share their experience with burnout, and what they did about it, how they recovered from it, and then how they continue to fight it because a lot of people then still go back to the workforce. So then, once you do find a way to recover, then how do you go back to work? And there have been some really great episodes. And I'll be sure to include a link for it in the show notes.
There's one particular episode with Grant Gurewitz, who is a guest on the show. And he speaks specifically to the strategy of Three Good Pockets. And this speaks to the idea that there are many things that we can't control in our day. It could be work, family, other commitments, but we can strive for Three Good Pockets of time where we focus on something that's just for us. This is time that's reserved for you and any activity that you find restorative or joyful. And each pocket can vary in size. So perhaps that first pocket is spent just reading a few pages from a book that you're enjoying, and then the next pocket of time is spent outside or calling a friend.
And Grant also has a great suggestion around if you're worried that you'll get sidetracked and not actually step away, which I felt called out for that one because that one's definitely me. I will have good intentions, but then I won't actually take the break that I set for myself. So Grant recommends creating a list of restorative activities so that way when it is time for that break when your calendar is reminding you, then you have a list of these activities to choose from. So it makes it easier to say, okay, then I can do this for a couple of minutes, and I can truly step away from work and step away from my screen.
But especially now, when so many of us when we're sharing our workspace with our restorative space, for everybody who is still working from home or working remotely, then creating those daily breaks are incredibly important to our wellbeing. And so, it has me thinking about what restorative activities can I add to my day? How can I encourage other people to add more restorative activities to their day? So I really appreciated that advice.
And I have noticed that the idea of burnout, but not so much burnout specifically, I've been thinking of it as recovery and balance is a theme for me. And it is something that I am purposely choosing as a theme right now where I want to research and understand more of how we handle these situations and continue to make progress not just for myself but also for my team.
CHRIS: I think finding that right cadence and structure and way to reinvest in yourself and ideally gain more spoons if that is at all possible or at least defend the spoons that you have, those all feel very meaningful.
I do have a question. I'm interested in your thoughts on this. I feel like we hear about burnout a lot in our industry. I get the sense maybe that it is a more common thing. Like, I hear so many developers talking about how their dream is just to give up tech and go get a cabin and just farm in the woods or something like that. And I wonder, is it a more pervasive thing in our industry? So that's one question.
Another is just an observation that we actually do work in a wonderfully...it's an amazing industry where being a developer, there are so many jobs out there. And I don't want to discredit anyone's efforts if they're earlier on and struggling with that. But broadly speaking, it is a developer's market trying to go out there and get jobs and extremely well-compensated, as a general rule. But does that come with this inherent burnout? And if so, which I'm not sure is true, I wonder if maybe we're just more vocal and maybe we actually share more in public. We have more blogs and podcasts and things like that. And that's just a common thing for developers, and so we hear the stories more often, whereas maybe in other industries, it is actually very common, but people are suffering in silence.
But also I do wonder, our industry is still so young. The work that we're doing is changing constantly, and that churn and that working in the unknown maybe there is an inherent nature. So that's a bunch of pontifications off the top of my head. And I have no idea what the answer to any of them is. But I am intrigued because it does feel like the shape of burnout as a concept in the developer world is perhaps a little overrepresented, or maybe it shows up more than I would expect. And, I don't know, is the work that hard? I don't know. But then I hear these stories constantly, and I definitely have felt it myself, so maybe.
STEPH: Yeah, maybe. Yes, I do think the work is that hard for the record. It's challenging work. I enjoy it, but it is challenging work between figuring out the tech but then also everything else that comes with that.
I don't have anything to back this up, but I suspect that a lot of other industries are also experiencing burnout. And I just happen to be more aware of it right now because I'm hearing it more from my friends and the people that I work with. And I suspect that's more directly related to we all just went through 2020, and probably a number of us were trying to forge ahead and get through that time. And so there may be a lot of us that are just now dealing with those consequences of where we just pushed ourselves through a very hard time. And now a lot of that is manifesting and surfacing around really identifying the damage that we may have done to ourselves by just prioritizing work and trying to put our head down and get the work done even though there was so much happening around us.
And I suspect that may be a contributing factor is that now people are really starting to recognize, like, oh, I feel this way. And maybe there's time for me to address it. Or frankly, it may not even be that there's time, but your body is just like, okay, I'm done. I made it through the past year or however many months, and I'm going to start shutting down on you. I've given you all the warning signs, but now we're here. We're at a breaking point. So I don't know about the other industries, but I do know the reason that it's more on my mind is because I'm just hearing it more from people, and they're just expressing it. And so, it has become more of a focal point for me, and I've experienced it myself more recently.
I'm sure I experienced this back early on in my career, but I took a strategy of well, I'm just a junior, and I just have to get through this. And I have to build experience. For the record, that is not a healthy mentality. I'm just being honest about where I was in my life. And so, I didn't really stop to think about it, but perhaps it is becoming more normalized where people are having more open, honest discussions about where they're at. And if other industries aren't talking about this, I would love for them to.
So to round that out a bit, this is something that is just very interesting to me. It's very top of mind. So I suspect I will be sharing a lot more content in future episodes that are just around this. How do we recover? And then how do we balance? How do we work hard without burning out?
CHRIS: Work hard, play hard; those are the two placards that you have. Well, I look forward to continued conversations on all of those topics because they are sort of that's the story that underpins all of the work that we do. So I'm very interested to chat more about that.
STEPH: Thanks. So what's going on in your world? How's your week been?
CHRIS: Oh, my week has been fine. My topics are going to be way more mundane and tech-focused. But let's see, a couple of things, so one is that Stack Overflow has their I think it's Annual Developer Survey. And this year, the results came out, and there was an interesting standout, which was that Svelte was the most beloved framework, which was very exciting to see. Granted, you always have to take these sorts of stats with a grain of salt.
But Svelte was 71% loved and 23% dreaded, which they give it as a ratio of how many people really love this thing versus how many people really hate this thing. And so Svelte, 23% of people who have used it are like, I hate that, but 71% loved, so that's a 48% net approval rating. Versus React which was 69% loved, 31% hated or dreaded as the word would be, so that's a 38% net approval. And then Vue, interestingly, was 64% loved, 36% dreaded for a 28% net approval rating. So, yeah, Svelte was decidedly winning in that.
But again, the big grain of salt there is looking at the usage stats. React has 40% usage. So of all the respondents, 40% of the people responding to the survey were like, yeah, I've done React professionally, which is a wildly high number for a JavaScript framework. Vue was at 19%, so roughly half of React's usage, which I'm actually impressed that Vue is that high. And Svelte came in at 3%, so it's definitely still in the early adopter strong fan phase. So it makes sense that they would have this outsized high rating. I'm actually surprised that Vue wasn't higher than React, given that. Because I feel like more people are cajoled into React versus Vue can be more of a choice. And I would have expected this to shape out a little bit differently, but yeah, that's the story.
STEPH: That's really cool. I liked how you described that as in the very early adopters’ strong fan base stage.
CHRIS: But nonetheless, the people that are using Svelte do seem to really like it; that’s coming through in these numbers. And that definitely is my experience. I love Svelte and would love to continue using it for as long as possible. But really, I want a lot of other people to start using it. I want to really grow the usage base so that there are more libraries, and frameworks, and blog posts, and just mindshare in that space because I really do believe there are some wonderful ideas in Svelte. And it's just so straightforward to implement things that I just want more people hanging out. So that's one quick thing.
Another quick thing is, I've been using a utility lately or a program called CleanShot X, which is a replacement for the built-in screenshot utilities on OSX, and it is just fantastic. So I can capture a screenshot. I can capture a window. You can capture a GIF or a video. And then you can do little trims and annotations. And then it has this really nice feature where after you take a screenshot, it just hovers in the bottom corner of your screen and is easily accessible. So if you take a video, and then you want to upload it to a Trello card, it's just floating there waiting for you. You can actually dismiss it and push it down, but it's still peeking up from the bottom of your screen, and you can pull it back up, and you can have a couple of them. But it just really makes the whole workflow of grabbing screenshots or videos so easy.
And I cared deeply about that because now that I have this tool, I'm all the more inclined to grab a screenshot or a video with just about every piece of work that I do. So it's going into pull requests; it's going into Trello cards. And it's so nice to have a utility that just really makes that as easy as possible.
STEPH: I really liked how you mentioned that you can annotate because I often...I'm laughing as I'm thinking about this. When I am taking a video of something that I'm going to share with someone, I will use my mouse to indicate, oh, this is important. And so I circle around it and do silly things with my mouse to try to indicate but being able to annotate would be so much nicer.
I know there is another tool that you're really excited about that I can't remember off the top of my head right now. Do you know the name of the tool I'm thinking of?
CHRIS: Was it Loom?
STEPH: Yes, Loom, because I also used that for a little while, and I've really enjoyed it. So I'm curious, how does Loom and CleanShot X stack up? Is one replacing the other, or are they complementary tools?
CHRIS: Mostly complimentary. Loom is great because it hosts the videos, and you can also do audio capture, although I wonder if CleanShot has that as well. CleanShot also, I think, has a hosting thing. So I think there's a strong overlap in their functionality, but right now, I'm using both. And definitely for screenshots and things, CleanShot owns that end of it. And I think it's more likely that I could have CleanShot as the entire tool that I'm using. But I'm still using Loom for this is a walkthrough where I'm going to talk to you about a thing. I want to make it available at a URL that everyone can see rather than actually getting a GIF or MOV artifact file on my computer. So ever so slightly different, but I think of them, CleanShot X is probably the ideal one. But yeah, I'm still reaching for both.
So the one other thing I did want to talk about is I have been expanding our use of the dry-monads within the project that I'm working on. And I've done some things. I did some stuff, Steph, and I think it's good.
STEPH: Shtuff with Shteph. [chuckles]
CHRIS: Shtuff with Shteph, yeah. I'm definitely pushing the envelope of how much we're leaning on these concepts within the app, and I continue to question it. I'm really intrigued to see what happens when other folks come into the project, and they're like, "Why can't I just get the value? It should be a string. Why isn't it a string? Why is it a string that I have to do a ceremony and a dance to get at?" And I'm like, "Well, because everything can fail, you know, like life."
But what I have done here so dry-monads is the project that we're using, particularly their result type. So the result represents something that can either succeed or fail. And so we either have a success, which is this wrapper around the value that's successfully executed. So say we make an API call, we get back a response. If we get a 200 or maybe even a 300, then we get the data, and that's a success, or we get a failure and the error message. But fundamentally, we're modeling that in our system in a way that downstream from that, we have to basically determine if it was success or failure. So we're really encoding into the system; listen, pretty much everything can fail, so let's be careful with that. Let's be intentional and purposeful with it.
But there is an interesting thing where these objects have fmap as a method on them. So fmap is a way to transform that wrapped value, but fmap works specifically on the success case. So if you make an API request, you get back the data. Everything's great. You can call fmap, and it will yield into a block that data. You can transform that data in some way, and then it will rewrap it up as a success object. So you can operate on this thing as if it has been successful. But in the case that it's a failure, it will just ignore that transformation because you don't want to transform the failure. It's going to be a totally different shape of data. So you want to separate those. We're getting into functors and monads here. So I'm going to handwave a bunch. But fundamentally, that's the thing that we're going for here.
But we found ourselves really wanting to work with both sides. So we make this API request, and in the case that it succeeds, we actually want to transform and actually slice out a piece of data from the nested object that we get back. So that's one transformation that we want to apply on the success portion of the aisle. But then, we also want to transform the failure message. It turns out this backend is giving us very unfriendly error messages. So we want to take those and transform them into friendlier user-facing error messages.
So it turns out we want to map both sides. And so I went to dry-monads, and I was like, what do you got? I want to know about this in the world. And it turns out they did not have anything. So I started looking into it, and it turns out this is a concept in the world of functors, specifically. Or, more specifically, I reached out to a former colleague, Sid Raval, a former thoughtboter as well. And he likes the functional programming stuff, so I knew he was the right person to ask about this. And he pointed me at bifunctors. So I found myself in a new space and category theory which I never thought I would explore a category theory in this way, but here we were.
So a bifunctor basically is exactly what I was talking about where there are these two branches. In our case, it's either success or failure, but it allows you to operate on both sides, both branches. So the method or the function that gets applied there is bimap. So it's fmap which I don't know why it's f why that's typically what it's called. Success map would be a really great word in this context in my mind. So success map only deals with the success side, but bimap takes two different transformations, one for the successful outcome and one for the failure outcome. And it allows you to very directly talk about what you want to do with that.
To be clear, dry-monads has a function called Either or Either, depending on how you want to pronounce it. And that takes two Lambda proc-type things because it's Ruby, and functions are kind of weird in Ruby. But it yields you either the successful value or the failure value, but then it doesn't rewrap them. So it's meant to be the terminal. You use that in a controller when you're either redirect or render or whatever it is you want to do. What I wanted was something for mapping, so staying in the success object or the failure object but yeah, bimaps. So I introduced my own extra wrapping layer. This is where things go off the rails, I think. We now have our own internal result objects.
I thought about monkey patching for a while. I convinced myself monkey patching was a bad idea. Now that I've implemented as an extra layer of wrapping and I got the wrapping wrong like four times, or I kept recursively wrapping and re-wrapping, and there's a reason people aren't supposed to write these things themselves. But I think monkey patching may have been a better idea here, or maybe I should have never done any of this. We ended up with a stable working implementation and a nice test suite that covers it. But I introduced bimap and failmap as two different methods on our success object. And I did it by doubly wrapping the result objects. So we have our internal result, which wraps the dry-monad result. And I'm worried about that future situation where a junior developer comes on the team and is like, "I don't know what any of this is."
STEPH: I love the weekly progression of I've done some things, and let's talk about it. And then seeing this glimpse into your argument with yourself as to yes, but we need it, and we want it, and it's not something that's defined. So let's go ahead and implement it. You ended on a high there where you talked about the fact that it is nice to work with. It does the thing that you'd like it to do, and it's well tested; I love that part.
I'm deciding which thread to go with because there were a lot of interesting bits in everything that you shared. And I'm intrigued about the monkey patching as to why you think that could have been a better approach. Could you talk more about that one?
CHRIS: Sure. So I ended up having to introduce the secondary object that then wraps the result. And so if you poke at that even a tiny bit, you start to see this like Russian doll nesting of it's our result wrapping a result, wrapping a value. And it's a burrito with three different tortillas wrapped around it. And if you want to add guacamole, you got to unwrap all three burritos. I'm sorry, this is a terrible monad joke here. [laughs]
STEPH: For the record, if Taco Bell is not offering that, they should now, now that you've created that. [laughter]
CHRIS: There is one, but there's usually cheese in between the layers. They're not just extra layers of tortillas, so that's what I've got here. It's way too much tortilla, and that's sad. You don't want that. And it's confusing. You're like, wait, does this one have two or three layers of tortilla? So when I was working on it and when I was implementing our additional wrapping layer, I tricked myself multiple times. And my test suite was telling me that things were working, but I was testing incorrectly. And I was like, oh man; this is very subtle. And even though I'm deeply immersed in the context here, I'm still struggling with this.
So the question is, did I successfully encapsulate all of this? And now anyone downstream just gets to use it,, and everything will be fine. Am I the heroic programmer that made the perfect abstraction that no one's ever going to struggle against, or was that pain that I was feeling representative of the complexity of what I'm trying to do here, and maybe I got it wrong?
And so then the monkey patching side is we've got this one layer of wrapping. What if we just monkey patch the result such that it's got these new methods? I'm not adding an additional layer. I don't need to deal with double mapping through multiple layers, and I just get to deal with the context that I have. So I did an initial spike of an implementation that way, but I talked myself out of it because #monkeypatchingisbad, but I don't know. I don't know where I'm ending here. I am happy with where we're at, but I am aware that I may be sad down the road.
STEPH: I'm just dying over here [laughs] from everything you're saying. I have this image of you staring out the window thinking, am I the hero, or am I the villain? And figuring out who you are in this scenario with this abstraction that you've created.
CHRIS: To be clear, it's raining, and I have a nice rocks glass of scotch in my hand. And I'm just wistfully looking out the window trying to determine what's true. That's pretty accurate, actually. That's pretty much what's going on here.
STEPH: I think we're just going to need updates as it progresses along.
CHRIS: I will say overall this paradigm...so failures can happen at all levels. These command objects, which are the core of where this is coming in in the application, really represent the workflows of the app in a wonderful, testable, straightforward way. So I love that part. And if I have that, it implies that I have to have this other stuff. I don't think I can get away from that.
The other thing is I've always loved Gary Bernhardt's Functional Core, Imperative Shell, which is a conference talk that he gave a while back. I talked to Gary about it actually when he was on the show, and we can link to both that and the conference talk because they are fantastic. And I just love the way he thinks about software. But that was always a little bit abstract for me. Like, what does that actually look like, though, in say, a Rails architecture? And I didn't have a great answer.
And now this thing that I'm doing is the closest I think to that where the innards of the system are almost functional even though it's Ruby. We're leaning into that. And so we have these command objects that take in some data, and then they operate on it, and they yield out these results. Did it go well, or did it not? We've got the railway-oriented stuff, which again I'll link to. I link to now every third episode, apparently, but here we are. And that just models the reality of these programs in a really great way.
And then we've been trying to introduce some, not rules per se, but guidelines as to how we interact with these things. So inside of the core of the application, we're trying to be as functional as possible. We do transformations on these result objects, but that's it. And then it's only really in the controllers or the mailers that we are doing unwrap or deal with the actual nested value, but everything else is working on conceptual values or whatever it is…these result objects. And that's actually been really nice, and it's allowed us to have really nice error handling within the app. The logging is very straightforward. A lot of apps that I've worked on in the past, I've just silently thrown away many error cases or edge cases. And this is a really great way to sequence the work that needs to be done but never throw away data that you would want. And so far, I'm finding it to be really great. And I'm seeing very obvious ways to hook into it like, oh, this is where we need to find the user-facing error message versus this is where we figure out what we want to log. And so, in some ways, it's great, but I am still open to the idea that this was a terrible idea. I always remain open to that idea to be clear. [chuckles]
STEPH: I love how that's the feedback that you're always open to it. You're always trying something new, and then you're constantly going back to revisit; was this a good idea or a bad idea?
To go back just a little bit, I do absolutely love the priority and focus that you're giving to the failure state because I feel like that is an area that we, as developers we're very skittish of that failure state. And I realize I'm projecting here. So if you're listening, feel free to take that however you like; maybe it doesn't apply to you, maybe it does. But the failure state is like you said, it's life, it's important, and it's something that is going to happen. And it is something that we should make accommodations for.
And I find that we're often very hand-wavy with a failure state. So I love, love how much you always prioritize the failure state and make that something that people can work with and understand. Versus then when something goes wrong, then that's when we have to start to understand the failure state. I recognize there's a balance there because you're not going to know the failure state until you encounter it, but there are ways that we can still optimize to have observability into that failure state for when we do encounter that failure.
CHRIS: I've definitely seen that as an evolution in my own thinking, how much am I focused on how easily can I do the core thing, the happy path versus how robustly can I do all of the variations of what this app needs to do? What if the network's down? What do we do there? I do occasionally worry that I've overcorrected on that. And it's like, you know what? This thing that I'm worried about that I'm protecting against in the application is a 0.01% edge case. It's going to affect almost no users, and we're both putting time into trying to avoid it. But also, there's code complexity that comes from trying to handle all the different variants. And so there's definitely an optimization, and I feel like, at different points in my life, I've been undercorrected or overcorrected on that.
But I think if I were to describe the arc of my career, it is desperately searching for that optimal path and trying to find exactly the right amount of error handling to apply, and then yeah, then I'll be happy, then it'll be great. But it is like when I look at DHH's classic 15-minute I'm making a blog, look how much I'm not doing, I'm like, sure, sure, sure. Show me that in three years, though. What does the blog look like? How easily can I add a new feature? What happens when there's a bug in production, and a user reports it? Can I chase it down? Can I figure it? Can I fix it? These are the questions that I care about now, almost to the exclusion of what's the first run experience like? I almost don't care about that at this point. Because I spend my time…six months and on that's where the hard work is. And so the first couple of months where you're figuring things out, that's not the hard work of this thing. And so, I'm very strongly focused on those later periods of time. But again, I'm open to the idea that maybe I am overcorrected there.
STEPH: I think it does highlight more of a shift in our career. We're still building, but we have experienced the maintenance side as well, and we felt that pain. And so that has led to perhaps overcorrecting, or maybe it's the correct amount of correction.
But I do like how you highlighted there is always a cost to each side and those are usually the questions that I'm asking myself when I'm thinking about the failure mode and how much I want to optimize for the failure mode is how much does it cost when this fails? Who's it going to impact? And how much does it cost for me to make this more observable or to address this failure state? And then I try to find the balance between those two. Because you're right, it's not free to address that failure state. And so I may not want to fully optimize to handle that if it's going to be a very small percentage of users that actually are impacted by this failure state, or it seems very rare this is going to happen. But then still finding ways to know that if it does fail, then I can say, "Okay, I'll come back, and now it's worth the investment to improve this."
CHRIS: When you said earlier that this is really hard work that we do, I don't know that I believed you. What you just described sounds super easy. You just handle all the stuff, and you dynamically optimize for the needs at the point in time. And that seems easy. [laughs]
STEPH: Super easy, yeah. [laughs] Way to bring it back. Well, speaking about observability and failure states, that does lead nicely into a bug that I was working on this past week where there was a particular page that was loading very slowly. And it was something that we'd heard from users that then they let us know that this page was either taking a very long time to load or, frankly, it was just crashing. And then they were never getting to that page. So I happened to be the one that then picked up that ticket. And I went to reproduce the issue, and sure enough, when I clicked on this particular link and then started counting, it took about 14 seconds for that page to load, which is a very long time. And then also sometimes it was just crashing.
So the first place that I went was to our error tracking. So I went to New Relic to then look to see okay; maybe there's a slow query. There's something here that's creating this performance issue, but I couldn't find anything. And New Relic does a great job of breaking down all the different response times so I can see how long Postgres is taking, Redis, and Ruby. All of those looked very normal. I couldn't find anything that seemed alarming that was indicating that the page was struggling to load even though I could reproduce the problem. Because I was clicking on it several times thinking, okay, well, if I just do this a couple of times, New Relic's going to notice, and then I'll get to see something, a little breadcrumb that's going to lead me in the right direction.
And while I was waiting for New Relic to surface something helpful to me, I mentioned to another developer the issue that I was triaging. And they said, "Yeah, that page has been getting progressively slower, and we don't know why." And I thought, ooh, okay, I'm intrigued even more now as this is something that has been escalating over time, and now we've hit this threshold that we're working on it.
And I discovered that in New Relic, I can look specifically at Postgres, Redis, Ruby, all those different response times. But there's a browser monitoring tool that I had not used before. And it showed a lot of helpful information around first paint, First Contentful Paint, window load, all of those areas. So I started diving in and found session tracing, and it was there that then I saw New Relic was telling me, "Hey, you have a page that's taking about 14 to 15 seconds to load." And I thought, okay, I feel validated now that at least New Relic is recognizing this issue. I have seen this issue, but I still didn't know why it's occurring.
So the next tool that I used that I don't know if I've used before or it's just been a very long time; it felt fresh in the moment, but it's the Chrome DevTools, the performance tool. And so you can open that up in your inspector, and then you can go to the page that you want to track the performance. And then you can essentially say, "Hey, go ahead and start profiling and reload this page." And it has so many stats when it finally does load. It has CPU flames charts, which essentially it visualizes a collection of all the stack traces. It has a film strip, so you can actually see the rendering progress of your website along different time points. So if you wanted to go back to a specific time, you can see what did the webpage look like at this point? And then if you go a little further, okay, how much was loaded at this point? So there's a lot of interesting and a little overwhelming information that's there.
But the thing that did catch my attention is there's a chart. I don't actually know what this chart is called. It's not a pie chart because there's no center to it. So it looks like a donut chart, and it's broken down. And it shows you the loading times, scripting, rendering, painting, all of those different values. And the rendering time was taking 35 seconds. And I was like, ooh, okay, that is meaningful right there. So then further investigation, now that I knew what I was looking for, I wasn't looking for something more on the back end. I was looking for something more on the front end. And I didn't think it was necessarily JavaScript because we also have JavaScript on this page. So at least this was helping me get a little bit closer before then I went into the codebase to start seeing what's happening.
So once I knew it was a rendering issue, I went to look specifically at that view, and we have a form on that page that was generating an empty HTML select option for every record that's in the system. So let's say that you're ordering from a restaurant. On this page, there was a form where it had a list of all the restaurants, and, in our particular case, we had about 17,000 restaurants. So there were 17,000 empty HTML selection options, which could have some significant impact on the DOM and page load time. And that was the piece that was really leading to the performance, is the fact that we were rendering that empty select option.
So from there, it was then just triaging okay; we don't really need to render all of these restaurants. There are ways we can scope this down. And that way, we're only showing a little bit at a time versus creating all of these empty options. I should clarify they're empty because part of this form is you select from the first dropdown, and then it populates the other one, and it gives you more information. But the way that this form was implemented, it was actually trying to show all of them at once. But it didn't actually have the data yet, but it was doing like a restaurant.all type of count. And so then that's how we were getting that many empty options.
So it was a very interesting journey. It was very helpful to learn that New Relic has this browser monitoring tool. And I really appreciated their performance tool. And circling back to Chrome, Safari may have something similar. But I found Chrome's performance tool very helpful because then it helped me realize that it was the rendering. And so then I could really focus on the markup and the view versus knowing it wasn't more in the database layer.
CHRIS: I really love the description, almost like a mystery novel of these bugs when we encounter them. Because if you just get to the end and you're like, oh, I was rendering a select, and it had all of this, that loses so much of this story because again, the coding is not the hard part of the work that we do; it's the figuring out what needs to be done. And in this case, that journey that you went on to find the bug. I really like the point where you said, "And someone mentioned this page has just been getting progressively slower over time." I was like, ooh, that's interesting. Now we got a clue. Now we've got a lead, and we'll chase it down, and then finding the browser tools and all of that.
And also, as an aside, browsers are just such an immensely impressive piece of technology, everything that they do. And then you add the DevTools on top of them and magical stuff going on there. But yeah, also probably don't render 17,000 empty selects. [laughs] That seems like it will get you in trouble pretty quickly. But also very easy to get to and especially if there is this incremental, slow creep over time where it's like, oh, that page seems like it's a little slower. It's a little slower still, and it just keeps creeping up over time. But yes, I appreciate you taking us on that journey with you.
STEPH: Yeah, it was a fun discovery. And it made me realize that while we have alerting set up for some of our other queries, we don't have anything set up for the browser time. So that would be a good optimization on our side is to start alerting us before a page gets to the point that it's taking that long to load to notify us sooner. So we don't have to wait for a user to reach out to us, but we can triage sooner.
CHRIS: I also do love the idea of extending the metrics that we hold ourselves accountable to all the way through to the user, and so the First Contentful Paint and all of that. The one that I really love recently that has captured an idea that I struggled to put words to is the Cumulative Layout Shift. Are you familiar with this piece?
STEPH: Uh-uh.
CHRIS: So there's like, how quickly does the page render? That's the thing that we want to know. But a lot of applications these days, particularly single-page apps, render pretty quickly, but they render what ends up being a skeleton or a shell of the page. And then behind the scenes, there are like ten different AJAX requests happening. And as the data comes in, suddenly, a part of the screen will render. And they'll render a list of items that they just got back from the back end, but they're still waiting for the information to populate the header. And so if you look at that page, it's constantly shifting as it's loading and just feels, I don't know, flimsy in my mind. But I didn't have a good word, or I didn't have a metric or a number to attach to that. And then I learned about Cumulative Layout Shift, and I was like, oh, that's the one. Now you've mapped the thing that I was feeling. And I like when that happens.
STEPH: Is that the difference between the first paint and First Contentful paint? Is that similar?
CHRIS: I think it's more than that because there are not just two discrete events in this. It can be multiple. And so it's like, how many different times did the thing that's rendered on the screen move around? And so if images are loading, but you didn't have a proper image height and width set, that's another way that this can happen. Then initially, the browser is not going to reserve any space for that because it's like, I don't know how big this is. And then, when the image shows up, it now knows the intrinsic height and width of the image. So suddenly, your page is going to jump from that. You can get ahead of that by putting the height and width on your image, and that's great to do. And frameworks like Next.js have done some really amazing work of making that a build time step as opposed to something you have to do manually.
But then also, more generally, how do we handle this? React is doing some interesting work with Suspense, where you can aggregate together multiple different loading states into one collective thing. It's almost like promise.all, but for your page. I haven't followed that too closely, but I know that that's framework-level work that's happening over there. GraphQL does a really great job of allowing you to group queries together. So there's a solution on that side. But broadly, if you just render some HTML on the server and you send it to the front end, then you don't have this problem because you just have one ball of HTML. The browser is pretty good at rendering that in one pass versus if you have single-page applications that are making a handful of AJAX requests that will resolve in their own timelines and eventually paint to the screen. You get this different shape. And then the worst case of it in my mind is you render half the page. And then suddenly, one of the requests realizes the JWT has expired, and suddenly, you get thrashed over to the login page. Please don't give me that experience, developers, please. Please do something else that isn't that. That makes me sad in my heart.
STEPH: Prioritize the failure state. That's what I'm hearing.
CHRIS: Callbacks.
STEPH: Well, on that wonderful circular reference, shall we wrap up?
CHRIS: Wait, I thought circular references were bad...Never mind. Let's wrap up. The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes,, as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us @bikeshed, or reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeeeee.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Support The Bike Shed

Aug 11, 2021 • 35min
304: MEGA Crossover Episode (The Bike Shed x Rails with Jason x Remote Ruby x Ruby on Rails Podcast)
This is the sweeps week episode, the epic crossover episode, the mega episode! We have a very special episode as Chris, and Steph teamed up with the hosts of three other podcasts to bring you one giant, mega Ruby episode!
In this episode, you'll hear from the hosts of Remote Ruby, Rails with Jason, and Brittany Martin, the host of the Ruby on Rails podcast. They cover the origins of their shows, their experiences as hosts, and why podcasting is so important in keeping the Ruby community thriving.
Remote Ruby
Rails with Jason
Ruby on Rails podcast
*Transcript: *
STEPH: Hello and welcome to another episode of the Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. This week we have a very special episode as Chris, and I teamed up with the hosts of three other podcasts to bring you one giant, mega Ruby episode! In this episode, you'll hear from the hosts of Remote Ruby, Rails with Jason, and Brittany Martin, the host of the Ruby on Rails podcast. This episode was so much fun to record, and we have Brittany Martin to thank as she organized and moderated this special event. So without further ado, here is the mega Ruby episode.
BRITTANY: Welcome, everyone. We have a whopping seven podcast hosts recording today. So, listeners, you are in for a treat. This is the sweeps week episode, the epic crossover episode, the mega episode. We're going to need our editor to insert some epic sound effects right here.
Announcer: The mega episode.
BRITTANY: So let's go ahead and introduce the crew today. I am Brittany Martin from the Ruby on Rails Podcast.
CHRIS OLIVER: I'm Chris Oliver from Remote Ruby.
JASON CHARNES: I am Jason Charnes, also from Remote Ruby.
ANDREW: I am Andrew Mason, also from Remote Ruby.
STEPH: And I'm Stephanie Viccari from The Bike Shed.
CHRIS TOOMEY: I'm Chris Toomey from The Bike Shed.
JASON SWETT: And I'm Jason Swett from Rails with Jason
BRITTANY: Today, we're going to cover the origins of our shows, our experiences as hosts, and why podcasting is so important in keeping the Ruby community thriving. Now I know personally, I really enjoy the origin story behind Remote Ruby. So, Chris Oliver, could you kick us off with that?
CHRIS OLIVER: Yeah, we can go back maybe to the first time that Jason and I met, which was Jason emailed me out of the blue and was like, "Hey, are you going to be at RailsConf?" And I wasn't planning on it, but it was over in Kansas City, like four hours away from me. I was like, "No, I'm not going, but I'll meet you." So we went and drove over there and met and have been friends ever since. And Jason had the idea of doing an online meetup. And I'll let him explain where that started and turned into the Remote Ruby Podcast.
JASON CHARNES: I thought it would be a good idea. There weren't any online meetups. This was pre even the idea of shutting down the world for a pandemic. And maybe I was just too soon because I got Chris to speak at the first one, and we had 40, 50 people. I spoke at the next one, and there were 20. And by the third one, there were five of us. So it wasn't really a super sustainable thing for me to do. So Chris and I got together and said, "What if we tried podcasting?" Chris, you hadn't really done your own podcast at that point, had you?
CHRIS OLIVER: No, I don't think so. And you and I were just having calls every week or whatever just to hang out and chat. And we were like, why don't we just record that and publish that as a podcast? And here we are.
JASON CHARNES: Yeah. So we've been doing that. I think we started in 2018, so yeah, three years in June, and somehow people still keep listening to us talk but probably because we brought along our friend, Andrew.
ANDREW: Wow. Okay. No, that's not true. But yes, I was a guest on Remote Ruby before I joined as a host. And not to get into the details, but I was on another podcast, and something went down, and I no longer was on that podcast anymore. And Chris and Jason were like, "Do you want to come hang out with us?" And I was like, [chuckles] "Absolutely." So I started doing that, and at the same time, I also started The Ruby Blend with Nate Hopkins and Ron Cooke. And so we were doing that for a while until that had to tragically shut down. But I'm still here with Jason and Chris. I guess I should also mention that Jason Swett gave me my start in podcasting a month or two after I started full-time as a Rails developer on a now archived show called The Ruby Testing Podcast.
BRITTANY: Which is the perfect segue because Jason Swett was also my first opportunity to guest on a podcast. So I was already hosting, but I hadn't guested, which is kind of the opposite order. So, Jason, do you want to tell the origin of where Rails with Jason came from?
JASON SWETT: Sure. I'd been involved with podcasting since around 2016. I somehow ended up on the Ruby Rogues Podcast and was on there for maybe a year or so. And then, somehow, I got the idea that I could start my own podcast. And as an experiment, I started a podcast that I called The Ruby Testing Podcast, which I figured was sufficiently narrow that I could get some traction. And to my surprise, guests actually said yes to coming on the show. And also, to my surprise, people actually listened to the podcast. That gave me some confidence. So maybe a year later, I broadened, and I changed from The Ruby Testing Podcast to just Rails with Jason. And I have been doing that for something like two years.
BRITTANY: That's fantastic. I want to move to probably our most experienced podcast veteran, and that would be Chris Toomey. When I was learning how to code, I was listening to Giant Robots and then was excited for the transition that The Bike Shed took. Chris, I would love to hear the story of what it was like taking over a really popular podcast and really maintaining the drive behind it.
CHRIS TOOMEY: So, as you mentioned, I had done a little bit of podcasting. It was about a six-month run where I was a co-host on Giant Robots, which was the original podcast of thoughtbot. And that was more in the business and sort of how do we build a software company? So at that point, I was running Upcase, which was the subscription learning platform that thoughtbot had. So I was talking about the inner details of the business, and the marketing tests, and A/B tests and things like that that I was doing. And every week, I was sharing my MRR rather transparently in that thoughtbot way that we do. I did that for, like I said, about six months and then took a while off.
And in the background, thoughtbot had started up a new podcast called The Bike Shed, and that started October 31st of 2014. So The Bike Shed has been going for a long time now, and that was hosted by Derek Pryor and Sage Griffin. And they ran that for a number of years. I think it was about four years that the two of them worked collectively on that. But at some point, they both moved on from thoughtbot, and there was an opportunity for new hosts to step in. So I took over in August of 2018. So I've been doing this now for about three years.
And so, for that first year, I took the opportunity to do a tour around thoughtbot and talk with many different individuals from the company and a handful of people external to thoughtbot. But I knew that there were so many great voices and ideas and points of view within thoughtbot that I really wanted to spend some time getting to know more of them personally and then sharing that as much as I could with the existing audience that The Bike Shed had. But secretly, all along, I was looking for a person to hang out with all the more so, and Steph was the person that was a perfect choice for that. And so, for the past two years, Steph and I have been chatting. And I will send it over to Steph to share a little bit of her point of view on that transition. But from my point of view, it's been fantastic.
STEPH: I still remember exactly when we had the conversation. You were running The Bike Shed and doing an incredible job of just having weekly guests. And then you'd reached out to me and said, "Hey, would you be interested in doing an episode?" And I thought, "No, absolutely not. I can't podcast. I can't begin to do this." So you continued to convince me. And finally, you said something that resonated where you were like, "Well, we can just show up and record, and we don't have to publish. We can just see how it goes." I was like, that's a perfect safety net. I'm into that. So I showed up, and I think the first episode that you and I recorded ended up being titled What I Believe About Software. And it was a lot of fun. I realized I have a lot of things to say. And after that, I think it was another month or so. You continued interviewing more guests, but then you reached out to me and asked me if I wanted to be a co-host. And at that point, I was super jazzed about it, and it's been wonderful. It's been a roller coaster. I have learned a ton.
BRITTANY: I'm kind of seeing a pattern here where over the last three years, it seems like Remote Ruby came into place, Bike Shed transitioned. That's when I took over as host of the 5by5 Ruby on Rails Podcast. We're going to call it the golden era of the Ruby Podcasts. But for me, I probably have the longest-running podcast. It was started back in 2009 on the 5by5 Network, but it's gone through many different hosts. And so, I took over roughly about three and a half years ago as the main host from Kyle Daigle. And then, just a couple of weeks ago, as I announced on my podcast, we took the podcast independent. We are now just The Ruby on Rails Podcast. And I'm starting to change the model where I'm bringing in more co-hosts. So that way, I can get those regular updates that I really appreciate on all these podcasts we have featured on the show today.
I am curious. I want to talk about how we put together the episodes and plan out how everything's going to go down. I know for me, I'm currently a mix of interviews and co-host episodes. So I'd love to hear from Andrew. How do you plan out what Remote Ruby is going to be week to week?
ANDREW: This is an easy question because we don't at all. We don't plan. We do have some guests that come on, and sometimes, they may get their Zoom link the day of; who’s to say? But we really don't have a plan. We don't talk about what we're going to talk about beforehand. We all just kind of show up, and I think we have that kind of relationship and flow where it always just works.
JASON CHARNES: And I think part of that came from actually how Chris and I started the show because we were trying to make it as low stress as possible because we knew if we put a lot of pressure on it, we would stop doing it. Our first episodes were YouTube live links that we just shared out. And then in our next episodes, we were like, oh, we should start using some software to do this. And then eventually, we got an editor, but that same core of let's just keep it fun for better or for worse, I think, also affects our planning.
BRITTANY: I've been lucky in the sense that I have guests sit on all three of the episodes. And I do want to give a compliment to The Bike Shed because it is very well run and very well planned. So I want to kick it over to Steph as to how putting together a Bike Shed episode looks.
STEPH: Oh, thank you. That's wonderful to hear, by the way. That's wonderful feedback. So we predominantly use Trello to organize our thoughts. So we will have...and as we're capturing community questions that are coming in, so we will capture those on the board. And then, we will have a ticket that represents a particular episode. Usually, on the day of, we'll share some thoughts about, hey, these are the broad topics I'm interested in. And there's usually some hot takes in there, which is fun because the other person doesn't know exactly what's coming, and we can have real honest conversations on the mic. And then, every so often, we'll grab a beer, and we'll go through that list. And we'll chat through what sparks joy. What do we want to talk about? What would we like to respond to? And that's pretty much how we organize everything that we discuss. Chris, is there anything I've left out that you want to add?
CHRIS TOOMEY: I think that mostly covers it. We do occasionally have interviews just as a way to keep some variety and different things going on, but primarily it's the sort of what's new in your world? And I find that those episodes are the ones that I think are the most fun to record for Steph and I when it really feels like a sincere conversation. I've recently taken to a segment I call good idea, terrible idea where I'm like, "I'm actually considering this, Steph. What do you think?" And live on-air, I'm getting Steph's feedback, and generally, we're very aligned. But every once in a while, she's like, "That's a terrible idea. Don't do that." And I love those, and I love being able to share that because I think it's really easy to talk about, you know, here's a list of things that are true about software, but really, everything depends. And it's all the nuance. And so, being able to share some of our more pointed experiences and then share the conversation that we have over those is hopefully very valuable to the audience but definitely the thing that I enjoy the most.
BRITTANY: So kicking it over to Jason Swett, I really enjoy the interviews that you do. I'm curious, how do you select guests?
JASON SWETT: Well, thanks. Selecting guests is tough. I had Peter Cooper on the other day, and I was telling him that I feel like every guest that I get on the show is the last guest I'm ever going to be able to get on the show. But somehow, I keep finding more and more guests. Early on, it was relatively easy because I would just find book authors, or if somebody else does podcasting, then it's fairly obvious okay, you're the kind of person who does podcasts, so I'll invite you.
But it's a little bit tough because I don't want to invite people who aren't into podcasting and would be really thrown, although sometimes that happens. But let's see, sometimes I send an email out to my email list, and I'm like, "Hey, I'm looking for guests for my show." Sometimes I just tweet that I'm looking for guests. And sometimes I get some really interesting guests from surprising places. But at least in the start, it was looking for those authors and podcasters and the people who are known in the Ruby community.
BRITTANY: I know for me, I strive to have at least 50% of my interviews be with people who've never been on a podcast before. And so that usually involves the top of the episode they're dry heaving into a paper bag. And I'm explaining to them, don't worry, about halfway through the episode, you're not going to remember that you're recording anymore. It'll be fine. And you know what? It's always fine. And so, I do love hearing from a wide variety from the Ruby community just because it really proves just how big it is. So I'm curious, could you host the podcast that you are currently hosting now if you weren't actively working in Ruby?
ANDREW: I could because Chris is the one that has all the clout. I could sit back and make dumb jokes and memes during it. And as long as Chris is there, I think we'll be good.
JASON SWETT: Yeah, I think I could because a good majority of what we talk about on Rails with Jason actually has nothing to do with Rails, so that would probably actually work out.
STEPH: I think yes is the answer. While a lot of our conversations do focus around Ruby and Rails, we often use a lot of other languages and tools, and those are a lot of fun to talk about. So I think I would just talk about whatever new tool or language that I'm using. So I think yes, it would just take a slightly different form but would still be at its core the same where we're still talking about our daily experiments and adventures in web development.
BRITTANY: I agree with you, Steph. I will say that it seems like Chris Oliver and Chris Toomey have an endless well of things to talk about just based on what they do day-to-day.
CHRIS TOOMEY: I try and go on adventures and then share as much as I can. But to resonate with what Steph was saying there, we try to make the show more generally about software, and it happens to be that it's grounded in Ruby on Rails because the vast majority of the work that we do is in that. And I just recently started a new project. I was given the choice of I could pick any technology I want, and it remains the technology that makes sense to me to be the foundation of an application that I want to maintain for years and years and years. So, on the one hand, I think I could definitely talk about software more generally. I think I'm doing that most of the time. But at the other end of the spectrum, but it's always going to be based on Ruby because I haven't found a thing elsewhere in the world that is better than that.
CHRIS OLIVER: I completely agree with that. I probably have a little bit of a unique thing doing a screencast every week. A lot of those are based on I'm building some project, and I need to build some random feature like Stripe Checkout. And that's a good one to do a screencast on and implement in the project. And then, we can also talk about the decisions along the way on the podcast, which is kind of nice.
BRITTANY: Yeah, it feels like every week, Chris Oliver is like, yeah, I've created a new open-source library, and I'm fabulous. [laughs] Let me listen to this.
CHRIS OLIVER: Too many of them. I'm currently rewriting a lot of the Pay gem. And it's just one of those things where you make a bunch of decisions. And then, if you make an open-source project, people use it in all these different ways that you didn't intend yourself, and so you want to support that. But then you need to rearchitect things in it. It is a lot of learning as you go, which is always a lot of fun. So those I think are really good topics to talk about when you're building something like that.
I'm always amazed by how does the Rails core team make these decisions on what should be in the framework and what shouldn't? And what do they want to maintain, and how do they keep it flexible but yet have some sort of rule with how they allow things to be implemented and whatever? It is a very hard job to have. So I get my little taste of that with some open source but not on their level.
BRITTANY: I always thought that you had a good contrast to Jason Charnes because Jason works at Podia. And while you do get to work on a lot of really cool technologies, I feel like the stakes are much higher. So you can't just rip out StimulusReflex and put in something else just because it sounds cool that week. And I love how you talk through the pluses and minuses to making a big change within the Podia codebase.
JASON CHARNES: Yeah. I haven't really thought about that contrast before, but it's helpful for me even just to talk it out with two other people once a week, and luckily, pretty cool about me just coming on and talking about hey, these are the steps we took to get here. Yeah, it's a cool dynamic.
BRITTANY: Steph, have you ever had a client from thoughtbot say, "Hey, were you talking about me?" whenever you're talking about your current client?
STEPH: That is one of my fears at times that it will happen [chuckles] although we stay very positive on the show. That's something that's very important to us. There's enough negativity in the world. So we really want to focus on our positive experiences through the week. But there have been times where I'm speaking about some of the challenges or things that we are running into that yes, the engineering team is listening to the podcast, and they're like, "Oh, I heard you talk about this feature that we're working on or this particular challenge." And that's really cool because they get that behind-the-scenes peek to see how Chris and I are chatting about that. But yet they know enough, and they know which project that I'm on that they recognize exactly the technology and the feature that I'm trying to describe. So that has certainly happened, and it can be a lot of fun when it does.
BRITTANY: Andrew, how have things changed for you now that you're not working at CodeFund, which was very much like an open-source thing? People could see what you were actively working on. And now you're working for a company where it's closed source. And so, you might not be able to reveal as much as what you're working on at any given point.
ANDREW: It's different, but I don't think it's been an issue per se. I'm not like, oh crap, I let that slip, and I didn't mean to. That's not really an issue. I really cherish the time I had at CodeFund. When I think back on my experiences, that was my favorite time just because I was able to do that thing that a lot of people really want to do. I was working as an open-source developer. We were spiking StimulusReflex; that’s when we were building up StimulusReflex and trying to build up the community. I joined Ruby. We started the Ruby Blend, and things were going good before a dramatic turn. But in terms of the closed and open source, it hasn't been that big of a shift just because instead of talking about what I'm doing at work, like, I still talk about it, but I speak about it in more general terms. But I also then kind of freed up to talk a lot more about the dumb crap I do on the nights and weekends.
BRITTANY: So the majority of our podcasts either have the word Ruby or Rails in it, but I think we've all agreed that a lot of the topics that we're talking about are not specific to that community. But in a lot of ways, I feel that having podcasts in our community is how we're going to keep our community thriving. So I'm curious if anyone has any thoughts around...is there a way to market our podcasts so that other developers will listen to it? I get really excited when I get listener feedback saying, "Hey, I used to do Rails maybe ten years ago, but I've been listening to your podcast, and I really enjoy such and such episode." How can we make our podcasts accessible to the general software community as opposed to just Ruby?
CHRIS TOOMEY: One thing that stands out to me about Ruby and Rails is because it's full-stack, because of its foundations, it tends to be holistically about web development. And so, whereas I look at React projects or other JavaScript or different things that are going on, I see a more narrow focus in those frameworks. And with Ruby and Rails, what I love about it is that it's really about building software. It's about building products that are valuable, that deliver value to end-users. And so that being the core of it, that's the story that constantly brings me back to Ruby and Rails. And it's the story that I want to keep telling as much as possible. And it's the thing that keeps me engaged with this community. And so, I think podcasts are a great way to continue to literally tell those sorts of stories and really celebrate that aspect of Ruby and Rails and why it remains such a productive way to build software.
CHRIS OLIVER: I think related to that, one of the things that we should talk about more is the draw of Rails was look at what you can do with one person or two people. And I feel like we went down the JavaScript route, and now you need two teams of people, and you end up building bigger stuff. And Hotwire has kind of been like, hey, here's a reminder of what you can do with a very small team. And I think that resonates a lot with a lot of people building startups and trying to build side projects and everything. And that's one that is Rails-related. But there's a ton of people building Hotwire stuff in Laravel too. And they're all very similar. So I think at a certain point, yeah, we're talking about maybe Rails specifically, but you can apply all those things to different frameworks and just different tools.
STEPH: I'd like to add on and extend that because I wholeheartedly agree with what both Chris Toomey and Chris Oliver just said. And in addition, a lot of the conversations that we have on The Bike Shed are focused on Ruby and Rails, but then we will extract that particular concept to the point that it really doesn't matter which language that you're using or which framework that you're using. We're talking more about the high level. What's your process? What are you thinking as you're going through and implementing this? And based on more of our recent conversations, you'd think we're more of a Postgres podcast, how much we hype up Postgres, and the things that we can do at the database layer. So I think there are a lot of ways that we can start with a foundation of this is how we're doing it with Ruby and Rails, but then talk about it at a higher level where then it's really applicable for everybody.
JASON CHARNES: If talking about one technology defined your podcast, we might as well be a Laravel podcast because we talk about that framework more than we do Rails sometimes. [chuckles]
BRITTANY: So that begs the question: is there room for more Ruby and Rails podcasts outside of who's currently on this call?
JASON SWETT: I think so. And I mentioned that Peter Cooper was on our podcast a little bit ago. That's something he and I actually talked about in that episode. And I shared the anecdote about how in the new America's founding, Ben Franklin's brother or something like that wanted to start a newspaper. And somebody told him what a dumb idea that was because America already had a newspaper. And people might say, oh, there are already however many Rails podcasts. There are a small handful. But I think there could be ten more Rails podcasts or even more than that potentially because I think people have an appetite for help, and camaraderie, and stuff like that. And I don't think we've nearly bottomed out in terms of satisfying people's appetite for that stuff.
JASON CHARNES: Yeah, I agree with that because a lot of times, when I listen to podcasts, the more you get to know someone, that connection becomes what it's about for me. So, yeah, there's plenty of room. I mean, brand it as Ruby and tell me about your life as a developer I'll listen.
CHRIS TOOMEY: I'll also throw it out there that the way you framed the question is like, is there room for it? But one of the wonderful things about podcasting as a medium is it is distributed. It's not centralized. You can start up a podcast any day. And I will say, as someone who inherited a popular podcast or a sufficiently popular podcast and just got to run with that, it has been such a wonderful way to get my voice out there and provide opportunities that I want that for everyone. I want everyone to have this ability to speak about the way they think about software and then find like-minded people and be able to build even many communities within the larger community of Ruby on Rails. So beyond the question of, Is there room?” which I definitely think there is, I so wholeheartedly support anyone pursuing this for their own reason.
ANDREW: Yeah, I think to bring it all the way back, one thing that Chris, Jason, and I care a lot about is Ruby as a community. The community aspects of Ruby are very important to us. And we're actively trying to build that up and bring in new people and bringing people onto their first podcast. We say it all the time, like, hey, if you want to come on the show, let us know. We've had a few people even, you know, recognition in jobs from that. So to us, that is the payoff of doing the show. Maybe our show is the first time someone learns about Rails. And that to me is the possibility in the future. It's like, how can we market our shows that markets Ruby as well so that this meme of Ruby being dead finally goes away because it's not. I think it's growing. And I think the more and more we push as people who are public figures in this space that we want to bring more people on, that this is a space for everyone, I think that's just kind of the ethos that all of us have, and I think that's great.
BRITTANY: So I'm curious, on a lighter note, has anyone had the funny experience of realizing that you're not just podcasting into the ether and that what you're saying and what you're doing matters? For me, I have definitely been at conferences where people will run up and hug me just because they heard my voice, and they are like, "I didn't know what you looked like, but I have your voice memorized," and it just blew my mind. And I was like, "Thank you so much for being such a loyal listener." And it just proves that people are out there listening.
ANDREW: I tend to talk very openly about mental health. And I very often fail in public and talk about it. And I've had a lot of people message me and email me over the past three or four years and be like, "Hey, thank you for talking about this thing that's not actually about Ruby. It's not actually about coding, but it's just about being a developer." And those are the emails that make me feel the best. Like, someone who's out there like, "Yeah, I also feel like this. Thank you for speaking about it."
JASON SWETT: I had a surreal experience. I went to India in 2019 through RubyConf India. And this guy wanted to take a selfie with me because apparently, he considered me famous. So that was cool and pretty surprising because I definitely didn't consider myself famous.
STEPH: My favorite has been when we receive listener questions because it lets us know that people are listening and engaged in the conversation, and I essentially feel like they're part of the conversation. They will write in to us and share anecdotes, or they'll share answers to some of the questions that Chris and I will pose on the show. But every now and then, we will also get an email from someone that says, "Hey, just thanks for doing the show. I listen, and it's great," and that's all they share. And that, to me, is just the most wonderful thing that I could receive.
BRITTANY: Some of my favorite episodes from all of your shows is when we get an inside peek into what people are doing, like Andrew moving. Jason Charnes, you putting together a conference was actually some of my favorite episodes of yours, which was really early on, which proves that I'm a Remote Ruby OG. But I loved hearing the inside track as to what organizing a conference is because I think we need to get more content out there about how difficult but how rewarding it is.
JASON CHARNES: Yeah, I hadn't really thought about...that was around those times we hadn't done... It feels like it's been ages since we did Southeast Ruby, but Chris and I actually podcasted from the last Southeast Ruby we did. We just met in a room and recorded. But when I started that conference, I didn't have a lot to go on. So I'm more than glad to share because the reason I started is there were no Ruby conferences around me, plus I'm an open book. So for better or for worse, maybe that's good podcast material.
JASON SWETT: Side note, it's one of the most enjoyable conferences I've ever been to.
JASON CHARNES: Thank you.
BRITTANY: I completely agree. I miss the regional conferences.
JASON CHARNES: We lucked out because we were already planning on skipping 2020 because we were tired, and then COVID hit. I just sat on the couch one night and looked at Shannon (she helps me put on the conference), and I was like, "Wow, that would have been terrible. That would have come out of our own bank account, all that loss if we would have already booked somewhere." So phew, when it chills out, we'll try it again.
BRITTANY: So let's talk about legacies. I know that some of us have taken over from popular podcasts. Some of us have grown podcasts from the very beginning. So I'm curious, do you ever put any thought into the legacy of your podcast, whether or not you're going to stay with it to the end? Would you eventually pass it off? Do you think about whether or not it's your responsibility to the community to make sure that it keeps going?
JASON SWETT: I, for one, plan to have my consciousness uploaded to a supercomputer upon my death so that the Rails with Jason Podcast can continue on indefinitely.
JASON CHARNES: Did you recently watch Upload the TV show?
JASON SWETT: No, I've never heard of it.
JASON CHARNES: Oh, man. That's a whole nother conversation.
BRITTANY: Consider that homework, Jason.
JASON CHARNES: It's an interesting question because we started ours out of nothing. I wonder, is one of us going to get tired and just quit? I'd like to think that if one of us did, it would keep going because there are plenty of cool people who could hang out and talk Ruby on it. But it's interesting, something that's casually crossed my mind, but I think we're good. I think we're still doing it unless Chris and Andrew have a surprise for me today.
ANDREW: Surprise! [chuckles] I've thought about it a few times, specifically because I'm the youngest member of Remote Ruby. What if Jason and Chris just left, and they were like, "Oh, it's all yours now." Could I keep running it by myself? I think honestly, the answer is I would probably still do it just to have an excuse to talk to someone. I enjoy it. It's almost like a hobby at this point. I don't feel any obligation to create it. To me, it's really like an excuse to hang out with two friends, and other good stuff comes from that. But at the end of the day, I cherish that time just us hanging out a lot.
CHRIS OLIVER: Yeah. I think that's why we sometimes joke about it being a weekly therapy session where we are just hanging out and chatting about stuff. It's nice to be able to talk about programming things at a high level with people you don't work with that have totally different perspectives and stuff. So yeah, if Jason and Andrew dropped off, I would still try to have conversations with random people I know and keep it going just because it's enjoyable. I would hope that we would be able to keep it going and have other people on there.
BRITTANY: I'd love to hear from someone from The Bike Shed.
STEPH: I have thought about it. I've thought about it partially from the perspective that Chris Toomey brought up earlier in regards to being on a podcast is an incredible platform. You get to share your opinions, and people listen to you. And they know you, and it's really wonderful marketing. So I have thought about it from the perspective of I want other people to have access to this really wonderful podcast that we put on each week. So part of me is very aware of that and thinking about how more people can have similar exposures.
So a sort of a similar event occurred when Chris was moving on from thoughtbot and pursuing other interests. And at that moment, I just thought, oh my goodness, Chris brought me on as co-host, and now I'm here alone, and I don't know what I'm going to do. And I just panicked. I truly don't think I even considered other options. I was like, well, okay, it's over now. This was fun. And then it turned out where Chris was going to stay with the show. So things have just gone on swimmingly, and it's been wonderful.
But similar to what someone was saying earlier around when you start listening to a podcast, and you really develop that relationship and you go back to that podcast because you really enjoy hearing from those people and their adventures, it's very similar for me where The Bike Shed is very much the conversations and chats with Chris. So I think if we were to move on, it would be whenever Chris and I decided to move on and give the reins over to somebody else. I don't know if Chris fully agrees, so this will be interesting to find out. [chuckles]
CHRIS TOOMEY: I agree with that. Honestly, I'm honored to have continued on in the podcast after having moved on from thoughtbot because, in a very real way, the show is thoughtbot's channel to talk about things. I was at thoughtbot for seven years. I think I live and breathe that truth. And to me, that's what maybe has made sense for me to continue on. But I really do feel a responsibility to keep the show in good shape so that someday someone else gets to inherit this thing because I was so happy to get handed it. It was such a wonderful thing. And it has been such a joy to do for these past three years.
But at some point, I do presume that we will move on. And at that point, I do hope that other people pick up the mantle. And thankfully, thoughtbot as an organization, there is a group of individuals that I'm sure there will be someone wonderful that gets to step in, but I'm in no hurry to do that. And, Steph, I hope you're not either. So we'll continue the conversations for now, but I definitely do want to keep this thing alive if for no other reason than I got handed it. I don't feel like I could let it drop on the floor. That doesn't feel right.
BRITTANY: Well, I think on that warm, fuzzy feeling, we should wrap up. So let's go through everybody and just tell the listeners where they can listen to your podcasts and follow you. I am Brittany Martin, @BrittJMartin on Twitter. And you can listen to the Ruby on Rails Podcast at therubyonrailspodcast.com.
JASON CHARNES: So I'm Jason. We are Remote Ruby. I am @jmcharnes on Twitter. And I'll let the others tell you where you can find them.
ANDREW: You can find me everywhere @andrewmcodes. And if you email me, there's a really good chance you're never going to see a response because my email is a disaster. Please don't email me, but you can contact me anywhere else.
CHRIS OLIVER: I'm Chris Oliver, and you can find me on Twitter @excid3 or at Go Rails, and of course, gorails.com. And you can find the Remote Ruby podcast at remoteruby.com.
CHRIS TOOMEY: I am @christoomey on Twitter. The Bike Shed is @bikeshed on Twitter. We are at bikeshed.fm for a URL. I'm pretty sure www works, but I'm going to go check that real quick after because I want to make sure that's true. And yeah, that's me. And I'll send it over to Steph for her part.
STEPH: I am on Twitter @SViccari, and I post programming stuff, usually pictures of cute goats, cute dogs, that kind of content if you're into that.
JASON SWETT: For me, if you want to find my podcast, it's Rails with Jason. And if you search for Rails with Jason anywhere, you should be able to find it. And then my website, if you're interested in my blog and all that stuff, is codewithjason.com.
BRITTANY: Fantastic. Thank you, everyone, for being on this mega episode today. It was a lot of fun. We are going to be having a podcast panel at RubyConf; we’re excited to announce and some of us will be present. So stay tuned for details around that. And if you enjoyed this mega episode and want to see more mega episodes, please let us know on Twitter.
All: Bye.
CHRIS: The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us @bikeshed or reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Bye.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Support The Bike Shed

Aug 3, 2021 • 46min
303: Dear Mr. Grumpy Goose
Chris gives a DB sessions update and talks bifunctors & command objects. Steph shares the coolness of a gem she's been using called after_party, and excitedly gushes about her new laptop. (Chris is hoping to hold off on replacing his until the end of the year and then they can compare!)
The two then answer a listener question on retrospectives and how they've seen productive ones run, while giving some of their own helpful opinions on dos and don'ts. They're talking to you, Grumpy Goose!
dry-monads gem
attr_extras gem
after_party gem
What Went Well? - Bike Shed 123
What I Believe About Software - Bike Shed 172
Is Agile Over? - Bike Shed 299
Running a Retrospective - Upcase
Transcript:
STEPH: Cool.
[laughter]
CHRIS: Good. No, I like what you did there.
STEPH: Yeah, I feel like we can get rambling on that one.
CHRIS: It's been great. This is what the Bike Shed is at its best. It's the two of us just rambling and being like, well, what about this? And if it's this, then that, then these, and it depends. And it's complicated and it's nuanced. And what about the humans? That's the story of The Bike Shed right there. [laughs]
STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari.
CHRIS: And I'm CHRIS Toomey.
STEPH: And together, we're here to share a bit of what we've learned along the way. Hey, Chris, how's your week?
CHRIS: My week has been good. I have some updates actually on some topics from previous episodes. One of the things that I can update on is the discussion around the cookie versus the database store. So I had posed this as a thing that I was going to be doing in the app for a handful of reasons. Most notably, I wanted the ability to invalidate sessions from the server-side, wanted to have a little more control over that. And so that's a dream that the database-backed session store can do. Eventually, I have to make that actually work in the way that I want.
But I was asking the question in that episode, which we can include a link to the specific episode, but I was asking the question of why don't we just do this all the time? The database-backed sessions seem better in all these ways. It's a lower overhead per request because you're just sending the session ID and the cookie instead of the whole payload of the session. You actually can have more data stored in it, a bunch of things that seemed really great. And then right after I introduced it, I figured out the thing. I figured out the secret. It's not a big issue, and we're going to stick with database session stores. But we have to be purposeful because it turns out they are essentially plain text in the database.
And so if there's anything that you are putting into the session like say a social security number or an authentication token or other things which naturally I might have done if it was in a cookie that lives on the user's browser and never actually lives on the server, persists on the server, that seems fine to me. But now these things are getting stored in the database and that really changes the calculus, especially because if I'm not purposeful, they'll just stick around for forever. So social security is probably the most pointed example of this. If you happen to have a form in the app that accepts a social security number and you want that to persist through some number of other steps, not actually going to store the social security number in the database because that's a thing that I have actively chosen not to do. I need to send it off to some other system, but I do need to hold onto it for a few minutes. The session is a perfect place to put that unless the session gets stored in my database.
STEPH: That's such a great point. I'm so glad you discovered that. And in our recent conversation, we were trying to think of the reasons why this isn't the default case. You may be headed in this direction, but this may also be timely, the fact that you're discovering this issue but also the fact that Rail 6.0 now has encrypted columns. Is that where you're headed with the fact that you can still keep session data in a database?
CHRIS: That is a great question, and it is an intriguing option. But it's not the one that I'm going with here. I think broadly, my hope is to completely avoid ever persisting this data in the database, this truly sensitive user-specific PII or PCI or social security numbers or any of these other fancy acronyms that get collected together under the umbrella of I probably don't want that on my server. For those, I'm just opting to push them back into a cookie. So I'm using particularly a...In rails, it's fun because they have a fluent interface where you can just chain together things, so it's cookies.signed.encrypted.whatever, and then you go from there. But I'm using signed, encrypted cookie, which is essentially what the session store views; the cookie session store uses itself.
So I'm basically reverting to the old session store behavior for specific values. So anything that is truly sensitive like that, I'm just saying, cool, that's actually just going to live in a cookie, and that will be it, but not leaning on the ability to encrypt the database sessions. There's just enough subtlety around that. There's so much volume of data if I do allow that sensitive data into the system that any failure, any exploit that happens, would be somewhat catastrophic. So, in my mind, this lowers the surface area and says, yeah, this data really never lives on the server. It comes with a request, and then it's gone after the fact. And that's the world I want to live in.
STEPH: Yeah, that's super interesting. You're also raising questions for me that I hadn't considered when we originally had this conversation where there's necessity or that you're looking to store form data or sensitive data in that session as well. So that makes a lot of sense to me that for that type of behavior, we're going to separate that from the idea of authentication and the user session and still use encrypted cookies for those details. So it only stays with the user's browser, but then the actual authentication of a user that part could still live in the database.
CHRIS: It is ending up being a weird Venn diagram of; this is data that I want to stick around but only sometimes and particular to the machine that the user is interacting with because the session is still associated with a cookie at the end of the day. So a user may have multiple sessions in the database-backed session version. It is somewhat interesting, and I'm going to see how it develops over time. But yeah, at a minimum, I have now found this edge case of like, ooh, okay, sensitive data, that's a thing, which is one of the reasons that I would reach for the session inherently. So it turns out, as always, it depends. Things are complicated.
STEPH: It's a nice update. I like when we have closure to a question like that, especially so quickly.
CHRIS: Love to provide that continuity. It's what I'm all about. But yeah, what's up in your world?
STEPH: What's up in my world? I am excited that I have a new laptop. So I have been using a MacBook Pro for about the last...it's lasted me for a while. I think I've had it for a good four, four, and a half years, but that's on the fritz. The keyboard, in particular, the keys are popping off, and that's something that I could go get fixed. But I'm at the point that I need a new laptop. So I have a brand new shiny laptop. And I had the option to either go with a 16-inch MacBook Pro or to go with one of the new, fancy laptops that has the M1 chip. And I was torn for a little while because having the M1 chip sounds really cool and novel, and there's a lot of speed improvements that come with that.
But I ended up going with just the 16-inch MacBook Pro; specifically, one, it's still very fast. It's very reliable. I can use this as my work machine and just know everything's going to work. That part feels really important to me. And then also the screen size is important. So any Mac laptop that is using the new M1 chip, I think they only go up to a 13-inch, right now, screen size. And I really want the 16-inch in case I am traveling, so I have that larger desktop. But I did do some research into the M1 just because I know about it. I know it's out there. I know it's hot. People are interested in it, but I didn't know a whole lot about it. So for anyone else that's like me and is curious about what the heck this M1 chip is, it's essentially Apple's foray into making their own processors.
So traditionally, their machines have used Intel CPUs and third-party graphic processors, and other parts. And this introduction of the M1 chip really represents Apple's switch to having their own internal architecture rather than relying on those third-party parts. And it also means that all those features that were sourced from other parties like the CPU and its security are now being combined into a single chip, which has also led to some performance improvements. And while I was reading about the M1, there's a lot to go through, but the thing that stood out to me was this idea of Apple's Neural Engine. And I thought, well, that sounds super fancy. What is that? Are you familiar with Apple's Neural Engine? Have you read about that?
CHRIS: I don't think I am. What all is that?
STEPH: Yeah, good question. That was a question I was asking myself just recently. So essentially, their neural engine it's a microprocessor that specializes in the acceleration of machine learning algorithms. So it's really similar to how a GPU will focus on accelerating graphics rendering. And their neural engine or neural engines in general then focus on accelerating neural network operations. And the inclusion of a neural engine isn't something that's new because Apple introduced this into iPhones and iPads back in 2017 to support their features like Face ID and emoji, searching for photos with dog pictures. Siri speech recognition is also one that's using this engine and other machine learning tasks.
But the sparkly stat that Apple is sharing with this new design is it's a 16-core design that can perform 11 trillion operations per second, which sounds very fancy, very fast. But it really got me thinking about how companies are working to improve, not just laptops but also our mobile devices to run machine learning software more efficiently, and then how that's just going to evolve and change all the different features that we use, and then how developers can integrate with this engine. I think currently, Apple hasn't shared much information about how this engine works, but I think they've exposed a few developer tools so people can still build features that will then use the power of this faster, improved neural engine.
CHRIS: Oh, that's super interesting. I have still not really delved into machine learning or artificial intelligence, or any of that stuff in any real way. But it's one of those things like the number of mentions is ticking up. And at some point, I'm like; I probably have to pay attention to this, don't I? I'm still in the not paying attention to it camp. So if I'm understanding, though, you just described this wonderful feature, but you opted for the machine that does not have all the fancy stuff. You did not...
STEPH: Exactly. [laughs]
CHRIS: Okay, yeah.
STEPH: Yes, it would have been nice. That would have been neat, but yeah, I needed a machine with a larger screen, all those good things. And that's still really fast, for the record.
CHRIS: Oh yeah. I'm desperately hoping to make it to the end of this year. This is going to be a bit of a rumor mill here, but my understanding is the expectation is that Apple is going to release a 14-inch MacBook Pro with the M1 and the return of MagSafe, and the removal of the touch bar. And that sounds like my dream machine right there. I want that piece of hardware.
I also seem to care a little bit less about the size of the laptop screen. I'm so often working at my desk with a large-format monitor that I'm connected to. And so, when I'm on the road, I want to optimize for portability when I'm traveling because I do it so rarely, and then I'm hopefully focusing on travel at that point. But we'll see if that remains true as the shape of my work changes and I start to not only work from home. And maybe I'll actually change my tune on that. But for now, that's my hope is to make it to that machine and then get one, and that it exists because right now, those are all rumors.
STEPH: Well, I totally support this goal of yours. So that way, you can have that new-new, and then you can report back on what it's like, and then we can compare. Because I'll have the other version, the Intel CPU, and then you'll have the M1 chip, and we can see how our lives are different.
CHRIS: You'll have the new, and I'll have the new-new, and that's how we'll categorize them.
STEPH: [laughs] But yeah, I'm very much looking forward. Having a new laptop is always just such a fun feeling. It's just a clean space that I get to rebuild. It's like going through and prioritizing; what are the things that still spark joy? And then I get to only port over the stuff that I still really use all the time and want to keep. So I'm looking forward to getting it set up.
CHRIS: I need to do that sometime soon. I'm like five years deep, at least on this machine. So I've been dragging along. Also, the hard drive is just completely full, and I regularly have to go through and delete things before we start recording because it turns out these audio recordings start as very large files. [chuckle] So it's almost a weekly thing where I'm just like, got to throw something out today. I don't know what. It's fine. I'm going to be fine. [laughter] I'm going to make it to the end of the year, and it's going to be great.
STEPH: What else is going on in your world?
CHRIS: Well, I wrote some fancy code, and I use fancy not necessarily as a good word. [chuckle] So I'm intrigued that the code could be described perhaps as clever or other words like that, which I think are very complicated words in the coding space. I tend to try and avoid this type of coding where I'm trying to introduce abstractions and clean things up, and remove duplication because I've been burned by that so many times in the past. But this time, I think maybe this time it'll work.
So, in particular, there are two different areas of the application. There were two sets of refactorings, but they really went together. One is we have the idea of command objects within the application that we're working on. So there are a lot of cases where we need to save something to the database and then communicate something to an external API. And then presuming the results of that is a successful response from them, then unpack some data, make sure it's in the right shape, and then save something else to the database. And ideally, wrap that all in a transaction and keep everything together and then return some data at the end of it.
So that whole sequential operation, I've been using dry-monads to model that. I've talked about this on a few previous episodes. I'm really enjoying it. The more I lean into it, the more I find that it is just a really great way to wrap up that very procedural code. But ideally, do it in almost a functional way so that we've got these sequential operations that feed into each other. There's the railway-oriented programming stuff, which is associated with this idea.
But there is a lot of boilerplate to these objects. So the way we've defined them is they have a class method called run that takes whatever the arguments are, and then it needs to pass those arguments into the initialize and then call run on the instance. So in order to define one of these objects, what we had been doing was def self.run and then all the arguments. And then inside of the body of that, it's new, and then pass forward all the arguments .run, and then define initialize to capture all of those and set all the instance variables, and then define the run method, which actually does stuff. Also need to define an Adder reader for all of those instance variables, which is a thing that I enjoy doing. So that's the interface I want, or that's the way that I want this class to work. I know other folks in the Ruby world feel differently. But that's the shape of the thing that I want, but that's a lot.
And there's also I regularly would find myself forgetting to duplicate something that we put into the class method run interface into the initialize method. And it was just like, this is all just wiring up and plumbing. There's also the binding of the dry-monads do notation for the run method as well as the inclusion of the results type within dry-monads. Type is a strong word, but that gives us the success or the failure objects that we can create. So ideally, all of these command objects either return a success object or return a failure object. It's one of the two. And that's one of the things that I really like about them. But yeah, so much plumbing.
So we define a base command, and the base command has the self.run method, the class method, and that method is defined very abstractly. So it's just args * keyword args. So we're capturing all of the arguments and then forwarding them on to new. So that way, I don't have to think about that interface. It basically just says, "Give me anything, and I'll forward it onto new." And the new or initialize is in charge of actually defining things. It also includes the result type. It includes the macro annotation for the run method, which is how dry-monads does its magic, that actually I had to include inline within the self.run, just because of the sequence of definition and the metaprogramming that's going on there. As I said, that sentence terrifies me a little bit, but hopefully, no one ever needs to look at this magic base class [chuckles] and figure anything out. So that was one part of it. That cleaned a lot of things up, so that meant I didn't have to write a ton of the wiring up code.
Then there was still the noise of actually defining all of the arguments to these classes. They often take a handful of arguments because that's their job is to grab a bunch of things and do some work with those things. So for that, I have brought Adder Extras, which is a gem that I've talked about probably in previous episodes, I think so. But this is the first time that I've really leaned into it and used it. And it gives some very high level what look like macros are just class methods. But the one that I'm using is Adder private initialize, and that you can then pass a variety of values too. And it will then say, okay, this method accepts a required keyword arg, a defaulted keyword arg, and a positional argument or something to that effect. But it's a very, very concise way to express that and then also get the private Adder readers, which again is the direction that I want to go with all of this.
So that’s a bunch of things that I have said. But all total, it cleaned up these command objects very nicely. And now, when you look at one of these command objects, all you see is the run method that does the work. And the plumbing and the wiring up behind the scenes should just happen. I am concerned about the day that someone forgets to inherit from the space command, and then it's like, why does nothing work? I thought command objects just worked in the system. But we're going to deal with that when we get there, which is hopefully a while down the road.
STEPH: I like how you're pushing at the boundaries of our comfort zone. I say our comfort zone because I imagine we feel similar.
CHRIS: It is. We definitely got a shared comfort zone. [laughter]
STEPH: Yeah, we have a shared comfort zone with inheritance, but you're pushing at that boundary of that comfort with inheritance because it is something that can be so painful. But you've identified an area where inheritance feels useful. And then it also sounds like a very meaningful...you're introducing this pattern and then trying to make it easier for others to follow this pattern. So it's a very intentional design decision of where we want to group these behaviors together and then make it very easy for other developers to then pick up this pattern and run with it, and then also work with these classes. So I am intrigued to hear how it goes and how others feel about the pattern as well.
I also wonder, this is one of those areas where it feels like this very intentional design decision. Is it something that you think in the base class would be worth highlighting? Like, hey, here are the things that we are using in this base class. This is the intention of this base class. I don't know if that's maybe a comment or if that's something that's documented in the README. I know; I see your eyebrows went up when I said comment. But it does feel like one of those areas where it's like, hey, we have introduced this new concept. We want you to follow along. Here are some helpful guidelines.
CHRIS: Those were mostly joking eyebrow raises because I have thought of that. I haven't actually gone to that level. But in the back of my mind, there's this pattern that we have within this application. Ideally, we're going to lean into it more and more so that A, we have a clear way that we do things within the app but also make that as understandable and discoverable as possible. I'm not sure if a comment in the class is the right thing or...so I'm deferring what I want to do on that for now because right now, it's myself and one other developer. We sort of developed this in tandem. So we were working together on it. We would pair in a bunch of the features. And what we have now is the crystallization of what we found useful. And we're both very comfortable with it. So there isn't the need to explain it.
I'm almost thinking about it as just-in-time educational content around this piece of our application. I don't actually trust that I would do a good job describing it in the abstract because I know it. Like, to me, this thing makes sense right now. But I've been on the other side of stuff where someone was like, "Hey, this totally makes sense." And I'm like, "I don't know any of the words you just said," and so I felt that pain being on the other side. You could say I'm just being lazy, but I do think this is a purposeful delaying of that where I want to wait until I actually have someone to teach this to. And at that moment, I want to see what that conversation looks like. And I'll try and explain it to the best of my ability, but I'm sure they're going to ask questions, and I'll be like, "Oh, wow. Yeah. I hadn't even thought of that. But now that you ask the question, totally let me explain this part that I was going to gloss over and forget to mention."
And so, ideally, that is what will happen down the road. And then from that, hopefully, some artifact becomes clear, whether it's a documentation page in the repo or a comment in the class if it's simple enough or maybe even it's a recording of a pairing session. And that's the artifact that we keep around that explains this piece of the application. So I definitely think a version of that makes sense, but I am not doing it yet.
STEPH: It's funny; you’re saying so many good things that I agree with. I love the just-in-time education; that part is fun. And yeah, there's a part of me that definitely still leans into the idea because we've talked about this in the past too, where we write down, in the moment, the things. Having that context when we're implementing it is really important and helpful. So even if it's not this grand explanation…which I really like what you said around having someone to explain it to or have that conversation with so that way you're documenting the useful bits, that part I like very much, but capturing the intent as soon as the change was introduced. So even if it is a very high level like, hey, we are using dry-monads and Adder Extras, even if it's just links to those things, that's something that I think I would still favor just to go ahead and start surfacing this is a pattern. This is a choice. And then, as you continue to work with the pattern, if you change your mind, it's still very easy to scrap that documentation.
So I think if it were me, I would still go ahead and document it. I think it's that piece about discoverability that's calling to me so strongly where that's where I want to then highlight the things that are in use. So even if there's not an explanation, people can find the resources very easily. Because you're right, you did say a lot of interesting bits in describing this pattern. And the fact that we're talking about it now also just deepens my suspicion that it would be nice to comment somewhere, and perhaps a repo is a perfect place for it and just get it out there, and then it can always be revisited later and improved.
CHRIS: Okay. I like that you are keeping me honest on this because I do think there's a certain amount that I'm just being lazy here and not wanting to do that because it is actually really hard to try and document something like this. Like, what are the important pieces versus what are the extraneous details that people don't actually need?
I do wonder, so the pull request that did this refactoring and introduced this base command object that does have the explanation captures the point in time and whatnot. And so I wonder, is there a version of tagging important pull requests that tell the story of the application? A lot of things are just going to be like; this is adding a feature. It's the same as the other 30 pull requests recently that added a new feature. But this one is special from an architecture perspective. And so let's tag this, let's add a label. I don't know what it is but something that allows for discoverability of the story of how this application became what it is today because anything else I worry will go out of date almost instantly. But this pull request is true fundamentally in that same way that we say commit messages should capture as much of that detail.
So I did do that writing for the pull requests/the commit message. And I wonder if maybe that's the best artifact for this moment but then the question of surfacing it and making it discoverable because otherwise, it's just lost in the sea of other pull requests. So I don't know. But I do like the slight push back that you're giving me here of like, yeah, but what if you did something though? And I'm like, yeah, that's fair. I should probably do something.
STEPH: Being able to pin those specific PRs that have significant architecture changes sounds really novel, but I'm going to take this opportunity for me to be lazy. And if I'm joining a project, I don't want to read through what has happened. I just want to know what's true now. And if I go back and look at those PRs, I won't know if all of that is still relevant and how it's changed. So it sounds neat from telling the story of how an application has evolved. I like that sort of developer lens, and what are the things that we have tried and then changed over the years? But from I am onboarding to this application, I just want to know what's true today? What are the things that you want me to follow? What are the patterns that are going to be really helpful for me to look at? And so then, I don't know if I would use it in that context.
And this may be one of those areas where I'm feeling overly skittish in response to the number of things that you said and the use of inheritance. Because I have felt so much pain of where I'm going up the tree to figure out what the heck is happening in the world and then to understand all of those pieces, and then swimming all the way back down to the class that I'm actually working in. So it could just be past experiences that are now influencing how I want to document or work with inheritance. It probably is. [chuckles] That's probably a big factor of it. It doesn't mean I disagree with it because those painful experiences are meaningful. [chuckles]
CHRIS: Yeah. I think the foundational thing...I tried to start this with the context of like; I did a thing. This is another example of good idea, terrible idea; my favorite segment on The Bike Shed. I stand by it. I think it was useful. It does use things that we have traditionally moved away from. I say we because, again, I think we have a shared approach to development at this point. But I think it's worth it. I hear everything that you're saying about the documentation, but I've been burned by that so many times where the documentation is like, here's what's true now. And you're like, no, there isn't even a class called that anymore, and no less does it work that way. And so, my inclination is not to go that way.
The solution that I have in mind is when someone is onboarding into the application, I don't expect there to be documentation and other things that I can hand them so that they can run. I expect to sit down with them and work with them. I'm going to pair with people when they join a team for a long time. There's a period where that's true, I think, and then you get to a certain size of an organization, and you're onboarding enough people regularly enough that that's a thing that you should get better at.
But for I think a surprisingly long time, my answer I'm more than happy for it to be, yeah, we're bringing someone new into the team. Let's sit down with them. Let's spend the time. Let's tell them what's true because I know currently, and I can give them an up-to-date version of that. And ideally, as part of that, then update the static documentation, the repo, the README, the other things based on the conversation that we have and recognize oh, that that link is very out of date. Let me change that one real quick. But I'm not expecting to have comprehensive documentation for that. I'm expecting to use real human interaction to fill that gap.
STEPH: Yeah, I really like that you're also calling out how fallible documentation is and how it has misled us so many times. I also love what you highlighted where when somebody new is joining the team, we are more than often going to sit with them and then explore the app together. And it just made me revisit that phrase that you used earlier about the just-in-time education. Because for this command object, you may join the project and not need to interact with this design pattern for your first couple of weeks, first couple months, who knows?
So then it comes back to the idea of how when someone is in the space of where using a command object feels like the right approach, then how do we introduce them to this pattern and then make sure that they have the tools that they need? And if someone is accessible to then sit down and go with them, that's great. But if someone is not accessible, then I still want them to have at least a few of the resources that they need to dive into some of the more complex things that are being included. So, yeah, it's a tricky one. I like this thought experiment.
CHRIS: But yeah, overall, I'm happy with it for now. I'm hopeful it will work out for us moving forward, and I'm hopeful that it will also be a sufficiently discoverable or teachable thing within the application. But again, I will certainly report back and see how that one plays out for us. But yeah, that's what's up in my world. What else is going on in your world?
STEPH: Something else that's up in my world is I have pulled in a tool that I've used in the past, and I really like it. So I'd really like to talk about it here for a bit because I just find it so useful. And now that I've added it to this new project, it's just really top of mind for me. So I found that when working on a project, there are often times where I want to run something right after a deploy has happened, and I want that to be automated. I can do it manually. I can hop in, but then perhaps if you're deploying across many environments or many systems, you don't want to have to do all that manual work, or you also just want the convenience of you can set it and forget it. And that way, you know something's going to happen. So perhaps it's something where you want to change some data, or if you want to enable a feature flag, then this is really helpful.
So the gem I've been using for this is called after_party, where you can write automated deploy tasks that essentially behave very similar to migrations. So you can write a Rake task. It has a timestamp. You can implement the logic that you want to be run right after your code has deployed, and then after_party itself, we'll check the timestamp. It will see if it has been run. If it's already been run, it won't run it again. Or if you like, you can set it up so that way, you can tell after_party to say, "Hey, after every deploy, I want you to run this particular task," but it's such a nice improvement to the workflow.
And the other thing that I really like about this that I feel is a bit contentious is separating changing data outside of migrations. So I am a big fan of migrations are focused on changing your schema itself. But if there's actual data that you need to change, I really like when that is separated outside of the migration. There are definitely times that I understand it's really nice to just do it all at once, and it's easier. But anytime it starts to get even a little complex, I immediately want to write tests for it. And I can't test my migration. But if I'm changing some meaningful data on production, I want tests to back it up to make sure that I'm scoping correctly, that the outcome is exactly what I expect. It also makes it easier for other people to review. And after_party gives me that functionality so then I can have my migration.
But then I'm like, oh yeah, but I still want to automate changing this data because that's often one of the complaints that I hear from people when I do ask them to separate into a Rake task, changing the data. They're like, "But I don't want to have to then follow up and then run this task later." And I'm like, that's cool. After_party has you, and you can automate it and not worry about it. So after_party has been one of my favorite gems to add to applications.
CHRIS: That's interesting. There's a bunch of layers to everything that you just said. I think I've worked with after_party on a project. I think we were working together on that project, if I'm remembering correctly. I have no bad memories of it, which given the nature of the tool, makes me think it did its job very well because its whole point is just like, oh cool, now you can just do this thing, and you don't even really have to think about it. Because there are plenty of other times where I've had to orchestrate or do a deploy. And then I SSH tunnel into production, which is a bad idea, and then I'm running Rake tasks manually. And so, I think the fact that I don't have any pointed memories of this is a really good sign for a tool like this. So that's a weird vote in its corner for me.
You did say something that was interesting that I want to poke at a tiny bit which was you can't test migrations, and I think that's true. Like, I don't know of any way. And it feels like a thing that is sort of fundamentally deeply true. But I do wonder, is there any gem out there? Has anyone done a weird science experiment to figure out like, I would actually really like to be able to test my migrations? So I think the idea of having to pull data change out of migrations for the reasons that you said totally makes sense.
But there are often times where I want to convert from non-nullable to nullable. And in the process, I want to backfill with a given value or something to that effect. And I like to encapsulate that altogether such that if it fails or succeeds, it's transactionally consistent. And I do wonder, could I wrap a test around that? I don't know of a way, and I think it may actually be the Rails testing infrastructure is just like no, we prepare your schema for you in the background, so it's just up to date. And therefore, you don't even have a way to be in a state where the migration hasn't run. But it's an intriguing one.
STEPH: Yeah, that's probably a hard absolute that I said where you can't test it, and I'm sure there is a way to test it. How friendly or how easy that is to do, I'm really not sure of. It also feels like one of those areas where it feels like I'm testing this other service that I should trust fully, so then I'm not necessarily testing the migration itself. I'm testing some logic that I've added inside of the migration where I'm changing some data. And the example that you provided is perfect because that's one of those that I'm inclined to include in a migration. It's more like where we want specific users who have this value or in this category. And then, we want to migrate them from this data to the other data. And when we start getting complicated in our migrations, that's when I'm like, this is a bit much, and I'd really like a test that documents that we're doing this correctly. That's where I get squeamish about having data changes in migrations. But you do raise a good point. I don't know; I’ve never tried to test one. I've just always reached for this other approach, but that is more the pain point of if I could test this data change inside of migration, then that would work for me. That would solve my problem.
CHRIS: I wonder if an alternative approach would be to just introduce an object or a class that does this work. So like a command object as it were, to do a call back to earlier in the episode, that does that data transformation because it’s exactly what you're describing, for this subset of users do this. But if they're in this state, then do these things and create two new records for any user like this. That sort of stuff is really complicated. Definitely want to have some tests around it. But you're talking about a gem that allows you to extract it into a Rake task-like situation. But I wonder, could we just have a class for that?
And I used to be a big believer in your migration should live forever, and they should always be runnable from the beginning of time. I've given up on that belief. That's one of the things that I've been like; I don't know. It turns out I've never done that. It's not an important thing. Just DB schema load is going to be fine most of the time. It's great for the past ten migrations to be around just to tell a little bit of a story. But I'm not tied to migrations being runnable forever. So the idea of you introduce this class, it encapsulates that data transformation. You can test it because it's its own thing. It will still be run within the context of the transaction of the migration. And then you throw it away down the road along with the migration, and you do that migration roll-up thing. It's just a different thought there, although I do like the...well, I guess that would also run automatically, but that runs as part of the deploy as opposed to after the deploy, which is meaningfully different than what after_party does because there might be one of these migrations that takes a long, long time to run because you've got a ton of data. And you want to decouple it from the true deploy release sequence that happens and the time limits that are there. So I think I've now talked myself in three circles, and I'm going to stop.
STEPH: I like how you highlighted that part where it does decouple you from the deploy process where it's still automated; it runs afterwards. But say if it's something that doesn't need to hold up the deploy, you don't need to wait for this data to be migrated before the deploy can go out. Then that's a nice separation because then it can happen afterwards. Or if you do need it to happen part of the deploy, yeah, there's lots of interesting bits there. I feel like you and I could talk about it for a while.
But we have a listener question that I'm really excited for us to talk about. So I'm going to hard pivot over to our listener question. This question comes from Jonathan. And Jonathan wrote in, "Hey, gang, longtime listener, first-time emailer. I've heard you reference retrospectives a few times as part of your normal development practice. In my limited experience with them, I often find retrospectives don't feel productive because team members are reluctant to raise issues without seeming critical or blaming another team member. I would love to hear you describe how you typically run retrospectives to foster open discussion and make it a productive use of time. Bonus points," oh, I love bonus points "if either of you have experienced rescuing an existing team that was not having productive retrospectives. P.S. Thank you for ongoing participation in the Ruby and Rails communities. I look forward to seeing a new episode pop into my podcatcher each week."
All right, retrospectives. I love this question because I've definitely been part of teams that are really struggling to have a productive retro. So I think it would be helpful, as Jonathan highlighted, to go ahead and share how thoughtbot runs a retro. And then I'd also love to touch on some of the areas where I have seen teams really struggle to have a productive retro. So with the thoughtbot format, there are really two questions that we focus on. The first question is, what went well? And this starts the meeting on a positive note, which can help people get engaged before then we move on to heavier topics like concerns and issues.
When we run a retro, we ask each person these two questions. So that first question, we go around to the room, and we say, "Hey, what went well for your week or for your last two weeks?" And then we document all of those positive things that people say. The next question is, "What concerns do you have, or what are you worried about?"And the goal here is to highlight issues early, which then gives us the chance to address them as they come up rather than waiting till an issue has grown out of control. And it's usually during the concerns portion that I often see retrospectives fall apart. The reason for that is hearing someone describing a concern is often something that can stir up a lot of emotions. And I know for me, it certainly triggers my instinct to where I really want to dive into that issue, and then I want to solve it.
But by reacting to a specific issue and then trying to solve that issue, I'm interrupting that retrospective flow to then focus on that issue. And we may not get to a bunch of other important issues that people had. So that's often where I see retrospectives fall apart. And the way to fix that is to then have the team consensus that hey, this is a space where everybody gets to air concern. We're going to go around the room, so everybody has a chance to speak. We're going to document it, but then we're going to move on and then come back to this later.
So when do we talk about concerns? So once everybody's had a chance to share their concern and that's been documented, during that process, you're often upvoting other concerns. So someone may bring up a concern that I also have as well. So when it's my turn to speak, I'll say, "I'd like to plus-one that particular concern," and then maybe add my own or just plus-one some of the others. So then, by the time that everybody's had a chance to speak, you already have an idea on…whoever's taking notes or if it's being ideally shared so the whole team can see. You can already see the concerns that most of the team is identifying with or that are the more popular concerns. So then, as a team, you can say, "Hey, we're going to focus on the top two concerns because that's really the amount of time that we have," and that way, we're focusing on concerns that impact the majority of the team. So at that point, then we can start talking about those specific issues and how we'd like to address them.
And then out of that conversation is then the next part of the retro format, our action items. And then action items are where we can capture the things that we would like to try during our next iteration of work until our next retro. This is our experiment area. So then we can say, "Yes, we'd like to try something different, or we'd really like to monitor how this goes."
And then one other fun thing that I typically include in retros are housekeeping. So then we can talk about time off, team celebratory events, anything like that that's helpful to highlight to the team.
That's a quick overview of how typically I myself run a retro. Chris, do you have anything you'd like to add or anything that I've missed?
CHRIS: No. I think that that mirrors pretty well the best retros that I've been a part of. There are a couple of things that I think I would add or emphasize in that. So one is foundationally, with a retro, what are we doing? What's the goal? And the goal with a retro is to identify and evolve our process. So identify where there are any bottlenecks or things that aren't working, and then ideally change things over time. I've been on many teams where just the same issues get brought up over and over in retro, and nothing changes. And that will just completely deflate the team. And so, if that is happening, that's a fundamental thing that we need to fix.
And I can totally understand folks being like, "Retro is awful. We just sit down and say the same things, and then nothing ever changes." If that's happening, we have to fix that at a more fundamental level. That is going to be more than a retro’s worth of effort. But ideally, retro is now this structured space each week, each iteration, whatever it is where we are discussing what's going on and ideally, slowly, incrementally making the process slightly better. In my experience, it's something that I really love because I come to associate it with stuff is going to get better now. That's what retro means. If that's not the feeling you have, then I totally get why you wouldn't want retro. But I promise that that can be a reality.
And then to touch on some of the particular procedural points, everything you said definitely maps. And I've found that structure works really well, but there's a lot of subtle things in that structure that I think are important to highlight. So one, going around the room and actually asking everyone individually for their thoughts, I find to be so useful because it's very easy for one or two more vocal individuals to just dominate the conversation. So particularly by starting with what went well and then also by actually going around the room and requesting "Everyone reply to this question please," even if it's just like, "Yeah, you know what? It just felt like a good week." That's an answer we'll accept but ideally, a little more structure or a little more meat to it. But I find that to be really important.
Likewise, I have found that having a facilitator, so someone who is guiding the retro but not actually a part of it. They're not going to be saying what went well or what didn't go well. They are just directing the conversation and somewhat critical as you're going around and asking for concerns. They are the person whose job it is to prevent the team from starting to try and address the concern when it's first voiced. So ideally, we're just collecting the concerns. We're collecting the plus-ones so that we know which are the more prominent ones, and then we can focus on those.
And I think that idea of the plus-oneing of concerns and then really focusing on the ones that have more folks that are concerned about it feels really critical in my mind. So ideally, we are a team. We're working as a team, and if one person has this gripe that they really feel deeply, but nobody else really cares about it; ideally, we find a way to help that person not feel that way. But that's not necessarily where the team collectively should put all of their energy. So yeah, that's a bunch of little pieces.
Also, just as a note, we'll include these in the show notes, but there are a couple of previous episodes, so Episode 132: “What Went Well?” is a discussion between Derek and Sage, previous hosts of the show, talking about retros. Episode 172: “What I Believe About Software” was the first guest visit by a certain Steph Viccari. And so that is a wonderful episode in which we dug into retro because it's one of our favorite topics. Also, Episode 299: “Is Agile Over?” We definitely touched on...that was a pretty recent one, but we touched on retro. Then there's also a video on Upcase called “Running a Retrospective” that basically describes exactly this process and shows actually an example retro and running through it. So there are lots of other things that we can point out here. But again, I think fundamentally, what are we doing, and how are we doing it? If we can answer those questions well, retro is going to be great. If not, it's probably not going to be that great.
STEPH: I appreciate you calling out all of those important nuances because those nuances are what lead to then a retro feeling more productive. And to address Jonathan's other question around if people are feeling timid to bring up an issue because they don't want to blame anyone, then I think to address that one; specifically, you have to come to retro with a WE mindset. And I think HBO accidentally sending a test email is a really good example of that. Because in the Twitter thread, a bunch of other I presume developers were commenting and responding in support of the person that sent that out to say, "Hey, you discovered a missing safety net in the system," or the fact that it was fairly easy to make this mistake and send it out. So if you come to retro with this mindset of if a mistake was made, how can we as a team improve this so then it's less easy to make that mistake? Then you won't have the sense of we're blaming this on one person, but instead, we as a team are responsible for helping each other out.
CHRIS: It's interesting to have that conversation in the context of retro because I don't necessarily think of retro in exactly this way. But there is the idea of blameless postmortems, which come out of the Google Site Reliability Engineering; I think it's a book, maybe it's a website. We can include a link regardless. But that idea of blameless postmortems of collectively as a team, this thing made it out into the world, this bug, this problem. So we need to own that as a team, and we need to have a blameless conversation around that, just talking about what happened. And there are subtleties there. And that's a nuanced idea that needs to be evolved, but that is at least some writing that exists in the world that talks specifically to that part of it. That said, I wonder if a true postmortem, so a distinct meeting just dedicated to those more pointed issues, might be more relevant, and then retro is more of a shared overall conversation. But if there are smaller versions of that, then I think using that framing could be really helpful in retro.
STEPH: Yeah, I think you said that perfectly where there needs to be team ownership over all of the issues that are being discussed. And I think there is one other very tricky area to navigate with having a productive retro. And I don't know of a better way to say this. But you have a grumpy goose on your team. You have someone who doesn't like retros, and they're going to be negative, and they're going to be vocal. And that is a hard one. I have been there before. And I often approach that situation by speaking with them specifically around what are your concerns with retro? Are you willing to at least buy-in and give this new format a chance? But you essentially need them to buy in or have leadership buy-in so then they know to follow suit as well that this is a team process that we're going to improve and work on together. And if you don't like it, then that's what retro is for. So how we can make this a better, more productive meeting? But just showing up and being grumpy isn't helpful. And then helping people who have been burned by retros overcome that negative reaction to retros is something that takes time.
CHRIS: Oh yeah. The grumpy goose just affects everything on the team. But definitely retro is one where I've seen that particularly pointed. I think in those cases, the best luck I've ever had is to, like you said, have a separate conversation but have the conversation at a higher level. So the question isn't about do we have retro or do we have it in this shape? The question is, do we think we are operating at our best? Do we think everything is going perfectly? And almost never will the answer be "Yeah, this is great. We have no bugs. We're moving as fast as we possibly can. Everyone is happy. No one is burnt out." And so if we get to an agreement that is like, well, yeah, sure, there are things that we could improve, then I think that's a toehold that we can then build on and say, "Okay, so how do you want to go about that?
I am fine to explore a different approach than retro as a meeting to continually improving and evolving our process. I'd love to know what thoughts you have, Mr. Goose." But if they don't have an alternative, retro is the most effective structure that I've found for this continuous feedback loop around the process. I'm very happy to find an alternative, but I critically think we need something like that. And so if they're going to be pushing back on retro specifically, then I'll bump up to the higher level and say, "Okay, how do you want to be improving our process? Let's try something else, but let's make sure we are asking the question of how do we improve our process and is that succeeding?" And also, stop being so grumpy. Come on, what are you doing?
STEPH: [chuckles] I recognize that approach so much because then it really gets to the heart of the purpose of retro whether it's actually called retro or how we handle it is not significant, but the fact that we together as a team can get together and discuss how to improve. That's really the important thing that we're after. And retro just happens to be the format that I use and really enjoy. But like you said, it's always open to each team's interpretation.
On that note, Jonathan, I hope this quick overview of the thoughtbot retro has been helpful. And we will also include some other links that also highlight how thoughtbot runs retros and some other discussions that we've had about retrospectives. But on that note, shall we wrap up?
CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed or reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Bye.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Support The Bike Shed

Jul 27, 2021 • 39min
302: Observability with Charity Majors
Tune in as Co-founder and CTO of Honeycomb, an observability platform, Charity Majors joins Chris to drop some knowlege bombs such as:
Thinking of observability as being about the unknown unknowns: Allowing for high cardinality, high dimensionality, ad hoc queries at any point in time.
Comparing instrumentation to a muscle: It's a habit that needs to be developed and fostered.
Sincere continuous deployment: 15 minutes or bust.
And bunches more, since y'all know you hear her name come up at least once during every other episode!
Honeycomb.io
o11ycast
Charity's blog (charity.wtf)
Charity on twitter
Charity's post on cost of not doing continuous deployment
Charity's post - The Engineer Manager Pendulum
Transcript:
CHRIS: Hello, and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. And this week Steph is taking a quick break, but while she's away, I was joined by a special guest, Charity Majors. Now, folks who've been listening to the show lately will know I've been mentioning one idea or another from Charity almost every episode these days. Charity's work spans from the deeply technical through to the deeply human. And across all of it, she brings such a wealth of experience in pragmatism while consistently providing grounded, actionable advice about how we can improve all aspects of our work.
And to give a bit more context for those who aren't as familiar with Charity's work, she is the co-founder and CTO of Honeycomb, which is an observability platform that we talk about more in the episode. Charity is also a prolific blogger, tweeter and speaker, and general leaver of digital breadcrumbs for the rest of us to hopefully follow. And Charity is also one of the hosts of the o11ycast podcast. That's observability, o11y podcast. And in fact, in the intro to the first o11ycast episode, Charity provides a beautiful summary of her approach to the varied work that we do. Quote, "I'm someone who's always been drawn to where the beautiful theory of computing meets the awkward, messy reality of actually trying to do things." And that quote rang so deeply true to me when I heard it and really encompassed what I see across the variety of work that Charity has shared with us. And frankly, I've been so impressed with the quality and quantity of wonderful content that Charity has shared over the years. I was really just thrilled to get the chance to sit down and talk with her directly. So without further ado, here's our conversation with Charity Majors. Thanks so much for joining us today, Charity.
CHARITY: Thanks for having me. It's great to be here.
CHRIS: As I've mentioned on many an episode, I've been following your work for a while now. And at this point, I would say that just about every Bike Shed episode has a reference to you and some piece of work that you have put out into the world, whether it be a tweet or a blog post, or a conference talk or something. So I'm so grateful for all the work that you put out into the world and for taking the time to chat with us today.
CHARITY: That's so exciting. Yay. I feel right at home here then. [chuckles]
CHRIS: Fantastic. Well, I want to dive in. I think it's sort of the core of some of the conversation that we'll be having, which is around instrumentation and observability, and observability as a newer, noveler form of how we think about this space. But to give a bit of context, I was hoping you might be able to give just the quick summary for anyone who might not be as familiar with observability as a concept and what that means now, and Honeycomb as a product and how it offers affordances around observability and pushes that envelope forward.
CHARITY: Yeah, I think of the observability as being about the unknown unknowns. For a long time, all of the complexity was really bound up in the app. You had the load balancer, you had the app, and the database. And all the complexity you could just attach to a debugger and step through it if you had to. But then we kind of blew up the app, the monolith, and now it's in services scattered to the winds, and you can't just trace it. And so observability is a way of passing that context along hop by hop so that you can actually slice and dice in real-time. And the hardest problem is not usually debugging the code. It's finding out wherein the system is the code that you need to debug.
And observability, if you accept my definition, which is it's about unknown unknowns, that you should be able to ask any question of your systems, understand any internal state just by observing it from the outside, well, then a lot of things proceed from that, in my opinion. Like, you need to be able to handle high cardinality, high dimensionality. You need to be able to string together a lot of these high cardinality dimensions. You need to... any kind of schema or indexing scheme in advance is verboten because you don't know what questions you're going to need to ask. And so there's a lot that flows from that definition; arbitrarily-wide structured data blobs is the source of truth, et cetera. But at its heart, it's just about the concepts, that our problems are getting harder and harder. We don't get paged to go, "Oh, that again? Oh, that again?"
CHRIS: [chuckles]
CHARITY: Ideally, we fix those things. But we still get paged. What the hell is this? It's about allowing engineers, empowering them in a reasonable amount of time to be in constant conversation with that code that's out there in the world because most problems honestly we never get paged about. They're too subtle until they snowball, and they pick up other problems. It's like a hairball under your couch until it gets so big and so impacting that it actually does alert someone. And then you just start picking up the rock and be like, oh God, what's that? Well, we've never understood this. And that's why ops has such a reputation for masochism. [chuckles]
CHRIS: Absolutely. There are so many little pieces in what you just said that really deeply resonate with me, although there is one facet of some of the way that you talk about observability that I find interesting. I'm someone who likes to cling to the perhaps unrealistic these days ideal of a monolith of what if we were to just keep everything in the same place and all the data lived together in one database, and I could have foreign keys, and consistencies, and asset compliance?
CHARITY: Which you should do for as long as you possibly can. You should never impose more complexity on yourself than you absolutely need to. And I would say that it's never not better to have observability than the older paradigms of monitoring and so forth. Some of Honeycomb's biggest and best customers still use monoliths. But they still find it really valuable to be able to apply the principles. I think that it's the microservices revolution, if you will, that forced this set of changes. It was inevitable. The steps that I started talking about, like, somebody would have because the older way just became untenable when you started adopting containerization and a lot of these things that made everything suddenly a high cardinality including the number of applications you have. But it's never not better to have high cardinality tools and to be able to instrument your code for spans and tracing. Tracing is still valuable even in the monolith.
CHRIS: Yeah. As I've observed and started to play around with Honeycomb, that's definitely what I've seen is I'm almost exclusively working in the context of monoliths and, like I said, clinging to them for as long as I possibly can, which isn't going to be forever.
CHARITY: It's true. [chuckles]
CHRIS: I recognize that truth, but already I see the value. And so Honeycomb is a platform that you've built that allows for this high cardinality, high dimensionality ad hoc queries at any point in time. And so the idea that I can come into the tool and say, "Huh, I've got a new novel problem today." I don't need to re-instrument my code. I can just ask a new question, and the system will responsively be able to answer that question, ideally. And that feels like it holds true in a monolith all the more so, like you said, in an SOA architecture. But even in my safe little playground of everything is in the same space, I still don't know how everything's working all the time if we're being honest. So being able to answer those questions feels meaningful.
CHARITY: Totally. I think that one way of thinking about the SOA or microservices is that it pushes a lot of what was in the operations realm into a realm of development, and suddenly you're responsible for a lot more of the operating of your services, things like retries and backoffs, and load distribution, and thundering herds, and all these things that ops traditionally took care of. Well, now you have to think about them. So you need some ops tools, too. What I like about...of course I like everything about Honeycomb because we designed it for this problem. But it speaks in the language of variables, and endpoints, and functions, and not in the low-level language of proc IPv6 timeouts and stuff where I feel like ops has also traditionally been the translation layer between software engineers and their actual code in production. And it's time to start giving software engineers those tools in their own language.
CHRIS: Yeah. I love that. And I'm very happy to have Honeycomb as part of an instrumentation stack, which actually shifts me to the next question, which as I look at Honeycomb, very quickly the first time I saw it, I was like, oh okay, this makes sense. I want this in the world.
CHARITY: Oh, I like you. [laughs] Not all people are like you.
CHRIS: It might have been my second or third look, but it was definitely...once I got it, I was like, oh yes, I absolutely want that. But now, the question that I have is I typically will have a collection of tools that exist in this space. And there's a weird Venn diagram overlap of well, there's logging, and there's error tracking, and there are APM performance tools, and there's metrics, dashboards. And my sense is that Honeycomb perhaps can or an observability tool more generally can subsume a bunch of those, but it's not clear to me exactly. I think I probably still want logging. I think I still want error tracking as a discreet service tool that I'm using but maybe not APM and maybe not metrics as a distinct thing. Maybe I can infer those from a tool like Honeycomb. But I'm wondering what's the current thought on that?
CHARITY: Well, part of what you're seeing is just observability tooling is very new, and we haven't had time to grow up. And here I'm like, officially, we play very nicely with all other vendors, and none of us would ever try to compete or take away from each other's faces. But I do think that ultimately, logging pretty much the only real use case for it is security stuff, the security archiving, just keep every log light. It's gotten cheap enough, but it's not actually useful for debugging or understanding your system, not really. It's useful for compliance. It's useful for proving that you did something in the past. Most logs are just a pile of trash, but they can be useful trash. And I understand people's emotional want to hold onto them for a while, and there's nothing wrong with that. There's nothing wrong with keeping some trash around for a while, while you make it...[laughs] Sorry, not to totally slam on logs, but they are trash.
CHRIS: I love the analogies that we're going for. [laughs]
CHARITY: But the thing about observability is I do think the kind of center of the world is these arbitrarily-wide structured data blobs from what you can infer logs, from which you can infer metrics, from which you can roll-up. So I do think that well metrics are the right first tool for understanding infrastructure. Like if you're Amazon and you're responsible for all this hardware and stuff, you should be asking yourself, is my service healthy? But if you're someone who's writing and shipping code on top of that service you care about, can my request complete? What is my user's experience? And that's observability's territory. So I think that ultimately, I do think metrics, logs, and traces all get subsumed under the observability umbrella and performance management, too, if the tools get built correctly. There will still be use cases. They will just get smaller, for logs, for standalone metrics tools.
Honeycomb just launched our metrics product. Metrics is like a 30-year-old piece of technology. Prometheus and Datadog are going to be the last best metrics tools ever built. We have wrung the water out of this laundry. [chuckles ] But we aren't trying to compete with that. What we are trying to do is give people an on-ramp into Honeycomb. They've got decades’ worth of stuff. They've been corralling metrics, structuring them. You rely on them. You don't want to give them up. So yeah, let's feed them in. Let's give them an overlay. And number two, the more interesting use case for me is when you're a software engineer who's writing and shipping code, you do care about did the memory usage just triple, or is the CPU completely buzzing after I shipped my last change? But there's really only like three or four of those metrics that you really care about as system metrics. The rest are mostly legacy.
CHRIS: I like the idea that aspirationally, Honeycomb is moving towards a place where given sufficient input data, given this arbitrarily-wide data blob with high cardinality, et cetera, that we can infer basically all of those others from it. But also speaking to also observability is somewhat new, and so we got to build a lot of product to get there and that idea that there is perhaps a space right now where you might be bringing together a few of these tools. But if there is a future world in which I can have one of these tools that just handles everything and tells me about my code and directs me to the line of code that I incorrectly instrumented, that would be wonderful. Happy to do the work in the interim to cobble it together from the pieces.
CHARITY: The place in the meantime that we're at where all of these big vendors are acquiring other vendors and trying to put together...they're like, we have three pillars. Coincidentally, we have three products to sell you. It's like, it's not good for the users because when you're...like, you're sitting in the middle here. You've got your metrics dashboard. It's telling you that there's a problem. Okay, if you can't slice and dice and figure out what it is, you have to jump over into logs and visually correlate based on the times and hope no timestamps are wrong and try and find the thing. And then, oh, okay, so you want to trace it. So you've got to copy over and try and find that in your tracing product and hope that that would get sampled in. It's not good. You can't follow the question from the beginning. I have a problem to the end. I have a solution and back. And it's not linear. You're going to be following a trail; then you're going to need to back up, then you're going to find another trail. And then you're going to want us to zoom out and see who else is impacted. And you really can't back your way into that with different products. You have to start with the arbitrarily-wide structured data blob.
What does confuse me is I know that New Relic is built on this. New Relic has these. And we almost didn't start Honeycomb because we were just like, edit data, and New Relic is going to figure it out. Here we are like six years later, and they still haven't fcking figured it out. [laughs] But like Datadog, they aren't based on that arbitrarily-wide structure, so they are really...and I know that they're trying to get...all of these big vendors are trying to get to where Honeycomb sits technically faster than we can grow up and become a business.
CHRIS: The race is on.
CHARITY: Yeah. It's fun.
CHRIS: One of the related things that I've seen you talk about a few times is the idea that instrumentation is a muscle. It's a habit that needs to be developed and fostered, and that rings very true to me. At the same time, a lot of my instrumentation work has been more in a reactive space. If we're being completely honest, something went wrong; we can't figure it out from the information that we have available, so then we go in, and we add a new logging line. We wrap the code in some way. And so I'm wondering if you can talk a little bit more about that. What does that look like in practice or perhaps some examples or something? But how can we tease that apart and understand that a little bit better? Because it sounds wonderful to me.
CHARITY: I think of instrumenting a lot like commenting your code. It's a way of thinking to the future and reverse engineering; what am I going to care about? What is someone else going to care about? And I really do think of commenting as just a less true version of instrumentation, honestly. It's you talking about what you think the code should be doing, but you've left production out of the loops. You don't know what the code is doing. [chuckles] But ideally, they're kind of the same muscle. It's why you're writing your code. You've just developed a monitoring thread almost in your brain. It's like, yeah, this is going to be valuable. Oh, this is going to be valuable. And so I do think that it's on vendors to make sure that we do as much for you as possible. And this, honestly, is the long winding journey to Honeycomb finding product-market fit, which took almost three and a half, four years.
And for a long time, I was like, it’s not magic. You have to understand your code. You have to blah, blah, blah, which is true. But also, we need to walk closer to the user. We need to make it easier. We need to do the beeline, which will initialize the event, pre-populate it with a bunch of stuff, create the framework so that all you have to do as a user is just printf now and then just stuff this in the blob, vendors making it as easy as possible, as automated as possible. We have more to do. We really should be pre-populating it with all of the language internals and all of the stuff about the environment. We'll just be glad to tap that well. But there's something that we can't do for you, which is understand what you're trying to do and what is important.
Honestly, here's a story from the past. The reason that New Relic was so big, they hit the ground, and they super hockey-sticked everything was because they dovetailed with the rise of Ruby and Rails because Ruby allows for so much fcking monkey patching. Every web app looks the same. You can just be like, we assume all this crap, and so we could make it just like magic for you. You just install this library. Boom, you're off to the races. Well, try as you might, I want to say a type language like Go, you can't do that stuff with. You can't make it as magical. You have to think a lot more about how you're structuring things for better or for worse, which is why their growth slowed because those languages just aren't so popular anymore.
So it's trade-offs all the way down. Yes, everybody should be an expert in forecasting the future and understanding all the subtle things that you don't know you're going to know, but you're super are going to want to know. But as you've discovered, most of your learning comes from being in the trenches, which is why it's so good for devs to be on call and be close to their code and be in this constant conversation with it because you develop a sixth sense. I can't tell you exactly why I know it's going to be a problem, but I'm just going to wrap it because I'm pretty sure it is.
CHRIS: There was a tiny bit that I was hoping that you would have some very specific like, oh, you just do X, Y, and Z. I kind of knew that wasn't going to be the answer, but it also represents something that I so appreciate about your thinking and the work that you put out into the world, which is it's realistic. Sometimes you're like, you know what? There's going to be some tacit knowledge involved here. You got to put in the work. You got to learn the thing, and that's just true sometimes. And so I appreciate your willingness to be like yeah, you know what you got to do? You got to do the work. And then after that, you'll know...and so there's sort of a virtuous cycle that can happen here. There is a feature, as far as I understand it, of Honeycomb, too if I can briefly hype up your products slightly but the idea that you can observe the series of questions that another developer asks. So if they were in a debugging session, you can see like, oh, they asked this, and then they asked this, and then they filtered on that.
CHARITY: It's like your Bash history but for debugging. [chuckles].
CHRIS: I want this for everything.
CHARITY: Right?
CHRIS: Let's have a shared hive mind of the developers on a team, both in terms of our observability tool but also just kind of everything.
CHARITY: What did you do?
CHRIS: Yeah, what did you do, and why? What were you thinking? I saw you went down a road there, but then you stopped and backed up, and you went a different way. That's interesting to me.
CHARITY: This is why we keep trying to build things into the product that will incentivize people to write texts about what they're doing, whether it's retroactively applying tags or writing a breadcrumb to yourself. Why was this meaningful? As you're putting it in your bookmarks, why are you putting it in your bookmarks? Collaboration is just as much about collaborating with your past self and your future self as it is with the rest of your team. I don't remember why the fck I did that two years ago. I don't know. I don't know why I did that two months ago. But the more you can leave breadcrumbs for yourself and then surface that to the team, you're right; it’s transformational.
I wanted this so selfishly because I have never been that person on the team who loves graphs. I hate graphs. I don't think visually very well at all. I've been working with my friend, Ben Harts, off and on for like 10, 12 years now. He's always the person I've hired repeatedly. He's always the person who comes in and makes the graphs. And then I look over his shoulder, and I bookmark them. I can be up all night making the perfect dashboard. And then I'm like, great, mine. [chuckles] So there's room in the world for both of us. But the point is that not all of us should have to go through that effort. [chuckles] We should be able to learn from each other. Only one person should ever have to have to craft the perfect query, and then the rest of the team should be able to effortlessly piggyback on it.
CHRIS: Yeah, absolutely. And again, I want that but for everything. I dream of a future in which that's true.
CHARITY: And so much of debugging is this wandering path where you go down the wrong place, and you need to be able to zoom back to all right; where did I first know that I had a beat on it?
CHRIS: There's a corollary that I see to pair programming where one of the things that I find so valuable is, what Google query do you type in when you hit that wall? When you're like, oh, this isn't working as I'm thinking, and then you type something and I'm like, whoa, wait, I wouldn't have even thought to ask that question of the internet.
CHARITY: Oh, I love that. That's fantastic.
CHRIS: But now you've productized that, and I love that. So thank you for building that thing in the world.
CHARITY: Excellent.
CHRIS: Shifting gears slightly, one of the other themes that you really pushed for in the world is the idea of continuous deployment and not like yeah, you should ship your code pretty quickly after you merge it, but true, sincere continuous deployment.
CHARITY: 15 minutes or bust.
CHRIS: 15 minutes of bust, test in production. There are some really wonderful if we're being honest, scary themes that you talk about. I love the ideas that you're putting out there, but they're probably the things that I look at, and I'm like, ooh, that seems like a whole thing right there.
CHARITY: It assumes a lot. Let's put it that way. It assumes a lot.
CHRIS: It definitely does that. I desperately want to get to that world. I want to get to the place where there's that confidence. And similarly, there's a theme that you've talked about around Friday deploy freezes and why that's not a good thing. And the empathy for humans that part's good, but maybe we're applying it in the wrong way if we say we're not allowed to deploy code on Friday. Because it's like yeah, deploying code is terrifying and scary. No, let's solve that problem. But I wonder if you can talk a little bit about that. How do you get there? How do you get to the place where continuous deployment is a realistic outcome for you?
CHARITY: Yeah, that's a very good question. There are no easy answers, unfortunately. And the answer is always going to depend on where are you starting from? Are you starting from a clean slate? Are you starting...a lot of the advice that I give sounds like Looney Tunes to someone who's coming from enterprise because they're just like, "You don't understand the constraints that I am operating under." And I'm like, "Yeah, you're right. I'm not of your world. That probably shows." [chuckles] So I think the easiest way, though, is always when you're starting a new project that what you do on day one would be to set up your CI/CD and deploy it to prod before you've even started building. My favorite analogy to that is to like...you know the myth about Alexander the Great and his horse how when he was a little boy he would pick it up every day before he had breakfast? And so, by the time he was an adult, he could pick up his horse because he picked it up every day, and it was never hard.
When you start deploying that way, it's never hard. When you're just like, okay, anytime this gets above 10 minutes, we're going to put in a couple of hours of work, and it's never hard. It's just the easiest thing in the world. And everything's easier because you get to watch what you're doing and in real-time, and you develop that muscle of I’m merging it to main. I'm going to go look at it in a couple of minutes. And you don't feel done in your gut until you've looked at it. And that's doing it on easy mode. And you can do this in a hybrid way. Even if you have like, well, I'm paying for a deploy. Nobody is saying you have to sign up for a long, painful deploy process when you got to spin up a new project. And I've seen it gain momentum. If you start something that's clearly the new way, everybody sees how fast this team is executing. Everybody wants a piece of it. And so you start learning from the way that you are able to do it in your unique environment. You're the best evangelist to the rest of your team members because you know the subtleties. You know the problems. So that's the easy answer is start fresh. [laughs]
CHRIS: [laughs] That makes sense. I do, again, I appreciate the pragmatism or the realism of the way that you approach a lot of the topics.
CHARITY: Another answer, though, it's just that the engineering work involved in taking a deployed pipeline down from hours, days, to 15 minutes it's just engineering work. It is just labor. It can be done. The political problems are the hard ones. I mean, in the past, sometimes our deploy probably would get up to two or three hours, and we were just like, oh God, this is not…put in the work. You just start instrumenting your pipeline, and you start looking at where the tests are taking time. And it will pay dividends every bit of time that you pay down, which is why I really see these long…our own pipelines is it's a vacuum of engineering leadership that they've allowed it to happen because there's nothing fancy about it. You just put in some work.
CHRIS: Yeah, the solvability of the technical challenge feels very true, but what you're saying of it's people problems which again, that's always true of the tech stuff.
CHARITY: It is people problems, but I also hate it when people are just like, oh, it's people problems. That means mysterious and unsolvable. Now, most of the time, when you see this, it's a lack of collective confidence in themselves. They see this as being as just for the elite engineers, or only ex-Googlers are allowed to do this or something. Or they go to conferences, and they hear about it, and they're just like, God, I wish I was allowed to do that, or I wish we could do this.
But the thing is that engineers have more power than they realize. We build these companies. They wouldn't exist if it's not for us. We have all the power if we just choose to use it. I know that a lot of these people who I've talked to that were just like, "Oh, I wish we…" I'm like, "Have you ever lobbied for it?" And they're like, "No, I just know we could, or that's someone else's decision." I'm not going to promise you that you can get whatever you want. But I promise you that if you start speaking up if you start talking to your colleagues and being like, "Wouldn't it be nice?" And they start speaking up...if a quarter of the engineers want something in the company, it gets done. [chuckles]
CHRIS: That definitely feels true. And to the topic of actually lobbying for this and having the hard conversations internally and working on the people problems, you have done, I think, a really fantastic job of providing actual benchmarks in terms of timing and what does this look like as a practice and what are the multitasks?
CHARITY: It's so expensive. It's so costly to organizations. And it's the easy answer for any engineering leader to be like, "Well, we need to hire." That is the laziest answer in the world. You probably don't. You probably just need to fix your CI/CD system and then bask in the resources that you suddenly freed up. [chuckles]
CHRIS: You have a wonderful blog post that really I think does such a good job of highlighting the cost that you're talking about there, the human costs for every slowdown in your deploy process, it has this downstream ramification. And having that as sort of a piece, a bargaining chip in the conversation of here's a voice that is saying a very clear thing about this cost of not doing this work, which granted, it's always trade-offs. Everything is an optimization. But here is a way to actually measure the cost of not going with this approach. And again, I appreciate you're putting that out there in the world so that the rest of us can be like, "Look, on the internet, it says so."
CHARITY: [chuckles] Exactly. I'm happy to be the internet for you. But it's so true because other people in your business don't want you to suffer too, either. They don't want everything to get slow. They just aren't equipped to understand the cost of this slowness the way that engineers are. And I feel like sometimes this is...it's like we're always lamenting like, why does product get to own all the engineering cycles? Where aren't we allowed to do all this other stuff? I promise you're allowed to. You just have to make the case because the case is righteous and justified. But you have to explain to them the cost that it's incurring your organization in terms of your ability to execute and in terms of your ability to hire and retain people. You just have to explain those costs. And engineers are just like, "Well, we only say it once, right?" Well, that's not how you win arguments. You have to say it. You'll probably lose. And you say it again, and you'll probably lose. You say it a third. And you will win eventually because you control all of the creative labor of the technical organization. So just make the fcking case. [chuckles] I don't know. I make it sound simple; it’s not.
CHRIS: I love the sound bite of the cause is righteous, and that is the kernel of the thing here, which is like, just to be clear, this is a virtuous path that you were going down, battle for it, work towards it, absolutely. So I think a related topic here, so continuous deployment is one of those things that you want to get to and a practice that you want to evolve to. But in exploring some of your other work, one of the things that I was exposed to is the DORA metrics, which is not something that I hadn't seen before. But for anyone who's unfamiliar, the DORA metrics is a set of four key metrics to track developer and team productivity, so their deployment frequency, lead time for changes, change failure rate and the time to restore the service. And they are deeply interesting because frankly, I have for a long time felt like developer productivity was not really a quantifiable thing.
CHARITY: It's not, yeah.
CHRIS: Individual developer productivity I still feel like this is a bad thing. Don't do that. But team productivity these metrics actually are like oh, actually, as I look at those, those seem like the good ones. We should do that. I'm wondering, what does that look like in practice when you see that actually employed within an organization? What are the feedback loops, and how does this appear in the world?
CHARITY: Yeah. We all owe a huge debt of gratitude to Jez Humble, Gene Kim, and Nicole, who worked on this for years and got this out into the world, just putting some actual research behind the stories that we were telling ourselves about productivity. And people who haven't read Accelerate...a lot of people are always asking me, do we have any stories? Do you have any research? Do you have any proof or something? I just always point to the book Accelerate. That's where it all comes from. Yeah, it's true because it's such a noisy world. When you're an engineering org, and there's just so much going on, and there's so much stuff that bugs you personally, and some of the stuff that you have true beliefs about. And it's hard to just cut through the noise.
And I feel like that's the great gift of the DORA metrics. If you start focusing on one of them, you will lift your org out of poverty, and the others will get better too. And it provides just this wonderful focus point for teams that aren't sure where they stand or aren't sure how to get better because it can be so mystifying. When you're in the trenches, and you're just like, why does everything feel so hard? Why is it that we thought this would take two days, and here it is two months later, and we can't ship anything? And it feels like the more we ship, the farther behind we get. These are the beacon of hope. It's like, you pay attention to these, your lives will get better. You can dig yourself out of this ditch.
That's certainly been true for the teams that I've been on. And high-performing teams, I think we all have this idea in our heads that high-performing teams are ones where the great engineers join when in fact, those great engineers could join your team, and they wouldn't get any more done than you are. Because most of our productivity is defined not by the data structures and algorithms that you know but by these social-technical systems that we swim in every day, it’s the water around us. It's the friction involved in getting that code to production. If it takes the magical engineer from Google 24 hours to get their code changed out, well, they're not a member of a high-performing team either.
You mentioned earlier all these people are out there who haven't experienced a world like this don't live in a world like this. And in my experience, they often lack a lot of confidence because they don't think they're that good, or they don't think that they can have nice things. And the DORA metrics that's your ticket to a better life. It's like go to college and graduate because it kicks off these virtuous feedback loops, these cascading cycles of things getting better for everyone and people getting more excited and energized. And they just don't get burned out by shipping too much code. They get burned out by not being able to ship code.
And if you're a leader in any type of organization, and I don't just mean manager, I mean any type of senior engineer or manager or whatever, then it's part of your job to pay attention to these metrics, lobby for them, track them, track them on your own if you must, and try to make them better because every engineering team has two customers or two...whatever. I'm blanking on the word. But it's your customers and your engineering team. You're responsible to both of them. And I've never seen one of those sets deliriously happy and the other set miserable. They tend to rise and fall in tandem.
CHRIS: I'm just nodding along for anyone in the audience who can't see what my head's doing. But I love so much all of the things that you're saying and, again, the passion and conviction that you bring to this conversation because these are amorphous, hard to pin down ideas. But I appreciate the North Star that you're setting across all of these different things that as I'm reading, I'm like yeah, that sounds true. I want that. Those things are the things that I want. But interestingly, one of the other threads that I see weaving through a lot of your work is obviously we've talked a bunch about just deeply technical topics thus far, but also a lot of your work spans across to the interpersonal. And frankly, even dividing in that way is not representative of the world because it's a Venn diagram mishmash of some days it's technical, some days it's personal, some days it's both. But one of the things that you've talked about is the engineer manager pendulum which I find super interesting. I think every engineer at some point has that question, that internal oh, do I want to go engineer track or manager track? And this distinct idea or the idea that management is a promotion and any other movement would be different, and you have wonderful things to say about that.
The other thing that you've pointed out is that former managers can often make great engineers after the fact because of the earned empathy that they have now from looking at things from a slightly different angle.
CHARITY: Amazing engineers.
CHRIS: But I'd love to hear a little bit more of your thoughts on that because I think it's such an important space, and I've definitely previously operated under I'm an engineer, and then I guess I got to be a manager, and then I guess I don't know where I go from there, but it's this very linear path. And you shook that worldview of mine, and again, I appreciate that shaking. But yeah, I'd love to hear a little bit more about that.
CHARITY: The best people that I've ever worked with have been engineers who had been managers for a while and then went back to engineering, and it's not just empathy, although there's a lot of that too. It's also a deeper understanding of the business and the reason that we do things. So much of being a powerful engineer is choosing the right work to work on so that you get a lot done very efficiently and quickly, and you don't spend a lot of time just foundering, which you've mastered, and you know the basic technical principles. And how do you get better? A lot of it is just getting better at identifying what to do and what not to do because we have to not do so much more than we can ever do in order to move forward.
I wrote a blog post as a present for a friend of mine who was a director of engineering at the time, and he was suffering. He was just miserable, and he kept thinking about going back to engineering, just kind of dragging his...because he wasn't in an org where that was really celebrated or anything. When you've been there from the beginning, you built the organization; you’re like a senior director and everything. It feels like a long way to fall. And I wrote that post for him. And he did end up going on to be an engineer after that. And he was so much happier. But I think he was surprised at how he didn't fall at all. He actually probably had...I think the engineers had a higher opinion of him afterwards when he was one of them again. And he still had this vaunted voice because he could speak to how the system had been there since the beginning. And he basically got to look around and look out farther than the engineers who were heads down every day and go, "This is going to bite us. I'm going to take a small team. We're going to do this forward-looking security product."
I don't want to identify details, but that for me really just kind of cinched...It was like the more we can strip hierarchy out of these discussions; the healthier everyone's going to be because we're just monkey brains. And the monkey brain in our skull hates losing hierarchy, hates losing power or stance or anything. And I think that the thing that you learn after you've been a manager is a lot of it is just the wizard behind the curtain, the idea that you have more power as a manager. You have more of some types of power, and you have a lot less of other types. And you're just as constrained as the engineers but in other ways. And the path moving forward is not to dominate people or be above them but to combine your powers for good and self-sort to find a place that actually gives you the most joy.
CHRIS: It's a wonderful philosophy. And actually, a thing that you said in there really stuck out to me, which was you wrote that blog post as a gift to someone, and that is such a kind thing to do. And it also, again, reflects what I see in your work overall. You're really clearly leaving a trail of breadcrumbs behind you to help other folks that are traversing a similar path by questioning aspects of it. Or how do we do this well? Why is everyone sad, and why is it bad? And so again, I so appreciate all of that work that you've done.
CHARITY: I think that that comes from my lifetime in the trenches of operations. [chuckles] Ops is notorious for the pain that we bring upon ourselves and try to solve. But I would just like to add a pitch out there for other ops engineers of the world and our colleagues. I was fortunate enough to rise up through the ranks in organizations that really respected operations. We always felt we ruled the roost. We felt like we were way above all the other developers. We got to say what went into production and what didn't. And I feel like ultimately...if you have to have an imbalance of power, I think that's slightly healthier than the developers ruling the roost. Ultimately, there shouldn't necessarily be any imbalance of power. But I just want to pitch it; this whole no-ops thing really got my goat for a while there because operations is just the engineering workaround delivering value to users. I think the second wave of DevOps is now about okay, software engineers; it’s your turn. It's time to learn to write operable software. And so I just wanted to throw in my hat in the ring for all the ops people out there. You're just as good. You're just as good as anyone else. [chuckles]
CHRIS: I mean, it's sort of a theme that I've seen in your writing of everybody's doing good, important work and breaking down hierarchy and just collaboratively moving in the same directions and trying to choose the right North Stars to aim towards. And yeah, it's all fantastic. And so with that, I think we probably reached a perfect spot to wrap up. But Charity, if folks want to keep up with more of your work online, where are the best places to find you?
CHARITY: My blog post is at charity.wtf, and I'm @mipsytipsy on Twitter, and of course Honeycomb.io and our blog.
CHRIS: We will include links to all of that and many of the blog posts, and other podcasts interviews that you've been on, and a bunch of just various things that I collected as I was preparing for this episode because, again, you've produced such a wealth of information on the internet that I want to point as many folks as possible towards those things. But yeah, thank you so much for taking the time.
CHARITY: My pleasure.
CHRIS: The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes,; you as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us @bikeshed or reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Bye.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success._Support The Bike Shed

Jul 20, 2021 • 42min
301: Ants in the Cookie Store
What do you get when you mix a worm and a hammerhead shark? Also ants. Steph made some cool new discoveries in bug-land. She also talks about deploys versus releases and how her and her team has changed their deploy structure. Two words: feature flags.
Chris talks about cookies: cookie sessions, cookie payloads, cookie footprints, cookie storing. Mmm cookies! The convo wraps up with lamenting over truthiness in code. Truthy or falsy? What's your call?
Flipper
Bike Shed - Ask a Question Form
Transcript:
STEPH: At the top of my notes for today, I have marauder ants and hammerhead worms. [laughs]
CHRIS: I'm sorry, what? I lost you there for...not lost you, but I stopped following. I...what? Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey.
STEPH: And I'm Steph Viccari.
CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, how's your week going?
STEPH: Hey, Chris, it's been a good week. It's been busy, lots has been happening. I learned about a new creature that's in our backyard. They're called hammerhead worms. Have you ever heard of those?
CHRIS: I've heard of hammerhead and worms, but not together. The combination is new and novel for me.
STEPH: Cool. Cool. So take a hammerhead shark and a worm and combine the two and then you have a hammerhead worm. And it rained really heavily here recently because there's a tropical storm that's making its way up the East Coast. And when I was outside on the porch, I noticed that there were these new worms or worms that I'd never seen before on the back porch. And so I had to Google them to understand because they had the interesting hammer-shaped head. And I found out that they're called hammerhead worms. They're toxic worms that prey on earthworms. And they're basically immortal because if you cut them into multiple pieces, each section can regenerate into a fully developed organism within a few weeks, which is bananas. And a lot of people online highly recommend that you should kill them because they are a toxic predator and they prey on earthworms, which you want in your garden and in your yard. But I didn't, but I learned about them.
CHRIS: Wow. That's got some layers there, toxic, intense worms that you can cut in half. And so does their central nervous system just spread throughout their whole body? Where's their brain? How does it...I don't have any real thoughts here. That's just a bunch of stuff, and it's awesome. Thank you for sharing.
STEPH: I will warn you. I wouldn't read about hammerhead worms right before bed. Otherwise, you might have some nightmares because the way that they do prey and consume earthworms or other creatures that they prey on is the stuff of horror movies, which I find happens so much in nature, but them especially they fall into that category. So just be aware if you're reading about hammerhead worms and how they consume their food. Now I feel like everybody's going to go read. But as long as you have that warning, I feel safe sending you in that direction.
CHRIS: Yeah, first thing in the morning on a very sunny morning, that is the time to do this research.
STEPH: Exactly. He got it. I also learned about marauder ants because apparently, this is the day that I'm having. I'm learning about all these creatures. But I won't go into that one, but they're really interesting. And this one's thanks to someone on Twitter who shared, specifically @Rainmaker1973 is their Twitter handle if you want to go see what they shared about marauder ants. So I'll just leave that one for those that are curious. I won't dive into that one because I don't want to take us in the direction of that we're all about worms and ants now.
CHRIS: Not all about worms and ants but definitely some.
STEPH: But in technical news, I've got some stuff to share, but I was so excited about worms and ants that now I have to figure out which is the thing that I want to share from the week. So there's a couple of interesting things that I'd love to chat about with you, one of them, in particular, is there's been some interesting conversations going on with my client team around deploys versus releases and how we have changed our deploy structure, and then how that has impacted the rest of the team as they are communicating to customers as to what features are available. And there have been some interesting conversations around how to migrate this process forward.
So to provide a bit of context, we were previously having very strict, rigid deploys. So we would plan our deploys typically every Tuesday. It was usually once a week. And then we would make sure that everything had been through QA, things had been reviewed and tested. And then we would have one of those more like grand deploys, things are going out. And then hey, if you need to get something into the deploy, let us know; we need to talk about it. So there was just more process and structure to that. And so deploy really mapped to the idea that if we are doing a deploy, then that means all these feature bug fixes are going out, and this is now the time that we can tell customers, "Hey, this new feature is available or this bug that you reported to us has now been fixed." We have since been moving towards a more continuous deployment structure where we're not quite there where we're doing continuous deploy, but we are deploying at least once a day, so it's a lot more frequent.
And so this has changed the way that we really map the idea of the work that's being done versus the work that's actually available to customers. Because as we are merging work into the main branch, and then let's say if I'm working on a feature and then I merge that into the main branch and then push it up staging, we have an overnight QA process. So then overnight QA, if they say, "Hey, there's something that's wrong with this feature. It didn't quite meet the required specs," then they can kick that ticket back to me, but that's not true for my code. We could do a revert and take my code out at that point. But at this point, it's in main, and main may have been deployed at that point. So there have been some interesting strategies around how can we safely continue to deploy while we know we often have a 24-hour wait period for QA and to get sign-off on this work? But we want to keep moving forward and then also communicate that just because the code has been deployed doesn't necessarily mean that it's available to customers. There's a lot there. So I'm going to pause and see if you have questions.
CHRIS: Well, first, I'm just super excited to talk about this. This is something that's been very much top of mind for me, and it's a direction that I want to be going more and more, so yeah, excited that you're pushing the boundaries on this. I am intrigued. I'm guessing feature flags is the answer about how you're decoupling that and how you're making it so that you've got that separation of deployment and actual availability of the feature. So, yeah, can you talk more about that?
STEPH: Definitely. And yes, you're right. We're using feature flags, so we'll use the same scenario. I'm working on a feature, and I want to be able to release it safely, so I'm going to wrap it in a feature flag. And I'll probably wrap it, and maybe it's like a beta feature flag, something to indicate that this is a feature that's going to be available to all, but we don't actually want to turn it on until we know that it's truly ready to be turned on. So then that way, it's hidden, but then we can still merge it into the main branch. We can still have a deploy even if my code hasn't gone through QA at that point, but we know it's still safe to deploy. And then, QA can go to a staging environment; they can test it. And if they say, "No," it's fine because nothing was churned in production. But then, if it gets approved, then we can turn it on, and then we'll have a follow-up to then remove that feature flag.
CHRIS: So some follow-on questions. I'm wondering about the architecture of the application. Is this like traditional Rails app rendering HTML on the server, or do you have any more advanced client-side stuff? And then I'm also wondering what you're using for the actual feature flagging, and those will probably inform each other. But what's the story on both of those fronts?
STEPH: It's a traditional Rails application. So we're not using any other client-side application. It is Rails and rendering HTML. As for feature flags, so we're not using something traditional. And by traditional, I mean I typically have reached for Flipper in the past for managing feature flags. We're using more of a hand-rolled approach because there's a lot of context there that I don't know is necessarily helpful. But to answer your question, we essentially do have feature flags as columns in the database, and we can just check if they are enabled or disabled. And then that also allows us to easily turn it on, turn it off as well since it's just a database update.
CHRIS: Okay, that makes sense. I think the nature of being a Rails application rendering HTML on the server like what you're doing totally makes sense in that context. I think it becomes a lot harder the more complex the architecture of your application is. So if you've got microservices, then suddenly you've probably got to synchronize across some of them, and that sounds like a whole thing. Or even if you have a client-side application, then suddenly you've got to serialize the feature flag stuff across the boundary or somehow expose that, which really does push the issue of we could just render stuff on the server and send it to the client and let that be good enough, then man, is stuff simpler. But unfortunately, that's not the case in a lot of situations.
I'm expecting to be introducing feature flags on the app that I'm working on pretty soon. And again, we've got...so it's a Rails server-side thing. So there's going to be plenty of feature flag logic on that side. And then I'll need to do something to serialize it across the boundary and get it onto the client-side without ballooning every payload and adding complexity, and lookups, and whatnot. I think it's doable. Inertia, again, being the core architecture of the application, I think will make this a little bit easier, but I am interested to see what I'm able to pull off and how happy I am with where I get to.
Another question that I have for you then are you testing the various flows? So given a Boolean feature flag, you now have two different possible paths for your code to go through. And then there may be even more than Boolean, or you may have feature flags that sort of interact with each other. And how much complexity are you trying to manage and represent in the test suite?
STEPH: Yeah, good question, and we are. So we're testing both flows, especially if it's a new feature, then we are testing when the flag is enabled or disabled. One that's been tricky for me is what about a bug fix? Is that something that should be feature flagged? And I think at the surface level, if you're presuming that it needs to go through QA before this is live on production, then the answer is yes, that then you have to feature flag a bug fix, which feels weird. But then the other consideration would be, well, it is a bug fix. And could we find another way to QA this faster or some other approach so that way we don't have to wrap it in a feature flag? And I don't have a great answer for that one because I can see arguments in favor of either approach. Although wrapping everything in a feature flag does feel tedious, it's something that I'm not accustomed to doing. And it's something that then becomes a process for the team to remind each other that, hey, is this wrapped in a feature flag? Or just being mindful of that as part of our process. And it prompted me to think back on the other projects that I've worked on and how did we manage that flow? How did we go from development to staging to QA and then out to production?
And one additional consideration with this flow is that we do have an overnight QA team. So in the past, when I've worked with teams, often product managers or even other developers, we would QA each other's work. So then it was a pretty fast turnaround that then you could get something up on staging. Someone could check it out and say, "Yes" or "No." But then I'm also pretty confident most of the teams that I've worked with we have had a distinct staging branch. So we would often merge work into a staging branch, and then deploy that work, and then get it tested. And then, if it passed everything, then we would essentially cherry-pick that work and move it over into production.
And I can see there's a lot of arguments against that, but then I have also experienced that and had a really positive experience where we could test everything and not have to worry about going out to production. We didn't have to wrap everything in feature flags, and it just felt really nice to know that everything in the main or production branch, whatever you call your production branch, that everything in there was deployable versus having to go the feature flag route, or the hey, did this go through QA? I don't know. Let me check. Can I include this? Should I cherry-pick some commits into our actual deployment to avoid stuff that hasn't gone through QA? I've been through that dance before too, and that one's not great.
CHRIS: I like the way you're framing the different sort of trade-offs that we have there in velocity or deployment speed and ease of iteration versus confidence as things are going out. I have worked with a staging branch before, and I personally did not find it to be valuable. It ended up adding this indirection. Folks had to know how to use Git in a pretty deep way to be comfortable with that just as a starting point. So it already introduced this hurdle of knowledge, and then beyond that, that idea that you have commits going in in a certain order on the staging branch. But then say we verify the functionality of the third commit in that list, and we want to cherry-pick it across to the main branch. Commits don't actually...you can't just take the thing that you had there. That commit existed in the context of all the others. There are subtleties of how history exists in Git. And I would worry about those edge cases where you're taking a piece of work out of the context of the rest of the commits that were around it or before it is, more importantly…that preceded it in the history on the staging branch, and you're now bringing it across to the main branch. Have you now lost something that was meaningful?
Ideally, you would get a conflict if it was really bad, but that's more of like a syntactic diff level thing. It's not a functionality-level thing. So personally, I may be overly cautious around this, but I really like as much as possible to have the very boring linear history in Git and do everything I can such that work happens on feature branches and then gets merged in as a fast forward into the main branch or rather the main branch is fast-forward marched into my feature branch such that I'm never working with code that I haven't fully worked with in an integrated way before. But again, even that, as I'm saying that, I have this topological map of Git in my head as I'm saying all of that, and it's complicated. And having any of that complexity leak out into the way we talk about the work is something that I worry about, but maybe I'm worried about a bunch of things that don't matter. Maybe a staging branch is actually fantastic.
STEPH: I think you make a lot of good points. Those are a lot of good concerns that come up with...it comes back to the idea that we want to mimic production as much as possible, and we don't want to lose that parity. So then, by having a staging branch, then it feels that we've lost that parity. There could be stuff that's in staging that's not in production. And so staging could be a little bit of this Wild West area, and then that doesn't fully represent then what's going to production. So I certainly understand and agree with those points that you're making. And to speak specifically to the Git challenges, I agree. It does require some more Git knowledge to be able to make that work. Specifically, I think how we handled it on a previous project is where we'd actually cherry-pick our commits into staging and then deploy that. But we always had the PR issued against main. So then merging into main was often a bit easier.
But then you're right; things could get out of sync. And the PR is issued against main, so then you still could run into those oddities where then if you are cherry-picking commits in the staging, but then you have your final draft that's going into main. And then what are the differences between those, and what did you lose along the way? And as I say all of that out loud, I definitely understand the Git concerns. And I don't know; I just feel like there's not a great answer then here, which is shocking to me. I've been doing this for a while, and yet here I am feeling like there's not a great answer to this very vital part of our workflow. And I'm surprised even though that we do have a delayed QA process that this still feels like a painful thing to figure out how do we have a continuous deployment workflow even though we do have that delayed QA process?
CHRIS: I think somewhat fundamentally your comment there of "I'm surprised that we don't have a good answer to this is," I'm not surprised, I guess, is my reaction. I don't want to go to the software is bad and broken, and we don't know anything end of the spectrum. But I don't feel like we have great answers to a lot of the things about development. I feel like software is more broken than it should be. It costs more to develop. It is difficult. It's hard to create, and maintain, and build over time. And that's just, to get lofty about it, that's what the entire focus of my career is, is trying to solve that problem. But it's a big, hard problem that I do not think is solved, unlike just about any of the fronts. I know how to put stuff in a database and take it back out. And even that, I'm like, oh yeah, but what if the database gets really big? Or what if the database...everything has complexities and edge cases.
STEPH: [laughs]
CHRIS: And we've joked a handful of times about the catchphrase of The Bike Shed being it depends, and that really feels true, though. I don't know that that's unique to this industry either. I feel like everything in the world is just more complicated the more you look at it, and there aren't clear, good, obvious answers to just about anything in the world, but that's the human condition. I got weirdly philosophical on this, so we should probably round this out. [laughs]
STEPH: Well, I can circle us back because I was providing context, and I went a bit into the deep end providing all of that context. So if I circle back to what I wanted to share with you around deploys and releases, there has been that interesting conversation. Now that we have the context, there has been that interesting conversation around originally; we had this very structured deploys, a deploy map to the fact that features were going out to the world. And now we have this concept of a deploy doesn't necessarily mean that's available to customers. It doesn't mean that the code is running. It is more a deploy represents that we have placed a commit. We have placed code on the server. But that doesn't mean that it is accessible to anyone because it's probably hidden behind a feature flag.
But from the perspective of the rest of the team that then is communicating these changes out to customers, they still really need to know, okay, when is something actually available to customers? And we kept using this terminology around deploy. And so Joël Quenneville, another thoughtboter who's on this project with me, has done a lot of great, thoughtful work around how can we help them know when something is truly available versus when something is deployed? Because right now, we're using Jira for our ticket issue tracking. And there's a particular screen in Jira that was showing what's being deployed. And from that screen, you can see the status of the ticket, and you would see stuff like in code review, in QA. So, of course, those looking at the tickets are like, hold up, you're deploying something that's in QA? That sounds really dangerous and risky. Why are you doing that? And then we'd have to explain, well, we're deploying it, but it's not actually live or accessible to anybody, but we want to get close to that continuous deploy cycle.
So we have shifted to using the terminology of a release. So a deploy is more for the we're putting the code on the server and then release really represents okay, we have now released these features and these bug fixes, and they're now available all with the goal just to make sure that our teams are working well together. But it's been such an interesting conversation around how tickets move, the fact that they can progress linear and then also get moved backwards. But in continuous deployment, things don't go backwards and then making those things align. Typically, things don't go backwards. Technically, yes.
CHRIS: History is a directed acyclic graph that only points forward. The arrow of time is very clear on this matter. Yeah, that really does add one more layer of like; what does it mean to actually be out there in the world? I do wonder if giving view-only visibility to the feature flag dashboard and only when it's fully green does someone think that that's deployed? But if you're putting feature flags around everything, there's complexity. And yeah, it's just one more layer to having to manage all of this. And it sounds like you've gotten to a good place, or at least you're evolving in a way that's enjoyable. But yeah, it's complicated.
STEPH: Yeah, it definitely feels like we're moving in the right direction and that this will be a better...I want to say workflow, but it really focuses more around vocabulary and some of the changes to our processes and how we surface tickets in Jira. But it's more focused on how we talk about the changes that are getting shipped and when they're available. So, yeah, that's my story. What's new in your world?
CHRIS: Well, I very much appreciate your story. In my world, I am in the thick of the MBP initial drive to get something into production, which is one of my favorite times, especially if everyone's in agreement about what exactly do we mean by MVP? Who are the users going to be? What's it going to look like? What's the bar that we're going to maintain? What features can we drop? What can't we drop? When there's a good collaborative sort of everyone rowing in the same direction set of conversations around that, I just love the energy of that time. So I'm happily in that space hacking away on features building as much as I can as quickly as I can. But as part of that, there are a lot of just initial decisions and things that I have to wire up and stuff that I have to change or configure. Thankfully, Rails makes a lot of that not the case. I can just go with what's there and be happy about that.
But there is one thing that I did decide to change just today. But it's interesting; I don't think I've actually ever made this change before. I'm sure I've worked on an app that had this configuration, but typically, a Rails app will store the session in a cookie. So there is a signed HTTP only encrypted. I think those are all the things, but it uses a cookie to store that. And the actual data of the session lives in the payload of that cookie. And so, each time there's a request-response lifecycle, the full payload of that cookie is going up and down from the server to the client and then back and forth with all of the requests. And there's a limit; I think it's 4k is the limit on the cookie session.
But there are some limitations to cookie sessions as far as I'm coming to understand them; one is the ability to do replay attacks. So if someone gets a hold of that cookie, then unless you rotate the secret key base, which will have some pretty wide-ranging effects on your application, that cookie can be reused in the future because it basically just has like, this is the user's ID. There you go. And there's no way to revoke that other than rotating the secret key base. Additionally, there are just costs of that payload of data, especially if you're putting a non-trivial amount of stuff. Like, if you're getting close to that 4K limit, then you have 4K of overhead, both on the request and the response of your HTTP requests. So especially in apps that are somewhat chatty and making a bunch of Ajax requests or doing different things, that's some weight that you should consider.
So all of those mixed together, more so on the security side, I decided to look into it. And I have now switched from a cookie store, and I went all the way to the ActiveRecord database store. So I skipped over...there's a middle option that you can do with Memcached or Redis. We do have Redis in this particular application. We don't have Memcached yet; we probably will at some point. But you can do a memory store, so do Redis and store the session there, but I opted to go all the way to the database. And my understanding of the benefits here are we have a smaller cookie footprint, so smaller overhead on all the requests because now we're only sending the session ID. And then that references the actual payload of data that's stored in the database. We do have the ability now to invalidate sessions, so we can just truncate that table if we just want to sign all the users out and reset the world, which can be useful at times.
We also have the ability...if there's any particular user that's like, "I left myself logged in somewhere," we can…well, I actually don't know how to do this now that I say that. I don't know how to log out a specific user because the sessions don't inherently have the user associated with them. You can have an unauthenticated session, which then transitions to be authenticated when someone signs in, and then the user ID gets installed in there. I would love to have these indexed to users such that I could invalidate and have a button on the admin dashboard that says, "Sign out all instances," and that will revoke all of the sessions or actually delete them from the database table now. I think I would have to add some extra instrumentation to do that. So anytime a user signs in via device, we annotate the session records so that it's got a user ID column and then index on that so that we can look them up efficiently. I think that's how that would work, but that's one of those things that I'm like; I think I should think very hard about this before I do it. It has security implications. It's not part of the default package. There's probably a reason for that. I'm going to do that another day.
But yeah, overall, it was a pretty easy upgrade. I think I'm happy with it. It feels like one of those things that it's not clear to me why this isn't the default sort of thing where SQLite is often the database that you use just because it's slightly easier to get up and running? But for any application that we're working on, we're like, no, no, no, we're going to go to Postgres for local development and for everything because obviously, that's what we want to do. And I'm wondering if this should be in that space, like yeah, of course, the session should go in the database. There are so many reasons that it's better that way. I'm wondering if there are some edge cases that I'm not thinking about, but overall it seems cool. Have you ever worked with an alternative to the cookie store?
STEPH: I'm thinking back to the recent projects that I've worked on. And it's been a while since I've mucked around with session work specifically. And the more recent projects that I've been on, we've used JWTs, or they're pronounced jots, I found out, which is really surprising. I don't know why, but that's a thing.
CHRIS: What?
STEPH: [laughs]
CHRIS: This doesn't feel true.
STEPH: It's JWT, but it's pronounced jot, J-O-T.
CHRIS: I think I'm just going to not do that. This is a trend I'm not going to get on board with. [chuckles]
STEPH: I don't even know if it's a trend. I'm not sure who decreed this into the world.
CHRIS: You're familiar with the great internet war around GIF versus JIF, right? I think there's room for different opinions.
STEPH: I mean, it's really not a war. There's a correct side.
CHRIS: We're on the same side, right?
STEPH: [laughs] And this is how The Bike Shed ended. No, this is perfect for The Bike Shed. What am I talking about?
CHRIS: This is perfect for The Bike Shed. I'm just going to need to hear you say the word real quick. [chuckles]
STEPH: Oh, it's GIF, absolutely,
CHRIS: Okay. All right, phew. Steph, I was worried, I was worried. Also, anyone out there that says JIF, it's fine. These things don't really matter. Although I am surprised when you have an acronym that gets turned into...I think it's an initialism, like jot versus JWT. I forget which is which. I think JWT would be the acronym. But jot, that's not even...I'm going to move on and say...[laughs] And so I think that JWTs, which is what I'm going to call them in this context, are, as far as I understand it, an orthogonal, different sort of thing. Like, you can put a JWT in the session, and the session can be stored in a cookie or in the database or wherever. You can also put JWTs...often, they are in local storage, which my understanding is that's a bad idea. That is a security vulnerability waiting to happen from cross-site scripting, I think, is the one that is coming to mind. But I think that's an independent thing where JWT is this signed assertion that you are someone. But it's coming often from an external system versus I'm using devise in this case on a Rails app and so devise is using the warden session, which is signing and encrypting and a bunch of stuff that I'm not thinking about. But it's not using JWTs at the end of the day. Jot, really, huh?
STEPH: [laughs] I like how that's the thing that stuck out to you.
CHRIS: Of course it is.
STEPH: But it's fair because it did the same to me too, so I had to share it. [laughs]
CHRIS: This is The Bike Shed, after all. [laughs]
STEPH: So, going back to your question, what you've done sounds very reasonable to me, especially because you wanted to address that possibility of a replay attack. So I like the idea. I'm also intrigued by why it's not the default. What's the reasoning there? And I'm trying to think of a reason that it wouldn't be the default. And I don't have a great answer off the top of my head. Granted, it's also been a while since I've been in this space. But yeah, everything that you've done sounds really reasonable. I like it. I also see how being able to sign out a specific user would be really neat. That seems like a really nice feature. I don't know how often that would get used, but that seems like a really nice thing to be able to do to identify a particular user if they submitted and, I don't know, if some scenario came up and someone was like, "Help, please sign me out," then to have that ability. So I'll be intrigued to hear how this advances if you still really like this approach or if you find that you need to change back to using Memcached or the cookie store.
CHRIS: Yeah, I'm in that space where as I'm looking at it, I'm like, I only see upside here. I guess there's a tiny bit of extra complexity. You have to watch that database table and set up a regular recurring job to sort of sweep old sessions that haven't been touched in a while because this is sort of like an append-only store. Every time someone signs in anew, they're getting a new session. So over time, this database table is just going to grow and grow and grow. But it's very easy to stay on top of that if you just set up a recurring job that's cleaning them. It's part of the ActiveRecord session store is the name of the gem. It's under the Rails namespace or the Rails GitHub organization. So that seems manageable. Maybe that's the one complexity is it has this sort of runaway trait to it that you have to stay on top of, whereas the cookie-based sessions don't. But yeah, I'm seeing a lot of upside for us, so I'm going to try it. I think it's going to be good.
I'm also unfortunately in that space where I think I see all the moving parts as to how I could implement the sign out a user in all of their sessions. But I'm worried that I'm tricking myself there. It's one of those things it's like this feels like it would be built in if it was that straightforward, or it could easily have subtle...it's like, don't invent your own crypto. Like, I think I know how crypto algorithms work. I can just write one real quick. No, don't do that, definitely don't do that. And this one, it seems clear enough, but it's still in the space of crypto security, et cetera, that I just don't want to mess with without really thoroughly convincing myself that I know what I'm talking about. So maybe six months from now, I will have talked myself into it. Or if anyone out there is listening and knows of a good founded, well-thought-out version of yeah, this is totally a thing that we do; here’s what it looks like; I would love to hear that. But otherwise, I'll probably just be happy with the ability to wipe everyone's session as necessary. If any one user leaves themselves logged in at a library and needs me to log them out, I'll just log out every user. That's fine. That's a good enough solution.
STEPH: Yeah. All of that makes sense. And also, the part that you highlighted around that there is that additional work of where then you have to make sure that you have a rake task that's running to then sign people out since there's that additional lift that you mentioned. But I'm excited to hear what folks have to say if they're using this approach and what they think about it. It is super interesting.
CHRIS: Well, yeah, I am very excited about this new development and the management of sessions. And I will let you know if I make any headway on the signing out a user sort of thing. But I think that covers that topic. As an aside, I just wanted to take a quick moment to ask folks out there; we are getting to the bottom of our listener question queue, and we absolutely love getting listener questions. They really help us find novel things to talk about that whenever we start talking about them, it turns out that we have a lot to say. So please do send in any questions that you have. You can send them to hosts@bikeshed.fm. That's an email option. You can tweet at us; we're @bikeshed, or either of us individually. I'm @christoomey.
STEPH: And I'm @SViccari.
CHRIS: And we also have a Google Form, which we will link in the show notes of this episode. So any of those versions send us questions. It can be about more tech stuff, more process stuff, more team-building, really anything across the spectrum. But we really do love getting the questions in, and definitely helps provide a little bit more structure to the show. So, with that aside, Steph, what else is going on in your world?
STEPH: Yeah, I love when we call from our listener questions, for the reason that you highlighted because it often exposes me to different ways of thinking in topics that I hadn't considered before. And you're right; we’re often very opinionated souls. [laughs] And along that note, so I have a question for you. The context is another developer, and I ran into a bug. And when we initially looked at the bug, it was one of those there's no way. There's no way the code is in this state. That does not make sense. And then, of course, it's one of those well, the computer says otherwise, so clearly we're wrong. We just can't see how the code is getting to this place. And what was happening is we were setting a value. We were parsing some JSON. We're looking for a value in that JSON, and we're using dig specifically in Ruby. So if it's the JSON or if it's a hash, and then we're doing dig, and then we're going two layers deep. So let's say we're going foo and then bar, and then dig; if it doesn't find those values, instead of erroring, it's just going to return nil. And then we have an or, and then we have a hard-coded string.
So it's like, hey, we want to set this attribute to this value. If it's the hash, then give us back that value; if not, it's going to be nil, and then give us this hard-coded string. What we were seeing in the actual data is that we were getting an empty string. And initially, it was one of those; how are we possibly getting an empty string when we gave you a hard-coded string to give us instead? And it's because empty strings are truthy. When we were performing the dig, it was finding both of those values, but that value was set to an empty string. And because that evaluates to truthy, we weren't getting the hard-coded string, and then we were setting it to an empty string, and then that caused some problems. So then my question to you is should we have truthiness in our code?
CHRIS: Oh wow. That's a big question. It's also each language I might have a slightly different version of my answer. Yeah, I'm going to have to go sort of across languages to answer. I think in Ruby, I have generally been happy with Ruby's somewhat conservative implementation of truthiness. Yeah, anything that isn't nil false...is that it? Are those the only falsy values? There's maybe one more, but zero is not a falsy value. Empty string is not a falsy value. They're truthy, to name it in the affirmative. And I like that Ruby has a more conservative view of what things are. And so it can have this other surprising edge. I will say that I do reach for present? in Rails, so present? Present with a question mark at the end, that method in Rails, which I pronounce as present, huh?
STEPH: Which is delightful, by the way.
CHRIS: Well, thank you. That method I reach for often or presence would be the variant in this case where you can presence or and then chain on the thing that you want, and that gets the value. It will basically do the thing that you want here. And so, I do find myself reaching for that, which does imply that maybe Ruby's default truthiness is not quite what I want. And I want a little more permissive truthiness, a little more like, no, empty strings are not truthy. Empty string is an empty value, so it is empty. But yeah, I think I can always convince myself of the other argument when I'm angrily fighting against a bug that I ran into, and I'm surprised by. Like, I've experienced this from both sides many times in my life. I will say in JavaScript, I am constantly surprised by the very, very permissive type coercion that happens where you compare a string and a number, and suddenly they're both strings, and they get smashed together. It's like, wait, how is that ever the thing that I would want? And so JavaScript's version feels like it is definitively foundationally wrong.
Ruby's feels like it's maybe a tiny bit conservative, but I like that as a default and then Rails building on top of that. I think I lean towards that most of the time. I will say at the other end of the spectrum, I've worked with Haskell, and Haskell has I want to say it's like a list of chr, like C-H-R list of characters as the canonical way to do strings. I may be mixing this up. It may be actually the string type, but then there's also a text type, and they're slightly different. Maybe it's UTF. I forget what the distinction was, but they both exist, and they are both often found in libraries and in code. And you end up having to constantly convert back and forth. And there are no subtle equivalents between them or any type coercion between them because it's Haskell, and there isn't really any of that. And this was early on.
I never got particularly far in Haskell, but I found that so painful and frustrating. It was just like, come on; they’re like strings. Please just do the thing. You know what I mean. And Haskell was like, "I do not. And I require you to be ridiculously specific about it." So that was sort of the high end for me of like nope, definitely not that JavaScript of like anything's anything and it's fine. That feels bad. So somewhere in the middle, Ruby feels like it's a happy in the middle. Maybe Rails is actually where I want to land, but I don't know that there is a good answer to this. I don't know that there's a language that's like, we got it. It's this very specific set of things. It's truthy, and these are falsy, and it's perfect every time. Like, I don't think that can happen.
STEPH: As an aside, I like how your Haskell voice had the slight air of pretension that really resonated with me. [laughs]
CHRIS: I don't know what you're talking about. That doesn't sound familiar to me at all. [laughs]
STEPH: I agree. I don't know that anyone has gotten this perfect. But then again, I also haven't tried all the languages that are out there, so I don't feel like that's really a fair statement for me to make either. Specific to the Ruby world, I do think Boolean coercions are a bit nice because then they do make certain checks easier. So if you are working with an if statement, you can say, "If this, and then do that, else, do this." And that feels like a pretty nice common idiomatic flow that we use in Ruby but then still feels like one of those areas that can really bite you.
So while having this conversation with some other thoughtboters, Mike Burns provided a succinct approach to this that I think I really like where he said that he likes the use of truthy and falsy for if statements, Booleans for the and statement, and only truthy falsy for Booleans, so no nulls. So Boolean should not have three states is what that last part is highlighting. It should be just true or false. And then if we're working with the double ampersand and in Ruby, that then if you have that type of conditional that you are conveying, then to use a strict Boolean, be more strict and use the methods that you were referring to earlier, like empty and explicitly checking is this an actual...like turn it into a Boolean instead of relying on that that truthy falsy of is it present? Is it an empty string? Does that count? But then, for the if statements, those can be a little more loose.
And actually, now that I'm saying it, that first part, I get it. It's convenient, but I still feel like bugs lie down that path. And so, I think I'm still in favor of being more explicit. If I really care if something is true or false, I want to call out explicitly. I expect this to be true or false versus relying on the fact that I know it will evaluate, although I'm sure I do it all the time, just because that's how you often write idiomatic Ruby. So I'm interested in watching my own behavior now to see how often I'm relying on that truthy, falsy behavior, and then see the areas that I can mitigate that just because yeah, that bug is fresh in my mind, and I'd like to prevent those bugs going forward.
CHRIS: I really liked that phrase of that bug is fresh. So that bug is going to own a little bit more mindshare than that old bug that's a bit stale in the back of my brain. I will say as you were talking about idiomatic Ruby, I think you're right that the sort of core or idiomatic way to do it would be if the user or whatever to see is the user here, or are they nil? Did we find one, or did we not? That sort of thing is commonly the way it would be done. I almost always write those as if users are not present? I will convert it into that because A, I'm writing Ruby, and I write Ruby because I want it to sound like the human words that I would say. And so I wouldn't say like, "If user," I would say, "If the user is present, then do the thing." And so I write the code to do that, but I also get the different semantics that present? Brings or blank? Is the counterpart, the other side of it. That seems to be the way that I write my code. That's idiomatic me, Ruby, and I don't know how strongly I hold that belief. But that is definitely how I write those, which I find interesting in contrast to what you were saying.
The other thing that came to mind as you were saying this is that particular one of an empty string. I kind of want to force empty strings to not be okay, particularly at the database level. So I'll often have null false on a string column, but then I'll find empty strings in there. And I'm like, well, that's not what I meant. I wanted stuff in there. Database, I want you to stop it if I was just putting in an empty string because you're supposed to be the gatekeeper that keeps me honest. And so I do wonder if there is a Postgres extension that we could have similar to the citexts, citext, which is case-insensitive text. So you can say, "Yeah, store this as it is, but whenever you compare it, compare case-insensitively," because an email is an email. Even if I capitalize the third letter, it doesn't make it a different email. I want a non-empty text as a column type that is both null false but also has a check constraint for an empty string and prevents that.
And then similarly, the three-state Boolean thing that you're talking about, I will always do null false on a Boolean column because it's a lie if I ever tell myself. I'm like, yeah, but this Boolean could be null, then you've got something else. Then you've got an ADT, which I also can't represent in my database, and that makes me sad. I guess I can enum those, but it's not quite the same because I can't have additional data attached. That's a separate feeling that I have about databases. I'm going down a rabbit hole here. I wish the database would prevent me from putting in empty strings into null, false string columns. I understand that I'm going to have to do some work on my side to make that happen, but that's the world I want to live in.
STEPH: I'm trying to think of a name for when you have a Boolean that's also a potential null value. What do you have? You have nullean at that point?
CHRIS: Quantum Boolean.
STEPH: Quantum Boolean. [laughs]
CHRIS: Spooky Boolean.
STEPH: The maybe Boolean?
CHRIS: Yeah.
STEPH: No, that's worse. [laughs] Yeah, I'm with you. And I like the idiomatic Ruby. I think that is something that I would like to do more of where I'm explicitly checking if user instead of just checking for that presence and allowing that to flow through doing the present check and verifying that yes, we do have a user versus allowing that nil to then evaluate to falsy. That's the type of code that I think I'd like to be more strict about writing. But then it's also interesting as I'm formulating these ideas. Is it one of those if I'm reviewing a PR and I see that someone else didn't do it, am I going to advise like, hey, let's actually check or turn this into a true Boolean versus just relying on the truthy and falsy behavior? And probably not. I don't think I'm there yet. And I think this is more in the space that I'm interested in pursuing and seeing how it benefits the code that I'm writing. But I don't think I'm at the state where then I would advocate, at least not loudly, on other PRs that we do it. If it is, it'd be like a small suggestion, but it wouldn't be something that I would necessarily expect someone else to do.
CHRIS: Yeah, definitely the same for me on that, although it's a multi-step plan here, a multi-year plan. First, we say it on a podcast, then we say it again on a podcast, then we change all the hearts and minds, then everyone writes the style, then we're all in agreement that this is the thing that we should do. And then it's reasonable to bring up in a pull request, or even then, I still wouldn't want it. Then it's like standard rb or somebody else's job. That's the level of pull request comment that I'm like, really? Come on. Come on.
STEPH: This is a grassroots movement for eradicating truthiness and falsyness. I think we're going to need a lot of help to get this going. [laughs]
CHRIS: Thankfully, there are the millions of listeners to this show that will carry this torch forward, I assume.
STEPH: Millions. Absolutely.
CHRIS: I'm rounding roughly a little.
STEPH: There are a couple, yeah. [laughs] I'd be far more nervous if I knew we had millions of people listening.
CHRIS: I kind of know that people listen. But at the same time, most of the time, I just entirely forget about that, and I feel like we're just having a conversation, which I think is good. But yeah, the idea that actual humans will listen to this in the future is a weird one that just doesn't do good things in my head. So I just let that go. And you and I are just having a chat, and it's great.
STEPH: Yeah. I'm with you. And just to reiterate what you were saying earlier, we love getting listener questions. So if there's anything that you'd like to send our way and have us to chat about or something you'd like to share with us, then please do so. On that note, shall we wrap up?
CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm.
STEPH: This show is produced and edited by Mandy Moore.
CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes, as it really helps other folks find the show.
STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @bikeshed or reach me on Twitter @SViccari.
CHRIS: And I'm @christoomey.
STEPH: Or you can reach us at hosts@bikeshed.fm via email.
CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeeeee.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success._Support The Bike Shed

Jul 13, 2021 • 45min
300: Mozzarella Sticks & Knowledge Silos
The big "Three Oh Oh!" What a milestone for this podcast! Aside from celebrating that the show has made it this far, Chris gives some followup on some Inertia.js issues he had been having, and talks about open source licenses and legality and testing against external APIs. Steph has thoughts on mozzarella sticks and what makes good ones; particularly the cheese to bread ratio...
They then, together, answer a listener question re: knowledge silos:
Jan asked, "Our team (3 pairs) is currently working on two different projects due to that fact we are creating information silos. Now we are looking into ways how we can minimize those information silos. Do you have any ideas how we could achieve this?" With switching pairs they are unsure about it as it can be difficult for new pairs to get up to speed.
inertia-rails thread safety
Rails Cache-Control no-store fix
Transcript:
STEPH: I have no shame.
CHRIS: That's important in this industry.
STEPH: [laughs] Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari.
CHRIS: And I'm Chris Toomey.
STEPH: And together, we're here to share a bit of what we learned along the way. Hey, Chris. So today's an exciting day. It's a rather momentous day, at least in my world, because today is our 300th episode.
CHRIS: 300? That is incredible.
STEPH: That's an incredible amount of episodes. And it made me pause and reflect on how many episodes I have been a part of. And I've realized it's over 100. I think it's around 104 or something like that, and I can't believe it. Time flies when you're behind the mic.
CHRIS: Time does fly, yeah. So yeah, fully a third of these you've been involved in. I don't know what the number is. And I'm just so grateful to Derek Prior and Sage Griffin, who started this whole process. And then to Thom Obarski, who was the producer for so long, and Mandy Moore, who recently joined us and has been doing a wonderful job of carrying that forward and to you, Steph, because this has just been such a joy to work on. Yeah, it's just a joy to be on the show and to get to chat with you each week and share some things. And frankly, learn from folks writing in questions and sharing pointers with us, and it really is such a delight. And yeah, 300 is pretty momentous.
STEPH: The listener questions and feedback have undoubtedly been a highlight for me. That is one of the areas that I love the most. I love the questions. I also love when people provide helpful answers to us, and then they help us out in return and also, all the incredible guests that we've had on the show. It has been phenomenal. I'm also very thankful to have been part of this journey and appreciate everyone that has got us here today. I wonder what the fourth iteration of The Bike Shed looks like. I consider this the third iteration because the first iteration was Sage Griffin and Derek Prior. The second iteration was where you took over The Bike Shed, and then you were hosting a number of incredible guests on the show. And then the third iteration is the iteration that we're living, so I wonder what the fourth will look like.
CHRIS: Oh, that is an interesting question. Hopefully, you and I get to hang out for a good bit longer. But at some point, much like the Green Lantern, this will get passed on, and someone else will take up the mantle and tell some stories. But, yeah, hopefully, that's not too soon because I certainly enjoy hanging out with you.
STEPH: Oh, I agree. I certainly enjoy this, and I'm in no rush to leave The Bike Shed. But I think it's just fun thinking about the next people that will carry this journey forward.
CHRIS: And determine the color of The Shed.
STEPH: And determine. I mean, that is their right. As host and co-host, they get to determine the color of The Shed.
CHRIS: 300 episodes in, and we still haven't figured it out. So I guess we got to keep trying.
STEPH: Oh, I have. I already know what color it is.
CHRIS: Is it yellow?
STEPH: It's yellow.
CHRIS: Yeah. Okay. [laughs]
STEPH: I like how we said yellow at the same time, you know. [laughs]
CHRIS: I do, although I feel like it's wrong to have a color in mind, or at least I want to dig in and talk about it for a while just to be in keeping with the show, but...
STEPH: One must first argue before deciding and then argue again. But to not continue bikeshedding on The Bike Shed, what's new in your world?
CHRIS: My week has been good. Actually, I have two quick updates on various Inertia things that I've shared in previous weeks. So we can include a show notes link for the two different episodes where I talked about these respective things. But there was one weird issue that I ran into with Inertia where it could start clicking a button that would delete, was behaving weirdly and occasionally, intermittently; some of the responses would end up as a full HTML page response as opposed to the expected Inertia response. And there's a bunch of subtlety around this. I actually reported it as an issue to the Inertia team. And they very kindly pointed me to the HTTP semantics at place. So it's the difference between a 302 redirect and a 303 redirect. And so, in their code, they were correctly doing a 303. They were standards-compliant; everything was great. But for some reason, it was still misbehaving sort of randomly, and I could never pin it down. I ended up working around it and opting out of Inertia behavior for those endpoints. But my assumption was that something in my Rails Middleware Stack was behaving weirdly and occasionally overriding Inertia Rails' setting of the status. So Inertia Rails was saying, "303," which is a special version of redirect, and something else in the Rails Middleware Stack, was saying, "302, it will be fine."
Turns out, in retrospect, the Inertia Rails team has discovered that this was, in fact, a threading bug on their side. So it's not Inertia's fault. Inertia as a core concept and as a protocol was definitely doing the right thing. And the Inertia-Rails Middleware was attempting to do the right thing. But threads and concurrency got in the way, which I'll be honest, I don't deeply understand those concepts. So I was just like, oh okay, that sounds like a thing that could go wrong occasionally, which is exactly how I experienced it. But now they've made an update to the project, so that should be resolved in a deep way. But goes to show you threading and concurrency are really tricky to chase down.
STEPH: I appreciate that you're coming back to give us the conclusion to that issue because I remember talking about it, and you were still going off on a journey and finding out what's wrong, so that's super interesting. And yeah, threads and concurrency those are super easy, like cache invalidation and naming, that's right up there.
CHRIS: It's actually kind of funny. One of the issue threads where I wrote about it, someone followed up and asked if I'd come to any solution. And I said, "Oh, I've gone kind of this weird way, and I'm doing these things." But I shared a code sample, and I said, "Just to be clear, this is 100% about something Rails is doing and not Inertia, which remains a stellar project." And then, very shortly after that, someone from the Inertia-Rails team was like, "Ah, actually, I think it was us. Sorry about that, but we fixed it now." And I was like, "I still love you guys. This is great. You're doing a great job. [chuckles] You continue to push the envelope in a wonderful way." But it was a funny interaction where I was like, never shall I let the name be dragged through the mud. Whoops. Okay. Never mind.
STEPH: You're an excellent hype man for Inertia.
CHRIS: I try, I really try. I believe in it to my core. And actually, there's another one that this one's not really related to Inertia at all, although I've seen it discussed within the context of Inertia. And again, I think the Inertia team has done a really great job of responding and pointing to here are the HTTP semantics, and adhering to the standards, and the way that things should work. But this one has to do with the back button. When you're doing sequential forms or really any sort of form type thing, the browser will just pull from its back/forward cache, which is a local cache of the HTML of the page as it just had it. And I had come to the understanding that this was not something that I could workaround. This was not something that I could control. I had tried every combination of headers, at least I thought I had, in Rails to try and control this from the server-side because ideally, the server is the one who knows about when data is changing and things of that nature. The server should be able to inform the browser, "Hey, don't cache or store this page in any way, always revalidate it."
It turns out there was a bug in Rails that was improperly normalizing the Cache-Control header and always removing the no-store Cache-Control value. So there are like five different or a handful of possible values that can be set for that header for the Cache-Control header. And Rails has a bunch of internal logic that says, "Okay, if you've set this, then I'll put these two, but not that one." And they're just trying to manage it and do nice things on our behalf. But unfortunately, they were being a little overzealous in that normalization effort. And so they were dropping an important value, which is no-store. So now there's a PR opened in Rails, or I think it's actually been merged in at this point that will fix that and allow you to set that particular header value, which then should get the behavior of "Hey, browser, if I hit the back button, please go ask the server. Don't trust your local cache, “which is exactly what I want.
STEPH: Interesting. Wow. So that's two very helpful resolutions to some of those strange issues you were running into before.
CHRIS: Yeah, definitely. And actually, for that issue, in particular, it was a very kind Bike Shed listener; Alexei Vasiliev wrote in and shared some initial thoughts, pointed me in the direction of some things. In that case, I actually was like, "I don't think that's the case. I tried it." And he was like, "No, no, no, pretty sure." And he was definitely correct in this case and was very kind and gave me an example of code reproduction and all of those nice things. So I was able to chase this down and then eventually find the issue in Rails, which had been opened like eight days before. So I think for me, I just happened to run into a weird period of time where Rails was subtly broken around this behavior. And therefore, I determined that the world was broken when, in fact, it was just a tiny slice of Rails' history. But yes, thank you so much, Alexei, for writing in and pointing me in the right direction on that.
STEPH: The dream came true. We talk about some of our troubles and our strifes, and people respond and help us out.
CHRIS: That is the dream. But yeah, so those are some quick updates, not really about me, although tangentially, I got to go along for these rides, and it was fun. But what else is up in your world?
STEPH: Let's see. Well, I also have a small update that I can share. It's circling back to the conversation that we had talking about extracting an untrustworthy service to a new location. And at that time, I don't remember exactly the process I laid out. But at that time, it’s the idea that it is a bit untrustworthy, but we have some security in how this process works, and it is ideal that we move it to this other location. So let's just go ahead and move it wholesale, bugs and all to the new location. And then there, we will start to refine, and we'll start to improve the service. Well, the update is that we have realized that the untrustworthy service is untrustworthy enough that I'm actually working on improving it in its current place just to a certain extent that then it feels like we can move it to another location. There have been enough issues with it that it has taken my focus to continue patching those bugs and making sure everything is working appropriately. But now I'm in the space of where I'm like, goodness, I thought I knew this thing and now I'm realizing I don't. And so, I'm looking for ways to inform myself and the team when something isn't working when we think it is.
So to provide a bit of context, this service is sending a bunch of messages to other systems, and most of the time, that is working, but there are times that it's not. And when it's not working, it's silent about the fact that those messages aren't being sent, and it's very important that we send those messages. So what's been on my mind is looking for a way to then elevate myself and the team to say, "Hey, these are the number of messages that are being sent on average." And then suddenly, let's say it dropped by 50%, or maybe we typically send 98% successful messages, and we have a 2% failure rate, but suddenly we have a 50% failure rate, but looking for those metrics that I can capture and then alert the team if something is going wrong.
And one of the suggestions that was bubbled up by Chad Pytel, who's a developer, he's also founder and COO of thoughtbot, and we're working on the same project together. And he had highlighted that a previous project that he worked on used AWS specifically to leverage the idea of tracking how many successful messages are being sent, or perhaps in their particular project, it was focused on how many orders were being processed. That was important to know. And in our case, we could do a similar metric where we look to see are we still sending messages? Has the number dropped significantly lately so then we can be notified, and then we can escalate that to PagerDuty? So then we notify the team that something's going on.
I don't know the specific mechanics of how I'm going to implement that yet. So I will report back, but I'm excited to have something that's going to alert me for when things aren't working the way I expect versus waiting for then someone that's a customer to notice it and then get back to us. It's very in line with a number of the topics that you've brought to the show recently, talking about how we can measure more of the user's experience and be notified sooner versus waiting for a user to bump into an error and then they reach out and notify us.
CHRIS: I'm super interested to hear where you get with that because that's definitely an area that I've poked at but not dug into particularly deeply. I know there are a number of projects like StatsD is one of them. I think there are others in that space, but that's where you're sending metrics just out to some service, and then you can aggregate and graph. I've also done similar things with Papertrail; I want to say, where you can do a very specific search in the logs, and then within that, you can aggregate and graph and show things over time. So you can do a very simplified version of what you're describing to sort of visualize a rate of something over time. And then I think they might have some thresholding alerts.
But also, that's one of those super hard things to do because it turns out like Monday morning, a lot of emails get sent and then Friday afternoon, fewer, and then on the weekend, none. And so, there's going to be an inherent sort of fluctuation to the data. And so then what is normal? What does the baseline look like? And then how do you do anomalies around that? Because inherently, there's going to be noise in the data. And so is it a 10% band around the normal? And I'm just saying a lot of words now that I barely know the meaning of. But it's one of those things where it's like, oh yeah, just let me know if it's behaving abnormally. There's so much in that one little sentence. And it's one of the like; I love the fractal complexity of this space where every part of that sentence that I just said is like, oh, that's way more complicated than it sounds when you just say that word. So very interested to hear where you get with this. And this is also something that I'll probably be pushing on in my work in the near term. So maybe we can even compare notes, but as of now, I just have, I think, buzzword-level knowledge of it.
STEPH: Well, I love that phrasing fractal complexity because yes, that was also where my brain got hung up in starting to think about this process and like, well, what's normal? I don't actually know what normal looks like because I haven't been tracking this until now. So do I go back a week and say, "Okay, let's compare our average sent rate to in the past week and try to define normal in that timeframe?" And I think the answer, for now, is to do the smallest thing but also has the biggest impact, and that's to notify the team if messages just stop. That feels like the first, small step to take, and then we can fine-tune. Do we want to know if suddenly successful messages are being marked as a failure? We have an increase in failed messages versus successful messages. But I think the first iteration is just to know or to confirm that we are sending messages and send us an alert if suddenly we're not sending messages for...ooh, I just realized there's a complexity in that statement too. It's like, how long are we not sending messages for? Is it for an hour? Is it for a day?
CHRIS: I was going to ask.
[laughter]
STEPH: I just caught myself there. Yeah. I don't have an answer to that right now. I have to think about it, but there's an answer there. I will have to choose an answer.
CHRIS: You sure will. And then you'll probably have to tweak it over time. It's also one of those topics where false negatives and false positives are really easy to fall into where the system's alerting too often. And so people then start to ignore the alerts versus it's too cautious before it will send out an alert and, therefore, you're missing things and so finding that optimum level. It also might be different days of the week. Aah. [chuckles]
STEPH: Yeah, I think that's very true. It will be different for different days of the week. So I have a lot more to think about in regards to how we're going to report on this. But that still feels very much like something I want in the world because right now, it's a lot of spelunking and production consoles to find out what's going on with the data and making sure that it's going through. And that feels like the least favorable option as to the world that I want to live in.
Oh, on a completely unrelated topic, I saw an article that I'm very excited to read. And it's not related to technology at all, but it looks like a very delightful article that someone wrote and titled My 14-Hour Search for the End of TGI Friday's Endless Appetizers. And I haven't read it in-depth yet, but I just read the first bit, and it seems like it's going to be delightful. But I thought of you because we've had previous outtakes around mozzarella sticks. And you were very excited when you thought thoughtbot had mozzarella sticks, the actual fried kind versus just the healthier cheese stick kind. So this seems like a thing that you'd enjoy.
CHRIS: I feel like it may have even ended up in an episode, and we talked about mozzarella wedges and the ratio of surface area to volume.
STEPH: Yes.
CHRIS: I don't know if that made it into an episode or not, but we have definitely you and I discussed mozzarella sticks before. And I'm definitely intrigued by this article. I will add it to Instapaper immediately and then probably never read it again because Instapaper is where I put things to forget them. But maybe someday I'll sit down with a coffee and read things.
STEPH: I've heard you mention Instapaper before, and I've looked into it. And I don't know why, but it just hasn't stuck for me. So I always throw anything that I want to explore or something that is also critical for me to do. I use Todoist. I don't know if you're familiar with that app, but that's my go-to.
CHRIS: Well, I'm familiar with Todoist. I take a slight line between my to-do list, which I want to be as, I don't know, clean and tidy and only the things that I have to do versus for me, Instapaper is a list of when I get around to it when I've got those ten free minutes, which apparently don't exist in the world. But when I have them, this is the list of things that I can read. But I think I've heard this from a number of people of having a more integrated system that all the stuff's in the same place. I keep my to-dos in Trello, also as an aside, and I'm not super happy with that. How do you like Todoist? Is it bringing you joy?
STEPH: I really like Todoist. I find it is simple enough an interface that I'm not spending a lot of time customizing it or messing around with it. I can just go there and log the things that I want. I can create individual projects and spaces as well. So if I want to separate my personal to-do list from my work to-do list or if I have a project, that's a really nice feature as well. I think my only small complaint is if I'm writing a date or if I'm writing tomorrow, Todoist will try to do the smart thing and say, "Oh, I'm going to add a due date for you since you mentioned a date." And I'm like, no, no, no, I don't want a due date. I just want to mention the specific date because somehow it's relevant. And undoing that is sometimes a little tricky. But otherwise, I have found Todoist very helpful. I'm a big fan. Also, you and I are slightly different creatures in terms of how neat and tidy we keep our spaces. I think how we both manage our email inbox is a really good indicator of this where you are more organized than I am when it comes to emails. And so, our to-do list might be similar. I'd be interested to see if Todoist fits your needs or if it doesn't offer enough structure.
CHRIS: I almost certainly could make it work. And it's one of those things where I've actually settled on Trello, which is a very loose tool. And so I've been able to shape it sort of to what I want, but it doesn't really have that many true productivity-type features. It's just a loose board where I can drag around cards and move them through. And that's worked fine, or I've been able to talk myself into not trying to be as neat and tidy and intentional with my to-do list, which I think has been good overall. I've looked at Todoist in the past. And the thing that gives me pause sort of related to what you were talking about with the date things, but I get the idea, or I get the sense that Todoist really, from a fundamental philosophical approach, really wants things to have dates and to have priorities, and my thinking is not quite that. Like, there is a priority, but it's relative. So it's the order of things in a list, but it's not this is a one, and this is a two, and that's another two. I find that logic of like there are different tiers of importance doesn't really map to my world, nor do dates. Almost everything I do has no date, has no context. It's just like when I'm at the computer because that's the only place I ever am. So it's when I'm at the computer, it's all kind of important-ish. Nothing really has a date, but it should probably be done pretty soon. That sort of stuff doesn't quite map to what I see in Todoist. So I've always found a little bit of a mismatch between what I think I want and what Todoist, as far as I understand, provides. I know they added Kanban-type boards recently. So I think that might help with just visualizing workflow and being a little closer to Trello, which I'm familiar with. But I'm sort of on the search right now for another to-do list.
I like what you said about being able to separate the work and personal because that's definitely a thing that I would want, although there's always the added complexity of whatever tracking tool that we're using as a team at work and which things go into my list versus that list. And do I try and synchronize them in any way? And then I do what I do, which is I start to imagine this ridiculously complex, fully integrated, bi-directional sinking nonsense system where like, never mind. Stop it. Pen and paper, Trello. I don't know; you’ve lost your privileges, though. This is me talking to myself. I lose my privileges much like I'm not allowed to ever try Emacs. I have had a multi-year moratorium on exploring new productivity tools, but I think maybe, just maybe, now is the time to revisit that.
STEPH: If you ever disappear for a week or two, I'll know that you tried Emacs or something like that happened
CHRIS: [chuckles] My beard is three times longer when I come back, and I'm like, "All right. I figured some stuff out, though."
STEPH: I'm with you in regards to trying to bucket all of your to-do items as if it's a priority one, two, three. I am not good at that, and I'm always wrong. So I've also given up on that system. I would describe myself as a minimalist user. I'm using all the basic functionality. I'm not leveraging what a lot of stuff that Todoist probably can do for me. And so I have a very just flat list of things that I'd like to do. I do have a couple of projects because I do try to have that personal versus work, and maybe I have some other project that's on there as well. And then, in my mind, I try to avoid due dates unless it's really important. Although I say that if it's really important, it's going on my calendar too because I'm going to budget time for it or make sure that I don't forget it. But then each day then I go through that full list, and then I pick the things that need to be done that day or it's reasonable to get done that day, and then I kick everything to the next day. So that way, I'm always reevaluating a fresh list of what do I need to tackle? What's reasonable for today, and what can I punt on? And Josh Clayton said this to me before, and I really liked it in terms of punting on work because typically, when you're really busy, something's always going to drop. You're always going to push something to the next day. So then it's just figuring out what's going to bounce and what's going to break? So I'm always looking for what's going to break? And let's prioritize that for today to make sure it gets done. If it will bounce, then I'm going to kick it to the next day, and I can't see it until I'm going back through that full list again.
CHRIS: I really like that framing around you're going to have to drop things. That's just the nature of life. There's always more to do than there is time. So will it bounce, or will it break in that? And that framing around how to decide which things get moved out. Interestingly, I just looked up because I wanted to know does Todoist support snoozing things? Which is something that I use constantly in Trello and Gmail and basically everywhere else. I'm just like, nope, future me problem, future me problem, and I just keep pushing things into the future. But critically, I want them to be hidden until that time. And it sounds like Todoist; you can set a future due date, and then it'll show up in today. But again, that's sort of conflating how I think about productivity and whatnot.
Also, I found…this is a Reddit post that I'm looking at where I'm determining this. And there is the question, and then there's someone answered, but the answer is deleted. And then there's someone replying to that saying, "Wow, what a thoughtful response. Have you written this up anywhere else, like a blog post? You sound like an absolute pro." But the parent comment, which apparently was beautiful, and articulate, and well-written, has been deleted. And this is the sadness of the internet. So a really beautiful xkcd about the saddest thing you can see is you search for a question, and you find Stack Overflow from 10 years ago one person asking the question and no answers. And you've got one other person out there in the world who cares the same way you do, but you have no answers, and it's sad. But I'm just sad about the loss of information.
STEPH: That's so tragic, or that's a really pro troll move. And you leave a comment, and then below, you're like, “Wow, that was amazing. That was beautiful.” And then you delete your own previous comment. So then you're just tricking people into thinking there was an answer.
CHRIS: It does sound almost performative, especially the last line, "You sound like an absolute pro." So I could see that being the case. And you know what? I'm going to choose to believe that that's what it is because then I can sleep better at night. So thank you, Steph.
STEPH: Happy to help.
CHRIS: But I think we should probably move on to perhaps a listener question or something. But before we do that, I do want to ask if anyone out there has a to-do list that they're using and they love; I would love to hear about it. I think I'm familiar with most of them, but votes of confidence from the listeners of this show will certainly go a long way with me. Because I think you folks are all very smart people. I mean, you're listening here, so, obviously.
STEPH: Yes, obviously. This very deeply intellectual show about mozzarella sticks and the ratio of cheese to fried and what's the best.
CHRIS: It's an important question.
STEPH: It is an important question. I have strong feelings about it. That's why we've talked about it. [chuckles]
CHRIS: On this very serious show that we host.
STEPH: [chuckles] Yes, we have an awesome listener question that I'm really excited to dive into. But before we do, I have a quick git thing that I'd love to share. It's a tip that Dimitry, another thoughtboter, shared with me today that I think is just really nice and something that I have not used before. And it's specific to a workflow where if you need to grab a file from another branch or from another commit, and then if you want to bring it into your current branch. And there are a couple of ways to go about it. One of them is you can do git checkout main and then pass the file presuming the file that you want is in main and then you want to bring it to your current branch. And that will copy over the file to that exact location.
But if you wanted to grab a file that's on the main branch but then you want to port that file to a new location, then you can use git-show and do git show branch. So let's say you're bringing a file from main over to your current branch, so it would be git show main: and then pass to the file that you wish to copy, and then the greater than sign and the path to where you want that file to live. So you can grab that file and then stash it in a new location, and you can also do it for commits too. So if someone has pushed up a commit and you want to copy a particular file, say if you need to bring in some of their work into your branch, then you could also do git show commit, and then that colon, and then the path to the file. And then, if you wanted to move it to a new location, you can use that greater than sign and then the path to where you would like that file to live. So it's a nice combination of the git command of git show and then also shell redirection. So then, you can pipe that content from the file that you wish to copy over to the new location that you would like. And it's not something that I've reached for very often, but I find lately I've been in a mode where I'm trying harder and harder to stay within my terminal and not have to jump over to GitHub or to external UIs if I can. And so this just feels like a nice additional tool where then I can use this one more thing where I don't have to either...I guess it's small. I could check out main locally. But even with this way, I don't have to switch branches, grab something, and bring it over, or I don't have to go to GitHub and then look for something. It feels like a nice way that then I could grab that file locally and bring it over to my branch.
CHRIS: That's a nice combination of tips there. Like you said, a bunch of different pieces at play, but that is definitely a super useful thing. It's one of those that I've not gotten that into muscle memory yet or even close to muscle memory. Git is complicated in terms of the interface that it provides, at least at the command line. I've been trying to make sense of it all and then trying to find what are the useful workflows that I want to build? Because you can do anything, and you can do most things in five different ways. And so finding that set that you do want to know deeply but then also getting that committed into your hands, not even into your head, is the thing that I strive for. But that particular one is one that I struggle with every single time. So especially, I think you broke that down really nicely, so it makes sense.
There's a corollary in Fugitive for any Vim users out there. There's a Gread command, so it's capital G-re-a-d. And then after that, it takes some identifier, and I've never gotten the identifier right. But as you just described it, it's the same as the git show sequence. So it's a commit or a branch name, colon, and then the file path that you want. And then, in Vim, you can use % to reference the current file. So I've tried really hard to teach my brain Gread main :%, and somehow, my brain doesn't want to remember that ridiculous sequence of characters. So, only in this moment am I like, oh, it all kind of fits together.
STEPH: Oh, that's nice. I am a Vim Fugitive user, but I didn't know that one. And I'm with you; I rarely remember all these off the top of my head unless I've done them like a hundred times, and it finally starts to sink in. So I always have a cheat sheet, or since we were talking about tooling earlier, I use Notion to capture tidbits for myself. So this is a place where I would probably stash in a web development folder that I have. And it's just a tip to my future self as to like, hey, remember when you were trying to do that thing, and then you had to look it up and figure it out? Well, here's how you did it, so then I can revisit it in the future.
CHRIS: I thought a number of times about introducing a flashcard system to revisit these sorts of things. Gary Bernhardt, who I had on a while back now, is building a platform that does this essentially for TypeScript and regular expressions in JavaScript arrays and a bunch of different topics. But it's got built into it the idea of spaced repetition, so you review a thing and then three days later, you review it again and then seven days later, and then ten. And there's a particular sequence to it, but it helps you to really internalize that knowledge. I've never gotten to the level of going to that, but I like that idea of being purposeful and trying to commit some things to memory because having them at your hands and being able to stay, like you said, in the terminal and closer to the work and not having to break out of the context, I do find a lot of value in that. But it does take some effort to build that up. So I've never quite gotten to that flashcard system myself.
STEPH: Yeah, that's interesting. I think I have mixed feelings about it because, on one hand, it is nice to commit some things to memory. And on the other hand, I'm totally cool with having a way to organize stuff so I can easily search it and find it later and not use up memory space for something that I don't use that often that then I just can't commit it. So I could definitely see it being useful. But I'm also okay with just having a nice way to search for it.
But pivoting a bit and circling back to the listener question that you alluded to earlier, we have a listener question from Jen and Jen wrote in about knowledge silos across different projects. Specifically, Jen wrote in "Hello, Steph and Chris, first of all, I want to say that I love to listen to your podcast for multiple years now." That's awesome. Thank you, Jen. "I like how you both share things along your week and fill the discussion with so many useful things and findings. Our team, which consists of three pairs, is currently working on two different projects. And due to that fact, we are creating information silos. Now we are looking into ways into how we can minimize those information silos. And do you have any ideas for how we can achieve this? Some additional context, switching pairs we're unsure about as this will be difficult for the new person to get up to speed. And currently, we are thinking about having a mob review session. But of course, with those, you only get a limited overview." All right. Well, thank you, Jen, for the question. I'm excited for knowledge silos because, I'll be honest, I am guilty of this one right now. I am a bit of a knowledge silo on my current project if we're telling our truths here on the show today.
CHRIS: Steph, I thought I knew you.
STEPH: You know, I'm full of surprises.
CHRIS: Aren't we all at various times? This really does feel like one of those core things that I associate with you, though. So it is interesting. But it's so easy to fall into this space. I think without purposeful, intentional effort, this is the natural way things will trend. It's so much easier for the person who understands a portion of a system or an entire system to take on the next piece of work for that system. And I think we can probably offer some specific advice. But to talk about it more generally, Jen, I think you've found yourself in the pretty common position of there isn't a great answer here. There's going to have to be an investment of some amount of effort; some potentially decreased productivity for a period of time in order to get out of the situation that you're in. But that's just the name of the game. So if we name it as that, and we say that, then the question becomes how much effort do we need to put towards that, and what are the different ways that we can do it?
So to go through the two that you listed, mob review sessions, I think can be a great way to give an introduction to a project, but I think they'll very quickly taper off in my experience. So I think it's a great way, especially if you're going to do any more formal things after that; a mob review or even a mob overview of the system is a great way to introduce new folks into it. But then from there, I personally would think that if you are feeling pain around the knowledge silos or even if you're not, because frankly, knowledge silos can very quickly become a major problem, say if someone needs to...if someone happens to leave the company or if someone needs to take some time off, anything of that nature, this is one of those things that can be fine until it's not, and then it's not in a very serious way, and that's the wrong time to try and resolve it. So I would very much be in favor of more purposeful things.
As you described, switching pairs is an interesting one. I think that's a cost you're probably going to have to pay. I am interested; the way you're talking about it, it sounds like your teams are paired up consistently, so you're working exclusively in those pairs, which frankly is a really interesting thing. I think it was the previous episode where Steph and I talked about agile and particularly 100% pairing, and that's a pretty intense idea. It also does potentially lean towards this. Now, each of those groups of people, each of those pairs is collectively aware of the same subset of the application. But now, if you were to split that up and you have six individuals that pair in varying sets across the different projects, you have this sort of Venn diagram tapestry of knowledge of the different systems and the subsets and the features. And for that reason, I actually would probably question, at least if I'm correctly interpreting it, that you have three consistent pairs; maybe you shuffle that up. Maybe that's a practice that should be unwound. And now the pair should rotate on a daily basis or something to that effect. But overall, I think this is a cost you're going to have to pay but will pay off longer term. And it's definitely worth doing in my mind. But yeah, that's some high-level thoughts. What do you think, Steph?
STEPH: I agree with all of those sentiments very much. And as you're talking about the cost and investing in the team, I think that's very true and something that needs to be done. The fact that they're working in pairs is already reducing knowledge silos because you at least have another person. Because I have been part of teams where there's one person that is that knowledge silo. So at least here, we already have two people that are aware of how code works and then why code was implemented in a certain way. So then, to categorize how painful that knowledge silo is or how risky that knowledge silo is, I think there are really two ends of the spectrum. And on one side, there's that example that you alluded to a little bit ago about isolating one developer on a project for six months, and they have minimal code reviews. And then suddenly that person leaves, and that's the hardest silo to then rectify. And it will probably be a lesson that stings enough that hopefully it won't be repeated where someone gets that isolated and then others have to figure out what was going on while that person was working on something independently.
And then on the other side of that spectrum is you need to take some time to explore and understand a portion of the application that you haven't worked on before, or perhaps it's you need to understand how to work with an internal API. And stuff on that side of the spectrum feels more addressable with documentation and also mob reviews. And maybe there are also demos as well because a lot of the knowledge that goes into building a product may not be specific to the code, but it's more why was this done, and why was it built, and why did we go this way? And that feels more addressable with documentation, with commit messages, with those mob review sessions, and also with demos where then you can show the high-level functionality of a feature that's being implemented. So then, even if everyone else on the team doesn't have the technical knowledge as to how it was built, they'll have more of the user context, and the product context as this is a feature that we built, and this is why it's useful to the world. I find a lot of that knowledge is what's harder to capture because then you'll find a feature and wonder who uses this and how is it in use? And that stuff is harder to backtrack.
Circling back to something that Jen caught out in their question, highlighting that it takes time for someone to get up to speed. That's a really interesting one for me because it goes back to the idea of wanting to know well; what’s difficult? Not specifically what is difficult, but let's define difficult and what's a reasonable level of difficultness because onboarding to any applications or onto a new section of code is always going to take some time to process and understand. But what's an acceptable timeline in which someone can onboard and be productive? There's something that I've heard from someone at thoughtbot. I don't have the exact context to quote them directly. If I find it, then I'll be sure to add it to the show notes. And they shared that another company is measuring this difficulty of onboarding by they take the person's first starting date, and then they track to see when that person has merged in 10 PRs because they are looking to see how long it took for that person to get up and running to then feel comfortable, to then make some contributions.
Often, your first couple of PRs might be something that's less challenging. It might be something that's updating the README because you are going through that onboarding process. And that's a great time to then reevaluate how clear the instructions are. But by the time you get to the 10th PR, you've probably addressed something that's a bit meatier and impactful to the product. And then they use that as a metric to then calculate okay; how well are we doing? Is it a month? Is it six months until someone gets there? How complicated is the application is another way that you could look at that metric to say, "Well, if it takes people a very long time to get there, maybe it's because of the codebase versus processes." And I really like that thinking of we have knowledge silos; let’s think about where it's actually hurting us. And then, if we think it's specific to the onboarding process where that part is painful, then let's break down how we can measure how difficult it is, and then look for ways to improve it but then also track that improvement.
CHRIS: Well, I like that idea of trying to quantify and measure onboarding. I've heard a lot of organizations having like, "We want you to ship a PR on your first day," that's a meaningful thing. But obviously, that first one will probably be pretty small, and it's sort of getting that first one out of the way, if anything. But it's not truly representative of someone being able to comfortably work within the repo, but ten, that starts to feel like a real number. And I do like quantifying it. More generally, I'm intrigued. Metrics around developer productivity is such a difficult thing to pin down. And it can, I think, become really complicated, especially if you're looking at individuals and trying to say, "Well, you had four PRs, but you had two PRs," and comparing individuals. But I do really like the idea of more aggregate stats of on average; right now last month, we were doing 1.2 PRs per week per developer, and now we're down 2.7 PRs per week per developer, something like that, and seeing that looks like something that we might want to address. Are there fundamental things that are happening that are causing development to slow down? Are we doing bigger PRs, et cetera? And starting to look at that, but try and have a metric to keep an eye on that. So I'm super intrigued by that and then again, more specifically to the onboarding one that you were talking about there.
Actually, popping up a slightly higher level, though, I think both you and I sort of jumped into this conversation as, like, yes, knowledge silos got to fix those, that's a problem. And I do feel that way. This is a topic that I feel pretty strongly about and pretty clearly about that knowledge silos are the natural state that things fall to, and it's not a good thing, and we want to avoid it. But it is important to ask the question of who is deeming this to be a problem and for what reasons? And we had a good conversation two episodes back in response to a different listener question about consulting versus building product. And I feel like, with this, we can almost go up to the consulting level of this can be a problem, but it also maybe isn't. Or, who believes it's a problem? Is it management thinking, "Oh no, when that person went on vacation, suddenly everything ground to a halt? This is a problem, and we need to resolve that." Or is it the development team themselves saying, "Hey, we feel like we're a bit siloed here, and that's a problem we're recognizing," but they don't have buy-in from management. Or worst case management saying, "This is a problem, but you get no time to resolve it." As long as everyone's in agreement of the potential benefits and aligned to this is a thing that we would want to improve, and then also aligned to there will be a cost to resolving it, that it's not free to try and unwind this siloing of knowledge, then I think everything can be great. But any mismatch at sort of any level of that either on the cost or the benefit side can be problematic. And so getting to the point where you've had a clear conversation that defines this and gets everyone to come to an idea of yes, we think it's a problem, and yes, we want to put in the effort to resolve it, then I think you can move forward and tackle any number of different approaches. But I think you have to start from that conversation.
STEPH: I love asking that question of how has this manifested into a problem or a concern? Because you just highlighted a really great example where if it's only a concern because someone was on vacation and the team couldn't respond to a customer request or couldn't respond to an outage, then there are different ways to address that. So documentation may not be the best way to help out with that. That's probably a pairing session. So then someone can respond quickly to an outage versus you don't want to say, "Okay, here's a couple of pages of documentation," and then have that developer go on vacation again, and then there's an outage, and you're trying to read through those pages to figure out what's wrong. So figuring out the right approach based on the pain that's being felt feels like a really great way to go about this. Because frankly, breaking down a knowledge silo is always going to have a cost. So you want to make sure that you're being as cost-efficient as possible with your approach and then addressing the root concerns and making everybody's lives better.
Because I do think there's some knowledge silo that's appropriate. And I think silo may be the wrong word, but someone who is more skilled or an expert in the area or has more context for a particular area of the application. Because applications can get so large that not everyone's going to know everything and context switching between all of those can be really challenging. So I think it's very natural that you're going to have different people that you go to around a certain feature. If there is some lofty feature around search and you know a particular person that has worked on it for a while, then you go to them, and that feels like an appropriate level of knowledge that someone has obtained. And I wouldn't classify that as a silo at that point. But then if you do get to the point where that person went on vacation and then search broke, then you can start to revisit okay, maybe this person does have too much context, and then we can offload some of that context to someone else.
CHRIS: There was a phrase I used earlier of like a patchwork quilt, but I think that's not quite the right image. There's an image in my mind of little islands of color that are fully separated; that’s bad. And then there's a version of more like a Venn diagram overlap where each of the colors sort of bleeds into the other ones, and I think that's good. But then the perfect overlap where it's just one big blob of brown because all the colors are the same, that's bad. And I think that's what you're highlighting is like, you don't want to go to that. You don't need the perfect overlap of everyone having a complete shared knowledge set. I'm trying to make word pictures over internet radio. So it's probably not going great, but it's something to that. Like, there is an optimization here, and I think the way to find that is by starting from what are the pain points? What are we feeling that is less than optimal? And then coming up with solutions that directly address those pain points, not generically try and target like knowledge silos bad. And retros are a perfect way to do that. So if you listen to our previous episode where we talk about the virtues of retros and other agile philosophies...This is great. I feel really good about being able to reference previous episodes. I think we've talked about good stuff in the previous episodes.
STEPH: You've been on fire with this episode. I think you've referenced at least two, three episodes at this point. [chuckles]
CHRIS: Yeah. Wow. Well, I mean, we're at 300 now, so we've got plenty to go back to.
[laughter]
STEPH: We've got plenty of content to reference. I think you and I do have an advantage here based on our experience where we have had to join a number of projects. And then we know our time with that project is very determined, and we want to make sure that we don't take any knowledge with us. So something that you and I have acquired as a skill is seeking knowledge when we first join a project and asking a lot of questions around how the application works and then understanding more about the intent of different features, and then knowing where to dive into a codebase to then make fruitful contributions. And I think there's a similar approach that can be taken when trying to break down a knowledge silo is a person who is that silo may be in a spot where they're having trouble communicating all that information and then dispersing it to others. So then us, as their teammates, can go to them and try to ask those types of questions to then help ourselves level up and then recognize areas that don't feel documented. And maybe it's adding documentation, maybe it's adding tests, or maybe it's doing a demo, maybe it's recording something about the feature and then sharing that with the team. But then you can be an advocate for that person who is in a silo position to then help them share that knowledge because they may be too far down that path where they don't recognize what they know, and other people don't. I don't know if that's directly related to being a knowledge silo but just an additional way to approach helping breaking down when you recognize that a silo does exist and looking for ways to then help that person communicate and distribute their knowledge.
CHRIS: Yeah, I think you're describing a distinction between a push versus a pull. It could be incumbent upon the person who has the knowledge to try and push it out to the team. But often, they're going to be perhaps a more senior person. They've got code review to do. They've got other meetings, and planning, and things, and they just may not have the time. But is there a way that other team members can proactively pull that information from them and help them find the moments that will clarify that? So, yeah, broadly, as a team, let's rally around the desilofication of the whole adventure.
STEPH: That's exactly what I was going for is that push versus pull mentality and how we can break down the silo from both sides. So thank you, Jen, for that wonderful question. I hope we gave you some helpful ideas and suggestions around addressing a silo and then also identifying the pains that you're feeling so that way you can find the most cost-effective approach. But on that note, shall we wrap up?
CHRIS: Let's wrap up.
STEPH: The show notes for this episode can be found at bikeshed.fm.
CHRIS: This show is produced and edited by Mandy Moore.
STEPH: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or a review in iTunes as it helps other people find the show.
CHRIS: If you have any feedback for this or any of our other episodes, you can reach us @bikeshed on Twitter. And I'm @christoomey.
STEPH: And I’m @SViccari.
CHRIS: Or you can email us at hosts@bikeshed.fm.
STEPH: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeeee!
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success._Support The Bike Shed

Jul 6, 2021 • 46min
299: Is Agile Over?
Let's talk about Agile! What is it, what do we like, we do we not like?
In this episode, Steph and Chris discuss:
Broadly, are they fans?
What makes this practice work well?
What makes this practice work poorly?
And also, hit specific topics and practices like Scrum, Kanban, and Extreme Programming.
Twitter Poll re: Gotime Podcast - Is Agile's Time Over?
The Mortifying Ordeal of Pairing All Day
The Real Story Behind Story Points
Agile Manifesto & Agile Manifesto -- Principles
Extreme Programming Introduction
Extreme Programming Explained
Ron Jeffries - What is Extreme Programming
Transcript:
CHRIS: I feel like we should try a couple of different byes just so we have sort of a smorgasbord of options, and then we can pick the best one.
STEPH: With countdowns, [laughter] because I do so well with countdowns.
CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey.
STEPH: And I'm Steph Viccari.
CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, I thought we would try maybe something a little bit different this week, a little bit more of a structured topic. In particular, I've been gathering little tidbits of information. I've been seeing conversations happen all around the topic of Agile, things that people like about Agile, things that people hate, mostly it's things that people hate about Agile. Lots of ire on the internet about Agile, but I think also some disagreement about what it actually means. And I think; generally, you and I are probably fans, so I want to talk about that. What parts do we like? What parts do we not like? What do we think Agile actually means or, at its best, maybe what it means? But yeah, let's start at the very top stuff. Steph, what do you think about Agile?
STEPH: I am generally a fan. I'm with you. And yeah, the internet being full of more negative remarks and ire, that sounds very true. But generally, I am very much a fan of Agile, and the very broad scope of this is how we work, and this is how we plan our work, and this is how we collaborate as a team, and then how we reflect on the work that we have completed. I can also pick apart some of the things I don't like about Agile, but in the broad umbrella definition, I'm a big fan. I've enjoyed that approach. Granted, I've also only ever used Agile. I haven't written software using a Waterfall style, at least not purposefully. And then if I have encountered a team that was using more of a Waterfall style, then we changed it quickly. I really only have known the more Agile approach to writing software.
CHRIS: I think that's largely true of me as well, where most of my work would fit somewhere under the umbrella of lowercase "a" agile, although I've tried variants of Scrum and Kanban and a bunch of other things that we'll probably chat about today. But I think in general, I find that things are most effective; things seem to move the most smoothly. And I think the software that we come out with is the best one. It's closest to those very simple ideals of Agile. And every layer of process that gets added on even though, like you, I've not done true Waterfall where it's like six months requirements gathering and then it gets handed off, and no one talks for a while. I've never done that.
STEPH: I have to interject because I actually think you have in a previous life when you were an engineer. You have done the more Waterfall. Like, you have to plan very far in advance.
CHRIS: I think this is one of those cases where people think "engineering" quote, unquote like mechanical engineering is one thing and it's actually...there is a little more structure, and there's a little more necessity of sequencing where you've got to figure out what you need to buy first because sometimes it takes a while to find the particular piece of metal that you need in the world. But it also has a lot of figuring out as you go and being like, well, we've got a bunch of stuff, and we're just going to figure it out. And also, this is something that as I was studying software while working as a mechanical engineer, I started to hear about this whole Agile thing, and I was like, huh, I wonder how I can bring more of that? Because I definitely saw cases where a more Waterfall-centric approach to engineering projects was leading to bad outcomes. It's like we decided upfront what we're going to do, and then we went away for six months, and we did it. And then we came back, and it turned out it was wrong. So that was solvable along the way. There were ways to build prototypes and things like that. So that is definitely a part of the mechanical engineering world.
Although I think there are some true constraints, but I think there are also some occasionally self-imposed constraints, but again, I see sort of the same thing in software. Anytime that we can shorten feedback loops, that's what I like. And I think that for me, that's the core of Agile. Specifically, to come to the Agile Manifesto, to start at the very top, the thing that kicked it all off is a very simple document that the first line of it is "We prioritize individuals and interactions over processes and tools." It's like, yeah, that seems like a great thing, having more regular conversations about the things that we're building rather than having those initial conversations. And everybody goes away for a while and tries to build that thing, and then they come back, and hopefully, the thing that they've produced actually solves the problem. But I think almost always there are some deviations like, oh, actually, it would have been better if it was like this or now that we're actually trying it in the field, it's fundamentally different. So in that way, I think there's actually a lot of commonality between mechanical engineering and software development.
STEPH: Okay, that makes sense. Yeah, I was thinking around the process of where you'd have to order stuff in advance versus for us; we can describe everything that we need as we need it unless we're having to procure some specific software or licensing. But otherwise, we don't have to wait on that shipment flow to then have our goods. And then, if we also mess something up, then we don't have to reorder more pieces. But I like how you started talking about that agile with lowercase "a" and then talking about the manifesto because I suspect most people are familiar with Agile, but it wouldn't hurt just to read off some of those top things about what Agile is so that way we're all on the same page together for this conversation.
So you already covered the first one that talks about individuals and interactions over processes and tools, and then the others are working software over comprehensive documentation, customer collaboration over contract negotiation, and responding to change over following a plan. And that's it; those are the aspects of Agile. And so then, circling back to what you were saying earlier where people are having more criticisms around Agile, it sounds that it's less about Agile, and it's often more about the implementation of these ideas and then how you're approaching them. Because, boy, do we have several ways to implement Agile. We have Scrum; we have Kanban; there’s Extreme Programming. Does that fall within the Agile umbrella? I think it does.
CHRIS: I believe so. And I think a lot of the things that people take issue with particularly come from Scrum and Extreme Programming. We're taken to their extremes. Yeah, it's right there in the name, so you should probably know that it's going to be a little out there. But taken to the extreme and especially where it becomes rigid and dogmatic, then it becomes a problem. But again, so we listed out now the four items that are the core of the manifesto. There is a separate part of the manifesto, which is the principles, which digs in a little bit deeper, but it's still very much in that same ethos. But I do want to highlight because there's a subtext to the Agile Manifesto that I really love, which is given there are things on the left and then things on the right when the Agile Manifesto was presented. And so it's like we like individuals and interactions, that's the thing on the left, over processes and tools. And so the subtext below it is that is while there is value in the items on the right, we value the items on the left more. And that's one of the things that I love about the Agile Manifesto is it's not this very rigid thing that says, "This is good, and that is bad," it is a statement of a preference of well, yeah, it's definitely good to have comprehensive documentation. That's a really nice thing to have, but it's incredibly difficult. And if we have to choose, we're going to choose working software. We're going to prioritize that well before we have comprehensive documentation. So I really love the juxtaposition, and the emphasis on it's not that one is good and one is bad of these two things that we're comparing but that we have a preference, and that we want to orient our work around the items on the left rather than the items on the right, which I think the items on the right are more traditional or were more traditional to the Waterfall approach.
STEPH: I like how you highlighted how those statements are presented to the reader. So then that way, as you mentioned, we still value what's on the right, but we favor more what's on the left. So one of the things that I saw recently was something that you shared with me in regards to where you're bringing up the idea of, like, hey, let's talk about Agile. And you shared with me a clip or a specific tweet that linked to a clip from the Go Time Podcast, which is a podcast that I hadn't listened to before. But I listened to that episode or at least part of it, and it's really delightful. I enjoyed listening to them very much. And they had Kris Brandow on the episode. And at the end of the episode...and they do something really fun where they ask the guests, "Do you have an unpopular opinion that you'd like to share?" And one thing that I like about their unpopular opinions is they often have polls afterwards, and they want to see was this truly an unpopular opinion? And if most people agree with you, then they actually consider it nope, he didn't win. I don't know if they use the word win if you didn't achieve the unpopular opinion. And in this instance, Kris shared the opinion that Agile is done and over with and that we should move on, which is a big thing to say. Everyone on the podcast reacted in a similar way that I would where it's like, well, how do we track things? And there are still things that we need to care about. But then also, there's a part of me that's just like, yes. I am not sure where Kris has heard it just yet when I heard that, but I'm already tuned in and very interested.
And one of the things that Kris said that also really resonated with me is he mentioned that "I've never worked on a team where Scrum specifically like sprint and story points functions well," and I absolutely agree. There are parts of Scrum, we can get to the specifics that I think are fine that I've certainly used in the past and that have worked. Story points resonate deeply. I very much agree that story points are something that I do not enjoy using, and I do not find that they really lead to building software. There's even a blog post that I published along with Matt Sumner, a former thoughtboter and guest on this show, where we talk specifically about story points and some of the concerns and issues that we have with using story points.
CHRIS: It was actually also the first episode where you came on as a guest to Bike Shed; that that was the topic that we dove into because it was so near and dear to our respective hearts.
STEPH: That's right. I forgot about that. So yeah, story points are certainly up there on my don't list. I feel like we're doing a fashion do and don't, but we're doing the Agile do and don't list. [laughs]
CHRIS: I kind of like that. Yeah, we should lean into that vibe. But yeah, continuing on with the poll there, it was interesting to see also, like you said, they tweeted out, and then there's the poll that comes after. And it was 64-ish percent of folks agreed that Agile's time is over and done with, and we need to move. Granted, it wasn't a huge sample size. It was like 85 people that took the poll but still, seeing both the statement and then also the general support from folks on the Twitter, it was interesting to see. So I do have the question of like, well, okay, if not, what else? And I share your sentiment of we should be able to ask questions and iterate. And nothing is so precious that it can't be replaced by something else that's better. So we always need to be trying to find the best ways to work. But again, I think there are still kernels of good stuff in the Agile. So I found this and I was like, oh, this is interesting. What's going on here?
STEPH: So I'd love to dive into some of the specifics around Agile to understand what are the bits and pieces that work for you and the bits and pieces that don't. So if we are taking our Agile approach and reviewing the things that do and don't work and changing that process, what are the things that you would keep, and what are the things that you would throw out?
CHRIS: Yeah, well, we can dig in, and we can bounce back and forth, I think, on this. But again, there are sort of a few different camps. So I collected together some of the lists of practices associated with some of the different approaches to Agile. So starting with Scrum, which I think perhaps is one of the most rigid, most structured, and perhaps most ire-deserving of the approaches to Agile, one of the first things is sprints or iterations, so the idea of starting...before you begin the work, you sit down, you define how much work you think you're going to take on. There's often an estimation process. Actually, we'll say that because that's maybe a separate idea, but even just broadly the idea of sprints and iterations, which often involve the idea of committing to a certain body of work. And that commitment is always handwavy and loose. No, no, no, we won't hold you to it, but then it's a constraint that's placed on the team. It's an expectation that's set, but it's wildly difficult to estimate software, as we all know. So sprints and iterations, personally, I am not a fan of. I really like a more continuous flow where we're constantly reprioritizing the work to be done. We're constantly measuring against what we built, what we think we need to get out there. How can we get something out in front of users as quickly as possible? But I've not found a ton of utility in the sprint or iteration workflow. But what do you think of that one?
STEPH: Yeah, I'm generally not a fan of sprints, and it has taken me a while to get there. And I feel like I can admit that openly because it is something that I feel like when I first started doing software development, sprints were life. It was how you planned everything. It was how you committed to work. It's how you measured your work. It's how you then looked back to see what you could and couldn't accomplish in two weeks’ time or maybe a week's time, depending on how long your sprint is. But over time, I have realized that I don't like the mentality of sprinting, and that may just be a nitpick on my part, but that is something that I don't enjoy because we write better software when we have breaks. And with the sprint methodology, there's really never that break unless you're going to plan that into your sprint.
And then there's the idea of the upfront commitment, as you'd mentioned, it's one of those, don't worry, we're not going to hold you to this, but can we all commit to this work? And it's one of those you just feel compelled to say, "Yes," to the person who's asking because then you feel like a jerk if you push back and you say, "Well, actually, I don't know if I can, so I'm going to commit to way less." And then that's the approach that I started taking of, well, I don't know. So I'm going to always commit to a little bit because I'd rather overachieve and then deliver more than come in under because I could work really hard, but I've over-committed and then still feel like I didn't reach my goals, and that's a rough feeling. So I found that I was already lowering my commitment there. So then, it felt more appropriate to be in line with that sort of continuous workflow instead of trying to commit to all these features or all these tickets that needed to get done. I think those are the two areas for sprint where it doesn't align with me and where it can work for teams. But I feel like there's always that underlining unhappiness that a lot of us just don't want to talk about because we don't know what else to do other than to keep sprinting.
CHRIS: Yeah, I think you said something about the specific, like nitpicking the word sprint, but I do think that's actually meaningful. It's The Bike Shed, after all; if we're not going to Bike Shed about some words, what are we doing here? But I do think that we're using that word...it's obviously the wrong word; this thing's a marathon. You can't have 26 2-week sprints back to back throughout a year. That's not going to work. That's not how humans work. But any amount that we let that thinking into our head, I think, is problematic. If I'm understanding correctly, it sounds like you've come to a place of comfort around committing to a smaller body of work and then ideally overdelivering. But in my experience, many developers, perhaps even most developers, don't feel comfortable. It's so difficult to say, "Yeah, I know that the login form should take a day. That's what I feel in my heart. But let's be honest, every other time we've done a form, it's taken a week. So I'm going to say a week." It's so hard to do that. And so I think continuously, we end up in a mode where we are failing to meet the collective commitment that we made, and that's demoralizing. That's going to constantly just be a drag on the team, even if they're fake, made-up deadlines that we're constantly setting, that we're constantly not hitting. Just doing that over and over, I think, is really detrimental to the morale of the team, to the cohesions, and the feelings of are we actually doing this work? So perhaps pedantic, but I definitely share all of that.
STEPH: I do want to highlight, as I mentioned earlier, I'm feeling more comfortable that I can under commit and then I can overdeliver, and that is hard. That is something that still in the moment, even today, is very hard for me to do. And it's like how you said, in my heart, I feel like this should take a day, and the heart lies. But on top of that, it's often it's also my ego that's driving me all the time. And with that, it feels like a competitive environment to me where someone's saying, "Hey, can you get this done?" And in the moment, that brings out my more competitive side where I want to say, "Yes, I can get all this done, and I can deliver all the things." When, in truth, that's often not how it's going to work out.
There is one thing I do like about sprints that I want to reflect on, or perhaps it's actually two. And one of them is that we are getting together every so often, and we're agreeing on the important work to be done. And I really like that planning process that is typically coupled with a sprint. So you get together, you review the work, you address any concerns or raise any concerns. And then you could say, "Yes, we all agree this feels like important work." And essentially, we're buying into the work that's getting done, and I really like that process. And then, as an extension of that, I really like how we often then pick themes. So as we are agreeing to the work, we're often grouping together work that makes sense where it's either the most cross-functional or collaborative. We're already going to be in that space together. We're aware of what everybody is working on. And those are the aspects that I really do like about sprint and some of the other styles, that more continuous workflow of where we're always pulling from a backlog. It feels more of a grab bag in terms of I don't really know what I'm going to get next. I don't know how this work has been reviewed or vetted. I haven't really gotten to talk to anybody, perhaps. I'm making some broad statements here. But I haven't really gotten to talk to anybody from the product side to understand this change. And I also don't really know what the rest of the team is working on, so I feel more disconnected from them.
CHRIS: Yeah, I definitely share that, the planning or the meeting where we discuss the work that's coming up and shape it a little bit; I love that. Although it's interesting within the context of Scrum, I think like truly to the letter Scrum; my understanding is there are very discrete meetings, and they each have a distinct purpose. And so there's the sprint planning meeting, there's a backlog grooming, there's a sprint review and the sprint retrospective. And each of those are these four distinct meetings that are happening once every two weeks or so or whatever your sprint cadence happens to be. And the splitting of those becomes interesting. And some of the practices in there, I think, are...I think you and I share not being interested in doing them or not finding them to be super valuable. But I think broadly having some version of hey, let's sit down and talk about the work before we have to do the work, definitely a fan of that. For me, it often can be let's collapse four of those meetings into one sort of thing and maybe have it more regularly or something to that effect. But actually, we'll touch on the rest of those. But if you're good with bouncing from sprint/iteration, I think we've covered that topic well. Let's move on to one that I think we can do pretty quickly because I'm pretty sure I know how we feel, but sprint planning/planning poker/estimation. How do you feel about this one, Steph?
STEPH: We grouped a couple of things in there. There's sprint planning, and then there's sprint poker, and those are different to me.
CHRIS: Yeah. So let's go specific to the planning poker as the most pointed version of it but also generally estimation and sizing of stories.
STEPH: Nope. Throw it out. I don't know how to play poker. Let's just get rid of it. [laughs] I was never a good poker player.
CHRIS: Playing poker can be fun, but planning poker...Well, so actually, to ask a slightly different question, I think in the past we've talked about keeping aspects of it, definitely not keeping the let's figure it out, let's hash it out. Let's get down to an exact point value, and then we know we can have 34 story points a week, and that's what we're going to do. But the version of using planning poker, using this numerical communication tool to see if we're aligned, that one I think we've talked about liking that. I have enjoyed that, but under the strict guidelines that we throw the numbers out. The numbers are only a communication tool. They get thrown out after the fact. We do not commit to a set amount of work or anything like that. We just use it to say, "I think it's an eight. I think it's a one. Oh, we should talk," just for that. That's when it's useful.
STEPH: I agree. Yeah, in my previous answer I was being flippant about it, but I do agree very much where I don't like the specificity of where you're trying to plan exactly what numbers are these. But I do find it very helpful for the reasons that you just said where the team agrees with the estimation around how long they expect something to take. Because then that is really great where you have someone who's never touched the codebase, and they're like, "I think it's a five or whatever system we're using here." It's an elephant...whatever scale you're using. And then someone else is like, "Well, I think it's a doughnut size." I'm making up silly stuff because it's more fun for me. And then those two people can talk and reconcile. So I do like discussing the estimation of work for that purpose but then not actually writing it down or maybe going with t-shirt sizes, something that's more simple, and then doesn't have anything with points, really. Anything with points can then be gamified and also brings out people's more competitive side. So, if you can make it something that's more fun, maybe around t-shirt sizes or a bunch of cute animals, various sizes, whatever works for your team. I'm trying to think of other fun measurements now [laughs] that we could use instead of t-shirt sizes.
CHRIS: There are the sizes of bottles of wine as you go past. So there's a regular bottle of wine, and then there's a magnum. And then it gets to weird names like a Nebuchadnezzar and other things. These are big performative champagne bottles. So I think we should use that kind of sizing because I think they also have a geometric progression type thing, not quite Fibonacci but something like that. So I'm going to make that push for Nebuchadnezzar as being my go-to [chuckles] sizing in story points.
STEPH: I have never heard of that, and I love it. That's great.
CHRIS: Okay. We'll find a relevant link to the wine bottle sizing, and we'll put that into the show notes. We will also, of course, include a link to your wonderful blog post. What's the story with story points that you wrote with Matt Sumner? Because I think that really does dial into this topic really well. And again, coming back to that core idea around Agile, while we see value in the item on the...which side is it? While we see potential value in story points, I have worked with countless teams who desperately wanted to make this thing work. So it would be great if we could quantify the work and then numerically understand the work that we had ahead of us and sequence things and talk about deadlines and whatnot. Man, that would be amazing. I would really love to do that. So with every other developer and every manager of a team of developers in the world, I have not seen it done. I am still looking for that day. When that day shows up, then I think this will be a wonderful practice. But unfortunately, my experience has been that this doesn't work, and trying to do it causes more harm than good.
STEPH: I agree that I certainly understand the reason that people want story points to work because it's very nice to then say, "We can calculate, and we can measure, and then we can have delivery dates." And that's really nice from a management perspective. But that does blend in nicely to the next topic, which I think fits nicely underneath the Agile umbrella, our daily syncs. Because that does bring us closer to that goal of where we can't give real valid updates on how something is going and provide a more real estimate as to when we think something is going to get delivered. That doesn't have the same effect of where we think we're able to plan and then promise delivery dates a week in advance because we're getting those updates in real-time, but they're going to be more reliable. And that is, we're so much more than where we try to over commit to work or if we try to say how much time something is going to take. And that is so much more valuable to have that reliable update and estimate versus trying to trick ourselves into thinking that we know when something is going to get delivered.
CHRIS: Yeah, I think the daily sync or sometimes called the daily Scrum, or standup, or otherwise morning meeting often in the morning, this is one that I see lots of folks really hate, and I'm personally a big fan of. This is one that I would definitely hold onto. But I think you have to be very, very purposeful with how you structure it. It really should be as short as possible. And there's one particular thing that I see very regularly in teams, which is almost a performative version of what I did yesterday. It's trying to demonstrate to the team that yes, I, in fact, did work yesterday. I was a valuable team member. Please don't let me go from the team. And I think that's the sort of thing that we should try and just get rid of. There are definitely times where what you did yesterday is relevant to the team, or you worked on something, and now you have a bunch of questions, and bringing that to the team is useful. But that version of everyone needs to prove that they did work yesterday or...it's the sort of thing like if anyone says that sort of thing, then everyone else is like if you don't say what you did yesterday, then it sounds like you did nothing because everyone else is saying what they did.
So you have to, I think, get a team buy-in to do this, say, "We're not going to talk about sort of bullet-list what we did yesterday. That's not going to get us anywhere as a team." But what's useful are those little magical moments of connection where I say, "Yep, I'm working on this. I'm going to implement it in this way." And someone's like, "Wait, wait, that way? Oh, we shouldn't implement it that way." And then ideally, what happens there is okay; let’s connect after this meeting. You've now made this connection, but you don't need to hold up the rest of the meeting for that. You can just say, "Cool, this connection has been made. That's an incredibly valuable little point in time, but now let's continue on with the flow of the meeting," so that it keeps that rapid pace. And so times where you're blocked, times where you have questions, times where you're just describing what you think you're going to be working on. So if anyone's like, "Oh wait, no, we needed to stop that work because we actually made a decision yesterday that impacts whether or not we actually wanted to build that feature at all." If you can head off incorrect work at the pass, there's so much potential value in that meeting that it is interruptive. And it does take up some time, but I find that it is so, so worth it if you're able to really keep it focused, keep it concise, and keep that end goal of those little connections. When those happen, they're so valuable. So I think it's really worth the input.
STEPH: I'm still smiling from where you said performative of what I did yesterday because that is something that took me a while to understand, one of the things that I did not like about the daily sync or daily meeting whenever your team gets together to talk about the work that's being done. And it was finally when I realized we're just going through a list of who has the longest list of the things that they accomplished yesterday. And again, it felt like it was bringing out more of that competitive mode in folks to talk about what they did, and it didn't feel very useful. Every now and then, maybe there was one thing that was interesting that someone did. But most of the time, it was always more helpful to hear what the person was working on that day for all the reasons that you just highlighted.
There is one practical concern that I have with these types of meetings or with these types of events. And it's where you'd mentioned where if we can keep it concise…and someone brings something up, and it starts to devolve into a conversation right there. So then whoever was up next is now waiting while that conversation is happening. And that part gets awkward because then there's usually one person who is then willing or no one frankly is willing to then say, "Hey, so sorry to interrupt, but let's actually table this discussion and let everybody else go, and then we'll come back to this." And if you have people on the team that have been there for a long time with that culture, then that will just work because everyone will keep each other in check. But otherwise, if you're starting that new process, or if you start to notice there's always that one person who's doing that awkward thing of trying to then set that culture of this is how we do our daily chat, and these are the things that then we wait for later, it's really hard. And I say that because I have often been that person that's in that space where then I encourage people to table a conversation. And it always just feels awkward to interrupt someone and ask them to please wait until everybody else has gone.
CHRIS: I share your hesitations around that, but it is very important. And it's that sort of ideally someone in a more senior position will model that behavior and model it in a positive, friendly way. Where I have done that often it's in the form of a question, so it's, "Actually, do you think maybe we could take this offline?" or something like that. Not a command, not taking over or shutting people down because it is somewhat interjective, and you're sort of correcting course. And so, being as friendly and empathetic in that moment as possible, but that's a hard note to strike. And again, if it's something that only one person is like the taskmaster, the Hermione Granger of the team who's trying to keep everyone focused and doing their homework sort of thing, nobody wants to be that. Well, Hermione did, but otherwise, nobody wants to be.
STEPH: I love all the Harry Potter-themed references that have been coming through in the last couple of episodes. And I agree it is something that's hard to help teams course-correct, but it's important, and it's very much something worth doing. I just recognized that I think that's why these roles get implemented, why there's this concept of a Scrum Master, and then why we designate these tasks to specific people because then you have someone who can do it. And then when they do interject, it feels more appropriate because that is their role, and that's one of the things that they're supposed to do versus putting it more on the social pressure of whoever is comfortable speaking up to then course-correct. So I do understand where that implementation of Agile has then tried to create those roles, which I've been on teams that have a Scrum Master. And my experience is it's often been a very positive experience because the person that is in that role is often very kind and caring about that team. And so they are a wonderful person to work with, but it's also one of those...I've also been on teams without them, and things have been fine. So I have mixed feelings about that one. It's one of those; it feels like an extra heavy process, but I've also been on teams, and it worked.
CHRIS: It's interesting the way you frame it, of the utility of that role. Like, having a role where we've now all bought into the idea that this person may take these actions say, "Hey, can we take that conversation offline?" and rather than one individual choosing to do that. I like that framing. I share what you're saying about the rest of the baggage that comes along with having this formal position, and often, that person is otherwise removed from the work. That can often be an aspect of Scrum. I think that gets complicated. But now I'm wondering can we make a software solution to do this? Because, of course, that's where my head goes. Can we have a standup bot that is listening and is like, "Hmm, it seems like you two people have been talking for the past two minutes. I'm just going to interject like my little bot self that I am and ask maybe take this conversation offline," in the way that we've sort of automated a lot of code formatting things, and that's been really wonderful, so that's not a part of PR review. Can we do the same for standup? I don't know.
STEPH: I think all the award ceremonies have these where they start to play the music, and that's your cue to move off stage.
CHRIS: Oh, I like it.
STEPH: I think that's it. [laughs] So you cue the music whenever someone has been going for quite some time. On a slightly separate note but still related to this, some conversations that have been bubbling up around me have been related specifically to this idea around stepping in to say, "Hey, I'll take on that thing that you need a volunteer for," or "Hey, I will help the team stay on track," will often fall on people with a specific personality and then they will often be the one that continues to do that. And so they will end up taking on additional work or taking on additional roles just because they may be in a more empathetic spot where they feel that's the kind, helpful thing to do. And so, we've been looking for more ways to make sure that those tasks are being distributed evenly across the team. So we're not just waiting on someone to say, "Who would volunteer for this?" And then typically being the same handful of people that are always speaking up and then volunteering for it.
And then trying to shift to more of a purposeful approach of having a queue of people and then cycling through that queue, and then if someone can't do it at a certain time, then we move on and then we just put them back in the queue. But this way, we don't have people that are typically just always taking on these responsibilities. And that's something that is a new consideration for me but one that I have found really helpful to be aware of and notice on your team who's the one that's always volunteering for these roles and checking in with them to see if they're comfortable with this, or if they're feeling compelled to volunteer for stuff because they may feel more inclined to speak up versus others are okay with staying quiet. But circling back to some of the Agile discussions earlier, you'd mentioned a handful of meetings and that you have some feelings about those meetings. What are those meetings that you have feelings about?
CHRIS: Yes, the meetings. So again, this is somewhat contextual to Scrum, but the structure of Scrum has a handful of meetings that sort of define the sprint. So you have some at the beginning, the middle, and the end. So there's sprint planning, there's backlog grooming, there's sprint review, which typically includes a demo for stakeholders, and then there's sprint retrospective. And these, as far as I understand it, are four distinct meetings and are intended to be kept distinct so that their purpose stays purified in each of those meetings. And I think my feelings would be that again; I don't really find a ton of value in the sprint structure or in the two-week cadence or things like that. And so I think it can make sense in those contexts to be like, we need to make sure we have space for these things. But in a more continuous context, I think the backlog grooming or, more generally, let's talk about the work that's coming up. Let's make sure that we're all unified in how we're thinking about that work, what we think matters, what's prioritized. I think that is an incredibly valuable meeting. I think sprint review and specifically demo for stakeholders I'm really intrigued by that one. I don't know that I feel like that needs to be a distinct meeting. And in fact, more and more these days, almost every feature I deliver has either screenshots or a screen recording of what that workflow looks like. So we're continuously demonstrating to the stakeholders what does this look like now that it's a real thing? What does an end-user see? What's that experience like? And in retrospect, I think we'll probably spend a minute on that one. I like retros; some people hate retros. Yeah, let's loop back to that. But of those, what are your thoughts? What do you like? What do you not like about those meetings?
STEPH: I think grooming is a very helpful meeting that can help a product manager and a technical team have discussions about the upcoming work. I don't necessarily think it needs to be the whole team. I think it can be a couple of engineers from the team; maybe those people rotate, maybe it's the team lead. And they get together with the product manager, and they essentially answer any technical questions about upcoming work. So then it can be refined. So then, as we get closer to that planning session, whatever we want to call it, then it feels more in a ready state for folks to react to and then have opinions on. So I do like grooming, but I wouldn't necessarily advocate that the whole team needs to be present for those.
For a demo, I'm with you; it really depends. I've worked on projects where the stakeholders are less close to GitHub and Slack and areas that we could demo some of the work that's being done, and maybe they weren't poking around on staging as much. So it was really helpful to then have a more formal demo to then show them the work that's being done. And then I've also worked on plenty of teams where a demo was something that we used as a fun internal event where we have all these different teams, and we get together. And then we get to show off all the great work that we have done across all the different products. So then us, as fellow teammates, can then celebrate what the other teams are working on.
Retros, you know I love retros. I think retros are a microcosm of your team's culture and process. And if your team is struggling to have a productive retro, your team is struggling. Because I think that is representative of your team's ability to get together, and reflect, share concerns, celebrate wins, agree on what's important, and run measured experiments. And if you're not having a retro, then I think you're not going to know how your team's doing until it's too late, and it's going to be harder to course-correct.
CHRIS: #HottakeswithSteph. I like it. I like the intensity that you came in with there, but I know retro is near and dear to your heart. So I'm unsurprised that that is the line that you've drawn. I definitely share all of those feelings, particularly around retro, because I think much like the daily sync, I've seen many people who are just like, "This is a bad meeting. It's useless. Nothing ever happens. I don't like it." And I'm often surprised by that because I've found so much value in it. Retro similarly is this magical meeting that can just regularly change the course of how we're working as a team. But I also have come into plenty of teams where it definitely did not have that shape, where it was basically a place that everyone sits down, and somewhat downtrodden restates their list of grievances, their airing of grievances, and then nothing changes. And much like the sprint iteration thing where you're constantly missing the commitments, and that's just going to wear a team down. I think if you constantly have retro and nothing changes and it's that same list of concerns, then that is going to be bad, but that, like you said, is not the reason not to do it. [chuckles] Oh, we just keep saying the same things in retro, so I don't think it's even that valuable. I would say that maybe we should change the things. But I've definitely been on plenty of teams where retro was just so valuable. And it's definitely one where I feel like having a facilitator, having someone who is in that particular seat trying to guide the conversation without necessarily being in the conversation, can be incredibly valuable.
There are also structures that I've seen work particularly well. We have a video on Upcase that we can link to. That's a format that I've found; it’s a very lightweight format, but it basically involves getting everyone's input on a positive note, on a more critical note, and then revisiting and sort of sorting and waiting, and then digging into topics that need a little bit more focus. But I think a lot of different formats can work as long as retro is a way for people to sincerely meet up, safely talk about the things that they are feeling about the work, and then ideally, some change comes about as a result of that. You mentioned having measured experiments, and I love that as a framing or like something that retro can do for us.
STEPH: I really do think that retros are so important because they're the health check of the team. As you'd mentioned, if people are having a very negative retro experience, which I understand, I've had very negative retro experiences as well, and I've walked away feeling like that was not a productive use of my time. But then that is our warning. That is our signal that's saying, "Something is not right, and something's not great, and we're not working together as we really want to be working together." And this retro is just that reminder that is right in our face, that is making this so uncomfortable and feel like a waste of our time because it is informing us that something needs to be improved upon. And we can feel like retros are not productive when we feel powerless to make that change. And that again is then another discussion to have with the team, to have with management, leadership, to talk about how do we get the power to then make the changes that we need to then have productive, happy retros? Because that's going to be a reflection that you have a happy, productive team.
CHRIS: Love it, love the framing, love the symmetry there between team happiness and retro happiness. So to summarize, I think we've gone through most of Scrum now. So just to...correct me if I'm wrong on any of these, but I believe sprints and iterations, nah, we'll leave it. Planning poker, definitely not. That doesn't seem good, although maybe just to bring up conversations, but not as an artifact that we save in any way. And then otherwise, daily sync, we're fans. Retro, definitely fans. Sprint review, backlog grooming, some version of those, a lightweight version of a bunch of the meetings seems may be good, but a couple of things definitely are going to leave on the cutting-room floor. Does that sound about right to you for Scrum specifically? We've got other topics to cover.
STEPH: Yep. All of that list sounds really good.
CHRIS: All right. So we've now found our refined version of Scrum, re-Scrum as we'll call it. But now there's a couple of other pieces...So Scrum is very focused on the ceremonies and the team activities, but there's another facet of the Agile umbrella, which is Extreme Programming, which that's a book. I believe Extreme Programming Explained is the name of the book. And there are various different links that we'll include to point at those. But there are two particular practices that stand out that I have heard some people love, some people do not. So we'll go into both of them. The first is pair programming. What do you think, Steph? Do you like pair programming?
STEPH: I do. I'm a huge fan. [laughs] Yes, I very much like pair programming, although it still has its limitations. I definitely want time on my own, and I can get exhausted from pair programming. It is a very vulnerable experience, too, where you have to share with someone: this is what I know, this is how I work, this is how I think. And I think that is incredibly challenging. I find that I am typically more productive when I'm pairing with someone or when I have the opportunity to pair with someone at least every couple of days.
CHRIS: Yep. I'm definitely a huge fan of pairing. Although I think specifically to Extreme Programming, I think the idea is 100% pairing. I think you already spoke to this, but pairing is exhausting. And the idea of 100% pairing is I can't really even imagine that; even 50% pairing feels like an incredibly high bar to hold for any extended period of time. There's a recent article that was going around the mortifying ordeal of pairing all day, which spoke of one person's experiences getting deeply burnt out just going through that process. And so, as valuable as pairing is, it's definitely a tool to be used not all the time. That feels like a lot.
STEPH: That's a lot of Stephanie singing because I tend to sing a lot whenever I'm stuck or thinking through things. So that's a lot of singing that I don't know if the world wants.
CHRIS: I mean, based on all of the various Bike Shed intros that involve you singing, I think the world wants it. That's maybe one person's take. But definitely, something that you said of there's a vulnerability to it. And so many pairing sessions I've either been the one saying this or someone else that I was pairing with has said this to me, but they're like, "I swear I know how to type, just now that someone's looking, my hands don't work." It's like you're in a dream, and your legs don't work. You're like, I know how to run, I swear. But for some reason, my legs are made of jelly right now. Or you can't remember a particular method, or there's just something that happens, and so getting over that hump, getting comfortable with it, I think it is a skill and something to become accustomed to. And so, again, being conscious of that when you start doing it is super important.
STEPH: I don't know if this is true because I only have access to people’s thoughts when I'm pairing with them, and then they're sharing their thoughts with me. But I do feel like people tend to beat themselves up more when they have someone watching because then you feel the need to say, "Oh, I normally can type, but because someone's watching..." which is so true; that definitely happens. But those moments are some of those really great moments to then reflect on the fact that just because someone's watching us doesn't mean that then we suddenly need to beat ourselves up. And I don't know how philosophical that I want to get with this, but I feel like there are so many opportunities while pair programming to then encourage other people around us to be kind to themselves. That is one of the things that I have really benefited from pair programming is learning to be more kind to myself. And even if I don't know exactly what's happening or what I'm doing and I may not be as confident with someone else, I can still be positive and kind. Just because you're in a vulnerable space doesn't mean that you then need to be unkind to yourself.
CHRIS: Yeah. I definitely agree with the idea of being kind to yourself also, where you can, be kind to someone else who you're pairing with, especially if they're finding that they're like, "Ah, suddenly my hands don't quite work." But I have pretty uniformly seen that a pairing session may start out that way. And then as everybody kind of just relaxes into it, suddenly you'll see someone just kind of flying around their editor. And you're like, wait, what just happened there? That was so fast. I don't even know. And so there's just this comfort level that sometimes it takes a little bit of time to ease into. But yeah, so pair programming, broadly yes. 100%, oh, that's going to be a no, no, thank you, not that. All right, so one other practice that comes from Extreme Programming, which is Test-Driven Development AKA TDD. What do you think about that one, Steph?
STEPH: I feel like you're giving me lay-up questions here. For anyone that's familiar with us, [laughs] I feel like this is an easy one. Test-Driven Development is a thing. It's a thing that I enjoy. I don't always write tests first, though, so I don't always follow TDD, but I am definitely a fan of tests. So, I guess in that light, it’s not so much that I adhere always to TDD. I don't feel the need that I have to write tests first, but I have found that with practice, that often helps me write code where I have tests then help me write out the logic for my code. So generally, yes, thumbs up on TDD, but I'm also not terribly strict about it where if you want to write some code first, write some code first.
CHRIS: Yeah, I think I'm definitely in the mode where I like testing. I like Test-Driven Development. I can't always pull it off, frankly. It's hard. It is hard to know how to write a test in advance of the implementation that you're going to write such that the test will correctly constrain the system that you're about to write. That takes a couple of levels of knowledge that if I'm writing a Rail’s controller action form sequence, I can probably TDD that because I've done it so many times. But if I'm doing something that's a little bit more new, novel, less familiar to me, then likely I won't be able to pull it off. TDD is like a fancy move that I don't always have available to me. But I consider that whenever I'm in that mode like that's not oh, it's fine to just write the thing before the test. Like, I want to be able to do TDD 100% of the time. I'm just not a good enough developer, frankly. And I don't know that I ever will be because I always want to be working a little bit past the edge of my comfort. So it's a delicate line of when I will not use TDD, but wherever I can, wherever I do have that level of knowledge of the system and the frameworks and whatnot built up, I find it is a vastly more effective way to work. It's not that I feel cool when I do it. It's like I feel much more effective. It helps me stay focused and on task and get the thing done. So it's very utilitarian in that way but also not something I can always pull off.
STEPH: So, circling back to when we first started chatting, you were asking about Agile and then my thoughts about it. And having this conversation with you, I'm realizing, or I think I was already aware, but it's helping me re-solidify I'm very much a fan of Agile. There are specific implementations of Agile that I don't find enjoyable, and I don't find helpful to writing software, and I don't find helpful from the project management side either. But broadly speaking, I'm still very much a fan of the approach that we use generally for Agile, where we want to work in small deliverable increments, and then we also want to have the ability to change any moment what is the most important thing to work on? To me, that is the heart of following the Agile process. And I don't think that's going anywhere. Like, I don't think Agile's going to disappear. But I wouldn't be surprised if we see another implementation of an Agile variety of the things that you and I just shared and the things that we like. And so, I feel like most teams that I work with follow Agile within their own unique bespoke version. And we don't have to give it names because everybody's going to have their own custom version where they decide which process works for them and which one doesn't work for them. And that's what retros are for so then you can figure out which process works for you.
CHRIS: Once more, Steph on the record about her love of retro. I think the core of Agile, the Manifesto, those core ideas about small iterations, delivering value, staying close to stakeholders, all of that feels deeply true to me. And I would be really surprised if a year from now or two years from now I was doing something that was wildly different from that. But then each of the layers of practices on top of that to varying degrees I like or don't like. And I wouldn't be surprised if aspects of that were swapped out down the road. But that core, that idea of this is how we think about building software. I like that thing; that seems like a good thing. So I'm going to hold on to Agile for a little bit longer personally.
STEPH: Same. I still see Agile in my future. On that note, shall we wrap up?
CHRIS: Let's wrap up.
STEPH: Show notes for this episode can be found at bikeshed.fm.
CHRIS: This show is produced and edited by Mandy Moore.
STEPH: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or a review in iTunes as it helps other people find the show.
CHRIS: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed on Twitter. And I'm @christoomey.
STEPH: And I’m @SViccari.
CHRIS: Or you can email us at hosts@bikeshed.fm.
STEPH: Thanks so much for listening to The Bike Shed, and we'll see you next week.
All: Byeeeeeeee.
Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Support The Bike Shed


