Go Time – Episode #177
Building startups with Go
Jon welcomes four startup founders
Startups are all about iterating quickly, building MVPs, and finding that elusive product market fit, so how does Go fit into that picture? Is Go a good choice for startups, or is it exclusively for the larger corporations? In this episode Jon is joined by four startup founders to learn about their experience building a startup with Go.
O'Reilly Media – Learn by doing — Python, data, AI, machine learning, Kubernetes, Docker, and more. Just open your browser and dive in. Learn more and keep your teams’ skills sharp at oreilly.com/changelog
Linode – Get $100 in free credit to get started on Linode – Linode is our cloud of choice and the home of Changelog.com. Head to linode.com/changelog OR text CHANGELOG to 474747 to get instant access to that $100 in free credit.
Sourcegraph – Sourcegraph is universal code search for every developer and team. Easily search across all the code that matters to you and your organization: find example code, explore and read code, debug issues, and more. Head to info.sourcegraph.com/changelog and click the button “Try Sourcegraph now” to get started.
Notes & Links
- Segmed - W. Adam Koszek’s startup with a focus on high-quality, anonymous medical data.
- Rebank - Simon White’s startup that aims to automate your business banking.
- Okteto - Ramiro Berrelleza’s startup that provides a Kubernetes development platform to improve developer productivity.
- Hightouch - Josh Curl’s startup that syncs customer data across the tools your business uses.
Click here to listen along while you enjoy the transcript. 🎧
Hello everyone, and welcome to Go Time. Today’s episode is going to be a little different. I’m joined by not one or two guests, but four guests, and we’re going to be discussing building startups with Go. So I’ll just get jumping right into the guests…
Our first guest is Josh Curl, co-founder and CTO of Hightouch. How are you today, Josh?
I’m doing great.
Awesome. Our next guest is Adam Koszek, co-founder and CTO of Segmed. How are you, Adam?
I’m pretty good, thanks.
I realized halfway through saying your name that it’s Koszek, and I was like “Ooh!” I tried to correct, but I didn’t quite do it…
You did a great job.
I apologize for that. Next is Simon White, co-founder and CTO of Rebank. How are you, Simon?
Very well, thank you.
Alright. And last, we have Ramiro Berrelleza, co-founder and CEO of Okteto. Ramiro, you’re the only CEO here. Does that scare you?
[laughs] A little bit, but I think I remember enough coding to fend off all the sales jokes.
Alright… I know early on you probably did some coding, I’m assuming, so – I don’t know if you do now, but I know that pretty much any startup founder early on is doing everything, so…
…I’m sure you were involved. And right now I really wanna talk a lot about the early stages, because I think that’s where – I don’t know, for some reason Go doesn’t seem like the most popular choice all the time, but it does seem like it’s gaining popularity.
Interesting, yeah. That was – definitely.
[04:11] Alright. So for everybody listening, the company names - if you missed them, I’m gonna link them in the Changelog.com website. So if you go to changelog.com/gotime, search for episode 175, I’ll make sure links to all the companies and everybody in the episode is there.
Alright, I wanna start off easy… Hopefully easy. Why did you guys choose to use Go at your startup? What was the motivation behind that?
For us, there was a dual motivation. One is we were using Go before; both me and Michael (founders) at our previous companies, and we saw how well it performed. For us it was an easy way to get started, not worry about performance for a very long time, and just be able to focus on that MVP and making sure we just offer the functionality we wanted to build, without having to worry about “Will it run everywhere? Will it scale?” and all those things. For us it was probably the number one motivation.
I think for Rebank it was definitely around the simplicity of the language I really liked, and the ability to onboard engineers, work in a really simple way… And speed, obviously, but as well with what I’d call high-risk apps like finance, medicine etc. where the integrity of data is really key, type safety was something that we liked about it as well, which was really important for us…
You didn’t wanna break things with your bank?
Yeah, that doesn’t usually go down very well with customers. We try not to do that.
On the segment side it’s very similar. We deal with medical data, and we deal with huge datasets, and Go - I knew from my personal experience, I did several hobby projects with it, and I couldn’t say any bad words about this technology. On the other hand, I was kind of burned out with a lot of scripting languages where I can find my way around, but a couple of months from where you write the script or where you write your program, the dependency hell kind of gets back to you and you have to deal with all those libraries that are missing from system to system…
And on the other hand, the binary coming out of Golang - I can run it now and I will be probably able to run it with no modification five years from now, which is from my perspective great. And you know, building a technology for a startup knowing - just like Ramiro said - that performance issues won’t exist for a very long time… And the scalability of the technology made Go a natural choice.
Awesome. Josh, if I recall correctly, Hightouch is using – I think you’re using Go some, but I think you’ve used Go in the past, and I think you’re mostly Node in Hightouch… Is that correct?
Yeah, I’m kind of the exception here. We’re using a combination of Go and TypeScript, and we’re kind of trying to figure out what the right balance is between those things. A lot of our [unintelligible 00:06:51.08] logic is written in Go; a lot of our auxiliary microservices that are more like systems programming kind of things, like deeper in networking, and things like SSH - we use Go for those things… And then we have a pretty big integrations library; our business is very integrations-based… So for those things we choose TypeScript, because we need to hire a lot of engineers on that side of things, and we kind of felt like a) it’s actually a little bit faster to write the integrations in TypeScript. A lot of the times the SDKs we’re interacting with have Node SDKs, so they don’t have anything for Golang… So for various reasons, our integration catalogue is written in TypeScript.
So a lot of it for us was just – we were familiar with it, we’ve really liked using it in the past, it’s worked really well… Actually, a lot of it kind of just came down to personal preference… But I think the typical pros of Golang really apply to us, like the ease of deployment… It’s really cool that you can just build a static binary, throw that in a from-scratch container, and you can deploy that without any base image… All of those things are just like huge pluses for us as well.
[08:02] I think on the recruiting front too it’s nice for Go, where I think a lot of engineers were interested in tough distributed systems problems, you know like systems programming… I think a lot of those types of programmers have a preference towards coding in Go, both because they wanna learn it more, and they think it’s the right tool for the job… So that’s another big plus to that as well.
So almost all of you mentioned recruiting in some way or some form… Which is interesting to me, because one of the complaints I’ve heard is that you can’t get that many Go engineers because not that many people have used it at this point. So when you guys are building a startup and using Go, how do you combat that? Is it just hire engineers who don’t know Go and train them? Is it just get people with a little bit less experience? What options are you looking at?
On our side, my experience is actually quite interesting… So while it’s true that Golang is not as popular as other technologies, I also noticed that the community is pretty strong, and actually people who program Go seek other people who program Go, because it’s always nice to geek out about commonalities and ways to solve problems.
In our case, for the full-time employees we actually found people who loved Go as much as I did - and we have a great, strong team now that basically resonate around the same technology… But my experience also around internships was very interesting. Segmed benefitted a little bit from the pandemic, because a lot of interns who were lined up with internships in the big technology companies got those internships canceled, and we decided to snap the talent out of there and basically bring them on board with Segmed… So we got a lot of talent from local universities here in the Bay area.
In the university circles Python is the most popular, but I saw that our interns took less than a week to actually master the basics of the technology and were able to start producing valuable contributions pretty much right away… And I hope that I converted some of those people to Golang permanently. So from my perspective, being able to master this technology really quickly is very important, and it seemed like people didn’t mind.
Yeah, the market is definitely not the easiest in terms of finding Go engineers… However, I think great engineers pick up languages really easily, and are language-agnostic almost… I think across the Stack Overflow surveys etc. Go is consistently on the top of the list of languages that engineers want to learn in the next 6-12 months. I think we’ve had a lot of luck with hiring really great engineers who didn’t come from a Go background, but were interested in learning it, and because of the simplicity of the language, they were just able to pick it up, and they deploy into production in days, type things.
That makes sense. Ramiro, do you have anything you’d like to add?
Yeah, sure. I mean, we’ve gone through a similar experience, where for a certain class of engineers the fact that we’re mostly a Go shop was actually very appealing to them. Some of our hires were like “Yes, I want to learn Go” and they come from like a Java background, or other service-oriented languages… And that became a really good selling point, of like “Hey, you get to code in Go all day.”
And the other thing that worked really well for us is Kubernetes is kind of our top integration point, and that codebase is all Go. So the community itself is very Go-driven, so that made it easier for us to pick up both contributors for our open source projects, as well as employees from that pool of [unintelligible 00:11:30.29] learned Go because of that. So that was something that ended up being very lucky for us.
[12:06] The core pipelines of our application, the more difficult systems programming problems - it’s just a different kind of engineer on our team. Those engineers tend to prefer to write Go than TypeScript. It’s also just a better choice, too.
But yeah, we did find that most of the engineers on our team outside the founding team, actually, that work on those types of problems - they didn’t have prior experience with Go, so I’ll just echo what everybody else was saying here; it’s an easy language to learn, and I think because people want to learn it, the combination of those two things just makes it so that anybody coming in with prior experience in systems programming - it is a plus for recruiting, even if they didn’t actually have prior experience with it.
So that’s really one of the best things about Go, is just how fast it is to pick up a minimal working subset of it. It’s easy to read too, so if you join a company that has a very large Go codebase, it’s pretty easy to hop in and learn the best practices about the language, because it’s just so simple to parse… Whereas I feel like all the TypeScript codebases that I ever looked at are snowflakes, and I think it’s kind of hard to grok how should you be doing stuff… Whereas with Go it’s a lot more standardized, so it makes it a lot easier to learn. I don’t think you have to seek out engineers who already know Go; you can just seek out people who want to learn Go, and I think that tends to work pretty well.
That makes sense. I guess the next question I’d have is one of the complaints I’ve seen from people who are just picking up Go, especially coming from like a TypeScript, or one of those languages that have all these libraries and tools out there for building anything web-related is that they feel like they’re reinventing the wheel… And with a startup, I think a general complaint people might have is that it might feel like it takes longer to get something shipped. Onboarding would seemingly be harder if everything is built differently, whereas if you were like a Rails shop, all Rails apps hopefully look similar. So I guess can you guys sort of speak to that? Was that the case? Does it feel like you’re reinventing the wheel, or is it something where you’re actually customizing what you need to customize, so like that level is right?
I’ll talk about speed first. With high-risk – I keep saying high-risk; like finance, medicine, anything where the integrity of data is key, speed of development is ultimately a function of ease of development, but also confidence. So you get the speed with getting rid of type safety etc. but you lose the confidence, and then you have to spend a lot of time building that confidence with unit tests etc, which take time to build and time to maintain as well. So I think that’s a big part of it.
When I was learning Go as well, I was doing Node.js as well… And this was like pre-TypeScript etc. as well. When you do start writing in Go, and especially in a startup, you look at a problem and you think “Okay, I’ll just quickly Stack Overflow this to see how to do this.” Like, really? Is that it? It’s like 15 lines, and it might be one line in something else… So there is a little bit of that, but I’ll take that and the expressiveness over the things that you lose with that, and not being able to move as quickly and onboard engineers as quickly.
Yeah, I would like to extend on what Simon said, because we kind of went through the same in Okteto. I think there’s a misleading boost you get at first with things like Node, where you find a library that just does exactly what you need… I like the verbosity of Go, because (touching on what you were saying before) it kind of forces the developer to be more intentional on what they’re doing. For instance, we wrote an SSH server for some of our internal components, and if someone had to express very carefully what the server is doing, what it takes as an input, serialization, all those things - it makes it a lot easier when anybody else is looking at that codebase to understand “Okay, this is what’s going on. This is what we’re trying to do.” And that as a product and as a company, as you have more people, has this compounding effect, where - sure, the first developer maybe it took her an hour instead of ten minutes, but then every other developer is not spending hours trying to figure out what is [unintelligible 00:15:40.10] supposed to do, what is this call that’s hidden here, and all that at the end pays off tremendously just in having everybody onboard quicker, understand the codebase better, and be able to react then and implement on top of it as we build new stuff. That for us has been one of the secret advantages of building Okteto in Go, compared to what I’ve done before on Python, PHP, Java and other platforms.
[16:09] It’s not gonna be a secret if you’re telling everybody…
It’s a secret I want everybody to grasp and then use for their own benefit, too.
I think it comes down to the kind of programming that you’re doing, how much the repetitiveness will bother you. I think if you’re doing pretty complicated systems programming where you kind of do want the verbosity, you really wanna think through a lot of edge cases, and there’s not like a lot of repetitive programming, it’s like difficult one-off kind of work, I think the verbosity of Go is actually a good thing. I think it helps you think through those edge cases, and you can be more sure that you’re actually handling all of the errors. I think the way they handle errors, despite the common complaints against it, it really does enforce good habits, that help as you scale to a large codebase that has to have very high reliability.
I think in the places where it might fall a little bit short - I do find for CRUD, for general backend development, I think you can move faster with TypeScript/Node in a way that doesn’t really detract too much from reliability, or bugginess, and that kind of stuff. So I do think there’s some merits here, where you didn’t have a lot of complicated systems programming going on, or things like that. There’s some benefits to choosing Node there.
At the same time, I think Go’s parallel programming also makes it nice to do things like running background services, and even simpler services, so that’s kind of nice… But yeah, I’ve found Express easy to work with… And I don’t think there’s ever been something in the Go ecosystem where a number of lines of code does the same thing. I also don’t think it’s the wrong choice, even if you’re adding verbosity to it. I think it’s still, for most things, worth choosing Go.
I think for us the exception was – it was [unintelligible 00:17:43.23] but the exception was in our integrations codebase there were just so many lines of code compared to the rest of the codebase. We had this 10% that’s very difficult, that we chose to write in Go, and the 90% scaled out stuff we chose to write in TypeScript, because the time-savings for the verbosity is actually worth saving there. It’s not as critical as that 10%, and so it’s just kind of a trade-off of like speed versus reliability, in some sense… But I think for most startups we don’t have this scale-out integrations problem. If it’s just general backend development or web development, Go should be fine.
Yeah, I need to second what Simon and Ramiro mentioned… There is a little bit of a downside on Go not having enough fancy web libraries. For example from Segmed’s experience, we are Go from day zero, and web authentication is something that we knew we had to have custom-built, because we want to have users, and groups, and we have two types of users… So essentially, this feature grew, and I really wanted to have a library to give me this functionality. But when I looked around, there is not even in other communities - other programming languages - a readily available something that would work for us… So we would have to develop it ourselves anyway.
My experience is that if I tell the engineer “Everything is in this directory. We have the source code here. Just go and study it”, they will do it. But when you have a huge library that is a hundred thousand lines long, because it needs to encompass every single person who uses this library, the amount of time and study that they have to put in - it’s just ginormous.
So there is a little bit of element of copy and paste, I guess, and redevelopment in the Go frameworks… But I feel like overall as a company who is developing something, you want to have this understanding of the codebase from the point of view of a software engineer, and having them understand every single line of code.
We are in a weird space, we work on the medical data, which is not like a go-to solution for Go… And I work with engineers who had to help out the external developers of the medical imaging library, and this task was always the most time-consuming, the most complex, because not only you have to involve your engineer, but also the remote engineer, and make sure that they both agree on what you want to get, and put a lot of cases that maybe sometimes you didn’t even need them, but there’s an external library, so you have to encompass the whole community… This takes so much more effort, where if you are a startup, you really care about this.
[20:20] Yeah. I think I have to agree with all of you. For me it’s interesting that most of the times when people make those complaints, it’s when they’re learning the language and they build three of the same thing. But realistically, when you’re building a company, you aren’t gonna build a CRUD system four different times as you’re figuring out how things work. You’re gonna build exactly what you want once, and then you know that’s exactly what the code does… Whereas, like you were saying, Adam, if you pull up a library that does authentication for everybody’s use case, it’s really hard to understand the code, because it has to satisfy everybody’s use case rather than your specific needs.
Alright, so I guess my next question is a lot of you mentioned that you have hired and trained people… How about did you know Go when you actually decided to build a company using Go?
I would say we knew Go pretty well. My first job where I did Go was at Rancher Labs; they built everything in Go there, from operating systems and mid-systems, to Kubernetes controllers… So basically everything there was Go. So I had a pretty extensive background from there.
I went to Segment, where we applied Go to a different domain, which is more like data processing and pipelining, and that kind of stuff, so a lot of queuing and reading from Kafka, and that kind of stuff written in Go… And then my co-founders were also from Segment as well, so we have pretty substantial background working with Go… But yeah, ever since then, I think we’re the only ones that have worked on it prior, and then all of our new engineers since then have either worked on side projects with Go, or just dabbled with it, but they’d never actually worked on it professionally. So we had pretty good experience coming in, and then everybody since then is kind of new to it.
Yeah, I think it’s similar on my side. I had the biggest amount of experience in Go, and my co-founders kind of leaned on me on the technical decisions, so the decision about Go kind of came naturally to me. Before, I built a fair amount of bigger projects with Go, so I knew what I’m getting into. The only concern was the medical space and the lack of libraries, but I explored the space and I saw different companies building projects with Go, so I kind of felt comfortable because of that.
The team expertise grew as we started to hire more people, because they all brought their own little toolsets and toolboxes of little Go ideas, concepts, and now we all bridge it all together in Segmed… So I feel like overall our product actually grows, and evolves, and that’s really because of having more people who know the same technology.
Rebank was pretty much the first production codebase I’d written in Go. I hacked around a bit with it, but nothing beyond that… And like I mentioned before, I was doing JS primarily for the previous 3-4 years. Looking at the language, what we thought was important - I was happy with that decision. I also saw a lot of companies that were kind of similar to us, and I spoke to some of their engineers about why they chose to use Go, and made the decision that way.
[23:58] I think generally it’s probably not best practice to build a company in a language that you’re not very familiar with, but it helps that Go is simple, it’s easy to pick up if you have a software background… And again, the trade-off between some maybe hiccups at the start around learning the nuances of the language were worth the benefits to us, and I’m happy with that decision.
Whenever I was prepping notes for this, I’d actually written down a little note that said “Most of the time I wouldn’t recommend starting a company with a language that you don’t know…” [laughter] But I actually put a little disclaimer there where like “Go might be the one exception for me”, because it’s something where I feel like you pick up enough quick enough that it’s okay to do that.
Yeah. One of very few exceptions, I think… Yeah.
Definitely. I’ve tried the same with other languages… It doesn’t go well. For us it was a mix. Our CTO, Pablo, he used to work at Docker, and Docker is almost 100% Go. At least their backend, and their cloud, all that stuff. My experience was less intense. I did a lot of hobby projects in Go. I had worked for Atlassian, and my team there was very focused on Java and Python. But even internally, I had a chance to build some early prototypes in Go. But what we did that kind of helped is that before starting the company, we started an open source project. That was in Go, so probably the first year while we working on that, that’s when I got really my intensive course on Go, and best practices, build process, all that, and that was, as everyone said, a lot easier to grok compared to other languages. So it was a very fun experience.
Also for me it was kind of fun to learn something new. As we were picking up building this idea we had for Okteto, it was fun to also find this new language to express it on. That was a part of it for us as technical founders. Being motivated was also an important part, especially in the early days, when you were trying to figure out how things should look like… You wanna keep it fun, and for us, coding in Go was actually a lot of fun.
Yeah, that makes a lot of sense. So I guess this is more directed at the people with less experience, but app structure is something that comes up a lot. It’s a question that I see countless times. People say “How do I organize this web application?” or whatever application it is… So I guess, Adam, you had said that your team leaned on you heavily… Was this something where they had to come to you pretty frequently, to ask “What do you suggest for structuring this?” Or how did you handle that?
Yeah, so I gave the idea of the general structure, like how I would like things to look like. We also had a couple of reference web applications that anyone can look up and find on GitHub… But overall, our application is, I would say, two pieces. One is a data pipeline, which is a beast in itself, because it’s a little different to whatever you can find out there… And the web app. And the web app has the usual structure of a REST API, with a logging interface.
So through just the communication of a readme file and just explaining the architecture, it was pretty clear what the building blocks are. And once you put the structure in, I think just following the structure is much easier for the engineers.
The bigger changes came when we scaled up the team, where we had to do some refactor… But these were cosmetic refactors that were not around changing things in a very drastic way.
So I would say even though you don’t have a usual MVC structure in the Golang projects, most of the people intuitively when they got a little bit of experience in building any sort of like a more complex system, they kind of understand what the structure should be. So of course, maybe layering is different, everything is in one directory, and the packages are not from day zero, but it’s not that the source code cannot be refactored in like a day or two to make it more modular, more pretty, split to the library.
What I like about Go is that it actually suits perfectly the startup world. The functionality you need, you always need it yesterday. You can put it in, and making it nice comes later… And I really appreciate it, because I really don’t like the frameworks where I need to study hundreds of pages of the framework documentation just to put something in, because I have to follow a certain structure.
[28:13] So I’m kind of like a software rebel. I really like to do things the way I think they should be done, and if there is a painful point where I need to refactor it, I found refactoring in Go to be pretty easy, and putting things in the right places is not an issue, so I really like it.
Okay. Simon, I’m gonna change this up a little bit… So my question for you is related, but - coming into Go, things like interfaces and how you basically write more generic code, I guess, those things are different. So coming in new - was that something that was a challenge for you guys to pick up while you were also building a company?
It was, in a sense, because it is like a different model, like you said, but it allows you to decouple dependencies really nicely. Once you understand how to do that in an idiomatic way, and it just clicks in your head, it’s just such a nice abstraction, I think… And it’s not the typical sort of inheritance style that Java programmers or something might be used to… But once you understand the reason for that decision, it’s really nice.
Of course, learning any new pattern like that can be a bit painful, especially when you’re in a scrappy sort of prototyping phase of the company super early on… But I think once that clicks, it’s been good for us; we’ve enjoyed it.
Yeah, that makes sense. Did you guys have to refactor stuff when that did click, or did you manage to get that caught up early on?
I think like most companies, we’ve done lots of things good from the start, and we’re still refactoring things that we’re learning about now. One of the things about Rebank from an engineering standpoint is we integrate with banks and payment providers all over the world to abstract that into a seamless interface for our customers… So we are constantly re-abstracting, reinterfacing how we do that, and learning how different regions - how their bank APIs work etc. So it’s always an ongoing process, but once the building blocks are in place and you have the engineers in place that really get how that works, it’s pretty easy, to be honest.
That’s a good thing to hear here, just because we have a lot of listeners who are relatively new to Go, and I think it’s useful for them to hear that even people building startups and then building these bigger products still have to go back and learn things and refactor code… Because sometimes you’ll watch a video or a course and you’ll see somebody build the final version and you’re like “Man, how did they know to do that?” It’s like, they probably built it 17 times before they recorded it.
Yeah. And especially with startups, you have to plan for that kind of change and that kind of iterative lifestyle of a product. It’s one of the things that I think engineers from larger companies take a little bit of time to adjust to, because it is such a different style of working.
I think in some ways, if you are getting something right the first time in an early-stage startup, you’ve probably spent a little bit too much time on it… And that’s what I think Go is great for - it gives you that confidence in “This will work. This will work well enough for me to move forward”, and then refactoring is not super-painful afterwards.
I think I wanted to extend on the refactoring. That’s something that doesn’t get mentioned enough, and it’s the fact that Go is a compile language makes refactoring a million times easier. In my experience, before, in Python and some of these other languages, every time you went to refactor even something as simple as just moving a file from the util folder to its own, there was always this concern that “What’s gonna break? How many tests do we have to run to make sure this is not gonna affect anyone?”
With Go, you can just move things around, rename them, simplify whatever, and you know that if your binary built, at least the syntax and the semantics of this change will just work. And for us, as we go through this constant refactoring - for us, we started with one pattern of like a monorepo single service which runs the commands, now we’re slowly migrating to monorepo but multiple services - being able to move code around, make sure it works, without having to worry about months of pre-testing - it just makes things a lot easier for us as a startup.
[32:12] As Simon and Adam said, you are constantly iterating, learning of better ways of implementing certain patterns and all of those things. It’s something that I’m very glad that we picked Go over descriptive languages, like Node and Python. And they’re great languages; I don’t want people to get an idea that everything else sucks and Go just works… It’s just that for this specific scenario Go has made our life as a startup a lot easier.
I couldn’t agree more with the refactoring points. When I first started writing a lot of Go, the compiler was screaming and me, and it’s really annoying. But now I’m like “Yes! The compiler is screaming at me, and I know exactly what I need to fix, without having to go and unit-test everything in a backlog.” It really does help with refactoring in that sense.
So Josh, you’re the only one here who has the huge blend of TypeScript… How do you guys handle that sort of refactoring there? Do you notice that problem?
I think as you grow as a company, as your codebase gets bigger, and you have more people editing it, I think types serve as a documentation, and it makes these big, holistic refactorings even easier. So I think at all stages of a company types are just good; I think it’d be hard to find a stage in your company where you really don’t want types, unless you’re doing like a rapid MVP kind of thing; maybe it’s for those kinds of use cases. But even then, I would probably plan on adding types back in pretty shortly after something was proven out.
Going back to the folder structure, interfaces and things like that - the pattern that I’ve seen, having written Go at multiple companies, is that there is something kind of unstructured about the folder nature of Golang, like how you structure things, and there is a little bit of opinion there… But what I’ve seen is most people learn these patterns from a good codebase, and it kind of serves as documentation in itself. Rather than having to look through documentation to find good MVC patterns and things like that, what people is reference just example code and they tend to learn that way. Then they just have those patterns in their head, and whenever you’re doing something new, they just follow along with those patterns.
So I think it’s really important if you are choosing Go for your company to have a foundation in place where you have a more experienced engineer or somebody who knows Go set up the initial repository. At Segmed we actually had a lot of microservices, way more than we do at this small company… We had a generator for creating new Go microservices, and it kind of just had an opinionated folder structure off the bat, which made it a lot easier for junior developers. It enforced kind of a standard, even though because it wasn’t enforced, things still kind of diverged, but it was a good starting point.
And then to address the interface thing, I think for developers that haven’t worked in one language for too long - like if you’ve worked in classes a lot and you’re really familiar with Java, I think interfaces are a big jump from that. But at least for me, I started most of my professional programming with Go, so I didn’t have a lot of prior context and a lot of other ways of doing things, so I found interfaces to be pretty intuitive… Whereas people that came from Java, I think it wasn’t nearly as intuitive.
The other thing that I’ve found too is that a lot of interfaces for a codebase kind of act as like an index for the most important pieces of that codebase… In particular, I think if you call out “These are the most important interfaces of our application”, those tend to be very self-documenting; you can gather a lot of knowledge about how a system works just through those interfaces. I think in a way that’s more clear than most other primitives other languages have.
I actually think of all the things that Go has, I would say interfaces is my favorite concept. It’s just very minimalist. It’s one thing that was handled very well, and I think I appreciate it in Go the most. TypeScript has it a little bit, too; it’s a little more complicated and not quite as simple as Go, but… I’m kind of [unintelligible 00:35:53.17] simple interface is kind of like picking up another language as well.
[35:58] I have to completely agree with that. I think interfaces, if they’re defined well, the main staples of your codebase, can be so good that the documentation is just there in the interface, it tells you exactly what it’s gonna do and everything… And it’s actually to the point where when I write implementations, sometimes I’m annoyed that it’s yelling at me to actually document it… Because I’m like “Just go look at the interface. This is where all the real documentation is.” All this really is – it’s using some specific technology to implement that, but realistically, that shouldn’t matter right now. I don’t know, at times I wish there was a way to just write – instead of having those lint warnings, just have something that says “Just go look here for this. This is just an implementation of it.” Because sometimes you don’t wanna sit there and document every single method if it’s just “Oh, this is an implementation of X.” It’s pretty boring then.
Alright, so the next question I have is related to hosting and going to production, that sort of thing. When you guys were choosing your language and deciding to go with Go, was things like cost, performance or even just like your hosting environment a factor? I ask about hosting environment because weirdly enough, Mat Ryer, one of our other panelists, originally started using Go because he went to App Engine and he wanted to use it, and of all the choices of languages they supported, Go was the only one that he was like “Oh, I wanna go learn that.” And Go wasn’t even at v1 at the time, but that’s what got him into Go in the first place. So I’m curious if that sort of thing had an impact on you guys.
It definitely had for us. One of the important things that we wanted to do in Okteto was [unintelligible 00:37:26.15] and we knew the developers use Windows, Linux, Mac, all different architectures… And early on, as we started building [unintelligible 00:37:36.26] we got a lot of Windows users using Okteto. So early on for us it was the fact that with Go it was very easy to build these self-contained binaries that worked on Windows, on Linux, on Mac. Now we support x86 and ARM, all that, without having to significantly alter our codebase, our practices; it was a big driver of going to Go.
And same thing on the API backend side, where (as someone said already) you build a container, no OS, from scratch, small binary, and it just runs your API - that, compared to anything I’ve done before, makes deployment, production or reproducing issues a lot easier. You can clearly tell that the early engineers of Go had gone through this program before, of maintaining high-scale services, different architectures… And they built Go in a way that really minimizes, it really eliminates a whole class of problems that I’ve had to deal with before in previous teams and companies. That for me is another thing that whenever I speak to customers or friends about Go, definitely that comes up as like “Hey, we were able to support–” When new Macs came out, we were able to support M1 by just adding another target to our build script. That was it, it just worked. And that’s something that I don’t think you can say of many other languages.
Yeah, like Ramiro said a little bit here, it really depends on what kind of software you’re either shipping or deploying. I think particularly if you’re building CLIs to run on laptops, if you’re building agents that run on servers… At my last startup we were making software that ran on remote edge devices, things like Raspberry Pi’s and lower-power devices… So having the ability to produce a very small, static executable was very nice; something that was low-memory, low-storage on disk - that was pretty essential. I couldn’t imagine shipping anything written in TypeScript to a Raspberry Pi. I mean, it could be done, but it’s not the ideal thing… Whereas now, we’re a B2B Saas that’s hosted entirely in the cloud, and we don’t have any agents, we don’t have anything running on laptops… So if Golang compiles binaries that are like 5 GB, it wouldn’t even matter to us. The advantage is not as big here.
[39:53] But I still do appreciate the fact that it’s just kind of default nature to ship a static binary. I think for other security reasons that’s pretty nice. I think from-scratch containers, when you can use them, it’s really beneficial, because there’s less noise and security scanners, which saves a lot of time investigating issues that aren’t real security issues, they’re kind of just triggering the security scanner; so it’s kind of nice just to turn those off blanket by using a from-scratch container.
But other than that, I think Go is nice. But if you’re shipping to the cloud, you probably won’t see huge benefits here. I would say it’s above the average developer experience for deploying, but nothing too game-changing if you’re just running everything in AWS.
I can say that that’s not always true…
Yeah, that’s fair enough there… [laughter]
Only because I’ve dealt with – early when I was founding a startup I used Heroku and Rails, and the issue we ran into was just that we had a lot of web requests coming in that basically we had to go ping other servers and wait for them, and Rails was just not good at that… And the whole way Rails works is there’s one server per request, and you can spin up multiple servers in a single Heroku Dyno… But it’s still really slow as a result. Whereas a single $5 could do what $60 or $80/month was doing on Heroku with a Rails setup. It was just one of those things where just our specific use case, because it wasn’t heavy processing, it was just waiting on stuff…
So there are some cases like that where I’ve definitely seen, at least in my side of it, I’ve seen that the Go stuff is much easier for me, scaling-wise. Josh, when you guys are talking about building, another case that I’ve seen a lot is on-premise stuff. I don’t know if any of you guys have to do on-premise, but I’ve seen several companies that when they’re like “When we have to go on-premise, it’s nice with Go.”
I’ve heard other startups in the past talking about like when they’re shipping something on-premise that’s in like Ruby or Python, they’re looking for ways to obfuscate their code, which all of a sudden is a whole other ball game… Whereas with Go, I don’t think you really have to worry about that as much.
Alright, so Adam - now that I’m done talking; sorry - when you guys were choosing Go, was performance a factor, or did hosting or any of that stuff come into play?
When we started, performance was actually a factor, because after doing a little bit of an evaluation, what the whole space of medical data is all about - it’s actually about huge datasets. Just to give you an understanding, we deal a lot with MR or CT data, computed tomography, so it’s a lot of images, and each of these images can be half a megabyte, or up to 2 MB, and there is like hundreds of them just for one exam of one patient. We are talking about hundreds of millions of files. So being able to actually seamlessly do parallel processing, it’s amazing when you compare it to what you can do with Python and Ruby, and fully utilize underlying hardware.
So I kind of loved it from the zero, I would say… And that was a huge factor for me. Of course, nowadays the popular understanding of parallelize means that you would just go distributed right away; but for this early first year when I developed everything myself, on my own laptop, being able to do it in Go, on your own computer - the comfort of doing this is great.
And while we didn’t care that much about where we will deploy it, of course everyone wants to just go with microservices at some point. But early on, it’s just easy to instance, where I spin the process and it just works for us, and that’s the job that we’re supposed to do. So that was great. But what I would like to say is we actually have to be on-prem, and just like you guys said, I feel like Go with on-prem is like a match made in heaven; not being able to do it in other technologies is a huge obstacle to overcome… And you pretty much have to – I don’t know if I could do it myself, putting everything in containers, deploying it, figuring out the deployment pipeline on containers… I think it’s still much more sophisticated than just copying the binary over SSH and just spinning it by hand… And this you can do in Go. And I think it’s great, because people who will use - for example, we have a CLI command that we would like our partners to use; it’s a huge advantage of Go, and most of the time when it compiles on Linux or Mac… I guess on Mac and on Windows there are problems with signing those binaries, which I think we haven’t yet solved, and at some point we’ll have to actually solve it… But on Linux, being able to SCP a binary and not worry about our IP leaking to our data partners - it’s amazing. I actually loved it from day zero, and I think that was a huge factor of me picking the technology.
Not a huge amount to add on. Performance was definitely important for us, looking at our sort of expected use case around having to transform a lot of financial data in real-time, and thought Go was a good candidate for dealing with that. In terms of hosting, the first version of our production environment went live like two years ago. I think the platform support for Go by that time was pretty well-matured. We still came across a few tools etc. that don’t have native SDKs and we have to roll something, but it’s pretty few and far between, I think, nowadays.
We host everything in the cloud, so we don’t have a huge amount of complexity there. Like Ramiro and others said, worst-case you can roll up a static binary and put that somewhere. It’s much more of a concern or a benefit really when you’re doing on-premise, but we don’t have any on-premise, at the moment at least.
So we’re gonna go into unpopular opinions here in a moment… But before then, if there are people out there who are considering building a startup with Go, is there anything any of you would like to add, or any last tidbits before I jump into this unpopular stuff?
Just do it. Do it. If you’re thinking of building a startup, do it. If you wanna do it in Go, it’s a great choice. You’re not gonna regret it.
[47:41] Yeah, I feel like there was one point in the company pretty early on where we came up with an idea Wednesday, and Thursday we had a meeting with all co-founders, and pretty much there was software to be delivered. Basically, I decided to do it in Go, which was at the time kind of a risky decision, because I knew that I’m kind of by myself in there. My other co-founder is an expert in AI, and I knew that the web app development and the service development would be all on me. And by Monday early morning, I actually pulled it off with very little problems because of just great documentation, great support, ability to just do this brutal deployment that is pretty primitive, but works and does the job… And I feel like the experience of anyone starting a company with Go will be very similar. You can get off the ground pretty quickly. You’ll be a little bit frustrated because it’s not maybe as easy with other tools, but long-term, when you think about having the startup for years to come, having your own source code everywhere, it’s actually a great advantage.
I’d like to add one more thing; it is not all good. Definitely, the one advice - because we were kind of burned by this early on… It was kind of trying to figure out which integrations you’re gonna be needing early on, and figure out if they have good support for Go… It’s not that big of an issue today, but maybe two years ago there were a lot of very famous SaaS companies with no SDKs in Go, and you had to build a lot of REST requests by hand, which was not ideal. Now it’s better, but still, there are certain SDKs, like the Stripe one, for example, where it is a lot harder to use on Go than it is on Ruby or Node.
So if you’re gonna build something that heavily depends on a specific integration, do make sure that they have a first-class SDK for Go, if you’re going that route.
Okay, so who wants to start with unpopular opinions?
I’ll start, I’ll start. For me, what I always discuss in Go land is that I believe that the whole not having generics is a good thing for Go, and that there’s only one way of doing things is really, really good. Everytime there’s a discussion on introducing another way of dealing with returns, or errors… Like that pattern of if err!= nil, then do that - I know it’s repetitive, but I love it. Going back to what I was talking about earlier, it makes your code a lot more declarative, intent is clearer on why you’re doing things, so that is something that I hope that the people who are working right now in generics - I wish they would not do it. I think now it’s a done deal. But if they do, I hope that we don’t lose on this one way of doing everything; that’s one thing that I love about Go, that when I was coding in Python gave me a lot of trouble. There’s one way of writing to disk, and that’s great; and then everybody follows that pattern. That is something that I hope sticks around for a while.
I feel like I could play devil’s advocate here and say the way we currently have it without generics I feel like leads to people using multiple generation libraries that all work a little bit differently, to sort of generate types to do the things you want… Whereas one of the upsides I’m hoping of generics is that there’s a lot of common data structures that just sort of we get one way of doing them, and those are hopefully in the standard library or someplace, some good reliable source… And I’m hoping that sort of takes away all those, but I also completely understand your perspective of people using generics for a lot of other stuff where they don’t need to could potentially give us ten different ways to do things that really don’t need ten ways to do things.
[52:01] That’s my concern. If you look at other languages – it’s a discussion of what should be part of the standard language library and what should be something optional people can pull, and that’s where I feel like generics is always just kind of like “Oh, we really want this in the language.” It’s gonna make a lot of things more complicated. And there’s a use case, of course, but it’s like, “Do we really need it?”, or can we just like – I’m a big fan of copy-pasting code around. That’s another unpopular opinion. I think that people overestimate the value of super-simple, abstracted-away code. Of course, it depends on your use cases, but that’s where for me it’s like you just copy the structure and do it again on other things works well. That’s what we do internally and it works well for 90% of our use cases.
I can definitely agree… I understand a lot of that sentiment, where copy-pasting works for a lot. I guess for me it’s just hard, because data structures are something that I’ve definitely seen some more people try to implement them, and unknowingly make mistakes that would be nice to not really have there if people had built in one to use.
Alright, Josh… Do you have any unpopular opinions you wanna share? You don’t have to, so I don’t mean to put you on the spot…
I do. I think my first one is that I do agree with the mentality that copying and pasting is not as bad as it’s made out to be. Obviously, there’s a limit to that and you have to know the right place where copying and pasting is appropriate… But that’s always one of my classics too, that copying and pasting is not too bad. It aligns a lot with the Go spirit. I would say I still do welcome the introduction of generics, and I hope the culture of the Go community keeps it well-scoped to the places where it’s really needed, and it doesn’t just bubble up to encompass a lot of things and add complexity to the language… But I’m hopeful for it. We’ll see how it goes.
Other than that, even for startups, the other thing I think is a little controversial - having a mixed language stack is not as bad as it seems. There’s just always a reason to choose one language or framework or stack over another one, and a lot of times you just have different components of a company, and it just makes sense to specialize certain components for certain things, whether it’s the obvious choice, which is like frontend and backend, versus what we’re doing, which is like I think scaling out integrations is a very different engineering problem than getting our core syncing logic correct and getting your pipelines correct.
There’s a cost to having two definitions of everything, and I wish there were better solutions for that, but overall, I think if you have a problem where it makes sense to split your tech stack in two, it’s generally worth it, especially since – if you’re a startup, you probably have more senior engineers, and people who are capable of more unstructured work and complexity, so they’re kind of able to hop around between different languages.
We even have Python in a few places now, just because there are SDKs that are so much better in Python. The interop is kind of a pain, but as long as those interop points are pretty clean and there’s a way that you can separate out these different services and tech stacks, I think it can actually accelerate things. I think there’s oftentimes a bit too much emphasis on standardization across things.
For bigger companies too, I think it kind of works, where different teams use different deployment processes, different hosting providers… It’s kind of worth the speed versus standardization trade-off to have these mixed tech stacks, and I think there’s a little bit too much of an emphasis on standardization across things. I always say it’s always context-dependent, but I think in general, in tech stacks for startups people tend to focus too much on standardization versus best-in-class approaches.
Yeah, I guess my first unpopular opinion is there is a lot of pressure to open a lot of source code you’re working on. People talk about open sourcing, and a lot of engineers who joined early on think about open sourcing… But I feel like making the assumption that some pieces won’t ever be open sourced, even though they are a little silly and you could, because there is no secret sauce in there, kind of makes you put pressure where you probably shouldn’t be putting pressure; you spend more time because you want the quality to be very high, or you want the documentation to be perfect, and pristine clean, but there is no business value.
So what I encourage all the engineers to do is actually develop a little toolbox/toolset of your own routines that you can shamelessly copy… Of course, with all the respect of IP; I guess it’s from the engineers to the company, but not the other way around… [laughter] But overall, engineers don’t like to redo things over and over, and having this toolbox I’ve noticed that – I have a couple of my own repositories that are pretty much like a junkyard that I copy and paste from. It’s a tremendous speed-up in the development process, and it helps me out to get up and running much faster than otherwise.
And I guess another unpopular opinion that I have is I focused quite a bit early on on the deployment side of things. I was wondering, what is the Golang of deployment? How can I do the deployment in a really quick way? And a very interesting thing that I discovered is that when you go and read a lot of tutorials, and documentation, and blog posts, and GitHub projects is that the topic of deployment is kind of ignored. People who deploy to Heroku, they deploy to Heroku. Or people who do let’s say Lambda and AWS, they have some configuration files… But to be honest, other apps - I don’t know how people deploy them. So when I compare it to my experience like 20 years ago, when I originally started on Slackware Linux and PHP, I must say that the PHP so far is the easiest deployment I have ever seen. You just copy the files to the server and it just works… So I kind of miss that Go kind of ignored the deployment aspect, and I wish maybe Go 2.20 or something the go command will actually have a little deployment service that you can just copy the binary there and the tool will take care of restarting the service, monitoring it, reporting it, sending messages back to you, taking care of the logs… Because right now, you have to redo this again if you are deploying, just like we do to EC2 or like an on-prem service.
I’m curious if the go embed stuff that just came out will help with that in some ways… Because one of the ways I deployed it – it was like a really small app that I did, but one of the ways I deployed it was I actually… I used a third-party library at the time, but I embedded assets in everything, all under just one binary that I could build locally for the target, and just upload the file to the server and then tell it to restart, and it was like the easiest deployment process I’ve ever had… Aside from PHP, like you said, which was always – especially when you’re first learning, that was just magic, because you were just like “I just open up this FTP server and just start editing files.” But then that probably also had bad habits of “I’m gonna live-edit files on the server as a I’m learning.”
We’ve all done it.
[01:00:13.10] Never. [laughter]
And when you look at Europe, actually, the popularity of PHP in Europe is huge. What I appreciate in PHP is they never gave up. They kept pushing this technology further until there was like a breakthrough, when Facebook made this compiled version of PHP, and they said “Okay, we need to compete with Facebook”, so the performance caught up…
So if you have an app written 20 years ago, I kind of feel like with some minor changes it probably still is up and running, which is great… And I think Go is great, because they made this promise that the backward compatibility will be there always… So I kind of feel like solving the deployment would be a great improvement.
Yeah, I think embed is a good addition. In the .NET world they have this idea - and it’s come from Windows - of the Xcopy deployment of just one binary, drop it in your server, and it just works. I would love to see more of that in Go. We just move a bunch of things to embedded, and that will simplify our Docker build. Now you don’t have to add on these files, you just come up with the binary. That’d be a great way to just kind of run the binary.
I will warn you that I don’t know how go embed works, but I know that the library I was using, the only issue I ever ran into was if I had too many images, the amount of RAM it would use would bloom up really huge, because it would have all these things loaded in memory… And I was running on like a $5 DigitalOcean server at the time, and I uploaded a couple of images that were massive resolution (I forgot to downscale them), and then all of a sudden it started crashing because of that… And then when I realized it, I fixed it, but it was just like “Oh… I probably shouldn’t have done that.” I had like 30-meg files, a bunch of them that I was uploading, and I was like “Um, I didn’t want that…”
Yeah, I think that was just text files for our emails; like, our email templates - they should be fine, but I’m gonna double-check on that. That’s a good tip.
Yeah, templates are a really common one, and they’re ones that I’ve seen people get confused with, where it works locally, and then they deploy it, and then all of a sudden it doesn’t, and they’re like “Why isn’t this working?” And it’s a confusing thing, because you don’t really understand that those files don’t get built in there. Simon…
I mean, I hope this one isn’t controversial - I don’t think it should be, obviously - but TDD is not a good thing for startups. That’s mine. I think the more you spend time in an early-stage startup, the more you realize the only real thing that is differentiating you between success and failure is your ability to iterate and subsequently move fast enough. TDD adds a lot of overhead, and there are easier ways to reliably test your code at the early stages of a project that don’t have such huge amounts of overhead. It’s partly why I like Go, because the very strict type safety adds a layer of testing, in a way. There’s lots you just can’t get away with.
I try and research and argue against my own opinions, and I did this quite recently with this, and everything I read that says TDD is great for early-stage startups is written by engineers who have either never founded a startup, and have usually actually never worked in a startup either. The engineer in me is like “TDD is great.” The founder in me is like “It’s not a good thing…” For early-stage companies at least.
I feel like here is where we put a little “If you wanna check out banking for your business, go to rebanknow.com.” [laughter] “They don’t practice TDD.” I’m just kidding…
Yeah, but that’s a good point. Because it’s not binary, it shouldn’t be like “Test everything with TDD” and “Test nothing.” You have to be pragmatic, and you have to identify “Okay, what are the highest-risk workflows or activities that my app is doing?” and you should test those. Maybe you do apply TDD to those high-risk workflows, but you don’t do it as a default behavior, I think is the point.
I definitely can’t disagree with you, because I don’t like TDD in general… I use it for some things… But to me, TDD has only really fit well when it’s small, simple functions that you have an input and an output, and it’s really easy to test those. In other cases, I’m much more productive writing code, testing it in other ways, but then I might occasionally write tests for it still - in a lot of code I’ll write tests for it - but it’s not TDD, and it’s definitely not the same process that is often pitched by these people who write, like you said, these articles, or whatever, that it’s like “You need to do TDD.” And I agree with you, especially in a startup, it’s hard to build a startup when you’re spending 30% of your time (or more, potentially) writing tests and not actually getting things out the door, that you might throw away in a week, because you realize it wasn’t what you needed.
Yeah, I think that’s something that a lot of first-time founders or first-time early employees at a startup don’t realize, is that you are in a state of flux, and prototyping, and trial and error with how something is gonna serve customers or not… So you do end up having to, best-case scenario, do a huge refactoring, and worst-case scenario just throw code out. So the overhead on that is so much more painful when you’re throwing things away that you do TDD on because the cost of doing that is so high.
[01:05:13.01] Yeah, that was a big adjustment that I had to go through… Exactly what you said of TDD - the engineer in me, especially coming, before startups, from big companies… And this is a discussion I had with our CTO often, of like how much we’ve been investing. I was always trying to err on the side of more tests, but he kind of shared the same opinion you have, Simon - it slows you down at a time where you don’t know if what you’re building makes sense, if there’s gonna be a commercial aspect to it.
I think there are other ways of doing, as you said, more customer-centric testing to make sure the scenarios work, but not necessarily this 100% code coverage, every single line is tested, every variation is tested. That’s something that is one of the most interesting challenges I’ve seen, myself, and when we hire, of engineers coming from big companies or from more established products in startups, to early stage.
The absolutes, like you said, is a big part of it, where it’s not all or nothing it’s not like “Oh, we’re either doing TDD or we’re doing absolutely no testing whatsoever and shipping to everybody.” You can do small steps that’s sort of like “We’re gonna do one customer and see how this works.” It’s a much more narrow scope of potential problems. And then you can always add tests later, when you’re like “This is definitely what we want.”
Yeah. I think that’s part of my concern generally with TDD, is that it’s very – yeah, it is very absolute. If you do TDD, you have to test every single function that you write, to be doing TDD properly… And that’s not very pragmatic, it’s not high-value, and it adds huge overhead.
This probably relates some to – Adam, was it you that mentioned the open source stuff, where I feel like when people are writing something and they plan to open source, they kind of think “I’ve gotta test everything.” I’ve actually done this myself, where when I open source something, the tests are not always, but most of the time there’s much better tests on an open source project than what I actually keep internally… Because what I need to satisfy myself is not necessarily what I think everybody else might want in all projects.
Right. Of course, the challenge of contributing also to open source is that if you heat the project with these really high requirements, contributing to a project like that is very hard. You have to really allocate time, and it stops being a contribution and it almost starts to be like a full-time work. It gives, of course, a lot of appreciation, and I think it’s great that some projects are like that, but for a startup, like Simon said, there is not always the time to do it. We would rather be producing the value than making sure that this test is 99% tested. I’m okay with crashing the product if it’s in the process of adding the value to the customer. At the end of the day, the customer is who pays us, so… Of course, this won’t work when we are a hundred people and everything needs to be tested, but we are 12 people now. So it’s very different also from the size of the company.
In the past, for example, I worked for Xilinx, where we made a Silicon chip and if you need three weeks to think of a function to make it pristine, clean and perfect, just go ahead and do it; don’t even ask about it, because the quality matters so much. At the end of the day, it’s going to be [unintelligible 01:08:17.26] out and if you have a mistake there, it’s going to be millions of dollars or losses. In a startup it’s very different. You may lose a customer, but you still can wiggle out of the problems and try to mitigate all the issues that you have in the source code.
Alright, thank you for that, Adam… And thank you Simon, Josh, Ramiro. I think we are out of time, but everybody, thank you for listening in to Go Time. If you guys have any questions or want to talk to any of these founders, you guys are all on Twitter, so I’ll make sure your Twitter handles are also on the episode. Feel free to reach out to them, ask them some questions. They’ve all got lots of experience building these startups with Go, and I’m sure they’d be happy to help.
Our transcripts are open source on GitHub. Improvements are welcome. 💚