Adopting Effect at Zendesk with Attila Večerek
#1: Adopting Effect at Zendesk with Attila Večerek
In this episode, Attila Večerek, Tech Lead and Staff Engineer at Zendesk, joins our host Johannes Schickling to discuss how Zendesk incrementally adopted Effect in a polyglot environment with a large codebase.
In this episode, Attila Večerek, Tech Lead & Staff Engineer at Zendesk, joins our host Johannes Schickling to discuss how Zendesk incrementally adopted Effect in a polyglot environment with a large codebase.
Effect is an ecosystem of tools to build production-grade software in TypeScript.
Song: Dosi & Aisake - Cruising [NCS Release]
Music provided by NoCopyrightSounds
Free Download/Stream: http://ncs.io/Cruising
Watch: http://ncs.lnk.to/CruisingAT/youtube
- (00:00) - Intro
- (03:13) - Being an engineer at Zendesk
- (06:05) - Challenging the status quo
- (13:10) - Introducing TypeScript at Zendesk
- (20:22) - Adopting fp-ts
- (25:19) - The transition from fp-ts to Effect
- (31:00) - DX adopting Effect
- (37:15) - Implementing a Kafka consumer with Effect
- (42:18) - Dependency injection
- (48:33) - The power of TypeScript & Effect
- (53:03) - Onboarding developers to Effect at Zendesk
- (01:15:37) - Excitement for Effect Cluster
- (01:19:30) - Outro
Transcript
01:00:00like the dependency injection,
01:00:02like dependency management as well.
01:00:04It's just so great with Effect.
01:00:07I feel like I'm much more
01:00:09incentivized to write unit
01:00:11tests and I don't know how other people
01:00:13think about engineers at companies like
01:00:16Zendesk and like Facebook and Google, like big companies
01:00:21like how they
01:00:22deal with these things
01:00:23on a day-to-day basis.
01:00:24In the end, like it doesn't matter
01:00:26how skillful or experienced you are.
01:00:29It comes down to incentives all the time.
01:00:31Like you do things that you
01:00:33are more incentivized to do.
01:00:35So, If a language or a framework or a library
01:00:39makes something really easy to do,
01:00:42you will do it regardless, whether it's
01:00:44the right thing to do
01:00:45or the wrong thing to do.
01:00:49Welcome to "Cause & Effect," a podcast
01:00:52about Effect, the TypeScript library,
01:00:53and ecosystem helping engineers build
01:00:56production-ready software.
01:00:58I'm your host, Johannes Schickling, and I've
01:01:00been building with
01:01:01Effect for over four years.
01:01:03With this podcast, I want to help others
01:01:05understand the benefits
01:01:07and powers of using Effect.
01:01:09In this episode, I'm talking to Attila
01:01:11Večerek, a tech lead at Zendesk
01:01:14and long-term user of Effect.
01:01:16In this conversation, we talk about the
01:01:18challenges of building production-grade
01:01:19software in TypeScript
01:01:21and how Zendesk ended up adopting Effect
01:01:23in one of their main products,
01:01:25serving millions of users every day.
01:01:28Let's get into it.
01:01:29Welcome Attila to the very first episode
01:01:32of the Cause & Effect Podcast.
01:01:34How are you doing?
01:01:36Thank you.
01:01:37Thank you, Johannes.
01:01:37I'm so happy to be here.
01:01:39Uh, I'm doing pretty well.
01:01:40Thank you.
01:01:41How about you?
01:01:42I'm doing fantastic.
01:01:43Really looking forward to doing
01:01:45this podcast and to
01:01:46do it together with you
01:01:47since I think we've been in
01:01:49touch now for quite a while.
01:01:50We met like half a year ago, also
01:01:53for the first time in person at the
01:01:55first Effect Conference in Vienna.
01:01:58And yeah, really excited to do this
01:02:00together and share more
01:02:02your story of like
01:02:03discovering Effect and using Effect.
01:02:05So you're using Effect at Zendesk, but
01:02:08would you mind giving a quick
01:02:10introduction of who you are?
01:02:13What is your role at Zendesk?
01:02:14What have you done before?
01:02:16And then we can dive deeper.
01:02:19Sure thing.
01:02:19Hey everyone.
01:02:20My name is Attila, Attila Večerek and
01:02:22I've been at Zendesk
01:02:25for almost seven years.
01:02:26It's going to be seven years
01:02:27exactly this year in October.
01:02:29Currently I'm a tech lead at a
01:02:32team in the Guide organization, which
01:02:35is responsible for the
01:02:38help center part of Zendesk.
01:02:41So, if you see any help center
01:02:43articles or community
01:02:45and stuff like that,
01:02:47that's, that's what I do.
01:02:48And most recently I also got the
01:02:51responsibility of re-vamping
01:02:53our customer satisfaction feature.
01:02:55which is one of our most used
01:02:57features besides like the core product,
01:02:59which is ticketing itself.
01:03:01And yeah, I'm very excited about that.
01:03:03And that's actually the feature
01:03:05which is built using Effect.
01:03:08That sounds awesome.
01:03:09Yeah.
01:03:09I'm excited to hear more about that and
01:03:11go in depth, but would you
01:03:13mind describing a bit more of, given
01:03:15that, there are, I think,
01:03:17several thousands of engineers at Zendesk
01:03:19and not all code there is written
01:03:22with Effect, that might change at
01:03:24some point, but would you mind giving
01:03:27a quick overview of, what it means to
01:03:30be an engineer at Zendesk?
01:03:31So Zendesk is really large, we
01:03:34have many sub orgs and, or
01:03:37departments and each of them, even at the
01:03:40team level, like there are huge
01:03:41differences, we're truly a polyglot
01:03:44company when it comes to languages
01:03:46and different kinds of tech stacks.
01:03:48I still think most of our code is
01:03:51still written in Ruby.
01:03:53The company started with
01:03:54Ruby and Ruby on Rails specifically.
01:03:57We have two large Ruby monoliths.
01:04:00both of them I have to
01:04:01interact with from time to time.
01:04:03That's, that's always
01:04:03an interesting
01:04:05experience, especially
01:04:06when you've been working with Effect
01:04:08for a while and then you have to go back
01:04:10to Ruby and like, Oh, okay.
01:04:12Things are a little bit different here.
01:04:14But besides Ruby, there's also like a
01:04:16ton of Java, some Scala, some
01:04:20Golang, yeah, and obviously
01:04:22TypeScript mostly for
01:04:23front-end, but, we
01:04:24have also some companies that we acquired
01:04:27who brought in a lot
01:04:28of backend TypeScript.
01:04:30And yeah, we have some, some of the
01:04:32TypeScript on the
01:04:33backend in Guide as well.
01:04:36So it sounds like Ruby has always
01:04:39been the majority of code and still is.
01:04:42Is there any technology, any
01:04:43language that you feel like is really,
01:04:46on its way in and might replace Ruby
01:04:49as the primary
01:04:49language maybe at some point?
01:04:51That's really hard to tell.
01:04:52I don't think Ruby will go away ever.
01:04:56These huge monoliths, they're here to
01:04:59stay with us for
01:05:00until Zendesk will exist.
01:05:02I'm pretty sure of that.
01:05:04We had some initial thoughts of breaking
01:05:07the monoliths down, but it's really
01:05:09hard to justify these efforts, when
01:05:11it comes to product and, and like the
01:05:14business needs of the company.
01:05:16So for all the startups out there,
01:05:19like if you start with a technology
01:05:21and you become like large company and
01:05:23really largely successful, all the
01:05:26tech that, that you accumulate for all
01:05:28those years, that's going to probably
01:05:29stay there for, for a while.
01:05:31So yeah, maybe, maybe think about twice
01:05:34about what you start with.
01:05:36Not all this tiny decisions, but like the
01:05:38major ones, it's, it's good
01:05:39to put some thought into it.
01:05:41Oh yeah, for sure.
01:05:42But I mean, Zendesk is a very,
01:05:45profitable and very great company.
01:05:48So I suppose it wasn't
01:05:49the worst stack decision.
01:05:51If it led Zendesk to this point
01:05:53today and given that you, are also
01:05:57now leaning more into TypeScript, I think
01:06:00there there's, you can probably use the
01:06:02best tools for the appropriate jobs.
01:06:05But speaking of TypeScript, I think this
01:06:07is one example of like a theme
01:06:10that I'm noticing, which is that you seem
01:06:12to challenge the status quo a bit.
01:06:15when it comes to engineering
01:06:16within Zendesk where you see, okay,
01:06:19this is how things are done.
01:06:20And then, you seem to, send some
01:06:23ways to do things possibly better.
01:06:26And this is, I think we're using some
01:06:28colleagues, if I understood
01:06:29correctly have, at some point looked
01:06:32at TypeScript and said, actually,
01:06:34this is a bet worth making.
01:06:36Can you share that anecdote?
01:06:37Yeah, sure thing.
01:06:38So maybe just to understand for maybe
01:06:41people who are not familiar
01:06:42with Ruby on Rails, Ruby is a
01:06:44dynamic programming language.
01:06:46It's great for really one
01:06:49engineer or tiny teams that know the code
01:06:53base by heart, it makes
01:06:55them really efficient.
01:06:56So productivity wise,
01:06:57it's, it's terrific.
01:06:59So starting with Ruby for Zendesk was
01:07:01definitely a good bet.
01:07:03It allowed them to have like a
01:07:05velocity in the beginning that was
01:07:07absolutely crucial to become successful.
01:07:10But you know, working with a dynamic
01:07:13type language, especially like
01:07:16with a heavy OOP focus where you have
01:07:19lots of like design patterns.
01:07:22I'm not sure if you have worked with
01:07:24teams where people would argue
01:07:26like, Oh, you know what, for this
01:07:28feature, we should
01:07:29use this design pattern.
01:07:31And then the other side would be arguing,
01:07:33no, no, no, uh, look at,
01:07:35switch your mentality.
01:07:36Like, you have to look at the problem
01:07:38this way and then they
01:07:39bring up adapters and whatnot.
01:07:41And DDD and all these things.
01:07:43At a certain scale, it becomes fighting
01:07:46an uphill battle all the time because you
01:07:49have to be fully aligned with all
01:07:51the people who work on the code base.
01:07:54You have to agree on these things.
01:07:56Like what are the design
01:07:57patterns that we are introducing?
01:07:58Okay.
01:07:59Are we shifting to a
01:08:00different design pattern?
01:08:01Are we re-architecting
01:08:02redesigning our modules?
01:08:04Are we taking out and
01:08:06extracting reusable modules?
01:08:08And how do we do that?
01:08:10Are we doing some, you know, some
01:08:12module boundaries within rails and
01:08:14use rails engines or some other ways of
01:08:16enforcing these module boundaries?
01:08:18So all of these decisions, like you
01:08:20really have to pull the same rope in the
01:08:23same direction and then it's good.
01:08:25But at some point, now let's say you have
01:08:27this huge monolith, which we have,
01:08:29and you have 50 people or even hundreds
01:08:31and thousands of
01:08:32people contributing to it.
01:08:34Having this alignment across the
01:08:36entire organization is really hard.
01:08:39So what you end up having is a mixed bag
01:08:42of things and, you know, parts of
01:08:44the repo, use one design better.
01:08:47Another part uses another one.
01:08:49And then there's this new design better
01:08:51that you're pushing for some
01:08:52modularization and
01:08:54then that's a migration.
01:08:56And then there's tons of migrations going
01:08:58on at all time, like five, 10, 15
01:09:02different types of
01:09:03migrations in a code base.
01:09:04And then let's say you're a contributor
01:09:06who just wants to implement like a tiny
01:09:09bit of a feature, which is necessary in
01:09:11that repo so that the other service can
01:09:15communicate with it.
01:09:16I don't know.
01:09:16You, let's say you want to emit some
01:09:18events from
01:09:19the main monolith and then over
01:09:21Kafka or over whatever message bus so
01:09:24that you can consume
01:09:25those events in your microservice.
01:09:28Well, suddenly you'll see five or six
01:09:30different examples of how to emit
01:09:32domain events, or Kafka.
01:09:34So what do you do then?
01:09:36How do you find the people, that know
01:09:39what's the current status quo, or
01:09:42will you just blindly pick the one that
01:09:45is the most prominent?
01:09:46I mean, that's, there's no problem going
01:09:48with that route either, because if it's
01:09:51the most prominent thing and let's say
01:09:53it's something that
01:09:53we're moving away from.
01:09:55You can just commit to that and it will
01:09:57be moved away from with the rest.
01:09:59But then, you know, if you pick something
01:10:01in between, then that also brings the
01:10:03risks that the people who are doing that
01:10:05migration will just
01:10:07have bigger and bigger
01:10:08headaches because now they need to
01:10:10migrate different kinds of ways of doing
01:10:13things into this one,
01:10:14one way of doing thing.
01:10:15so these are the biggest problems
01:10:17that I see with Ruby, alignment,
01:10:20constantly fighting an uphill battle.
01:10:23You introduce a new feature, but at the
01:10:25same time you introduce a bug because
01:10:27you miss something and there's constant
01:10:29action at the distance.
01:10:30You change one part of the application,
01:10:33which has some
01:10:33unforeseen or unpredictable
01:10:35effects on another part of the
01:10:37application because
01:10:39everything is reusing everything.
01:10:41That makes a lot of sense.
01:10:42So it rather sounds like you're,
01:10:45you're running into some like social
01:10:47alignment issues where you just have so
01:10:50many engineers, like an all probably very
01:10:52brilliant and with like the best
01:10:54intentions trying to design it with their
01:10:57understanding of the world.
01:10:58But if you have thousands of engineers,
01:11:00this can lead to some, some very wild
01:11:04different directions and to enforce that
01:11:06alignment, I think if
01:11:08you're, if you don't
01:11:09have a types type system at your
01:11:11disposal to help with
01:11:13that, to be even aware of
01:11:15like, Hey, here's like some divergence.
01:11:17We're unopigniated maybe, or we
01:11:19tolerate both, but even to have some
01:11:21visibility into this and
01:11:23help drive the alignment.
01:11:25I think this is where a
01:11:27type system can help a lot.
01:11:28And I suppose that is what's what has
01:11:30made you so interested in TypeScript.
01:11:33Yes, absolutely.
01:11:35So that, that was one of the biggest
01:11:36driving forces behind the
01:11:38adoption of some language
01:11:40that is statically typed.
01:11:42it has tons of
01:11:43benefits, not just like this alignment.
01:11:45Very recently, I just actually had to
01:11:47go into one of these large Ruby
01:11:49monoliths and there's a feature flag
01:11:52that I introduced and some different
01:11:54behavior for when the feature flag
01:11:56is enabled and now this feature flag has
01:11:59been rolled out fully
01:12:00for, for some months now.
01:12:03So I was looking into removing the,
01:12:06if.else branch for the feature flag
01:12:09to keep only the logic that's basically
01:12:12used now that it's fully rolled
01:12:14out and by removing that one line of
01:12:17code, I broke like
01:12:19hundreds of unit tests.
01:12:21Because the unit tests had no idea that
01:12:24there was like a dependency on some HTTP
01:12:28call somewhere down the line.
01:12:30So now I have to find like a place where
01:12:32I can maybe permanently mock this call to
01:12:37a specific endpoint for all the
01:12:39tests forever, because I
01:12:41cannot pinpoint like the
01:12:42hundreds of different places
01:12:44where this is exactly called.
01:12:46So I have to mock it
01:12:47like on a general level.
01:12:49So, so these are also kinds of issues
01:12:51that you bump into
01:12:52and using languages and
01:12:54frameworks like this which is going
01:12:56to be another segway into Effect, I guess,
01:12:58later on with the
01:13:00dependency injection.
01:13:01Yeah, most certainly.
01:13:03So it sounds like you're building
01:13:05production grade software at scale at
01:13:09Zendesk in many different flavors,
01:13:12many different technologies, but at some
01:13:14point you've introduced TypeScript and
01:13:17that's the foundation for the services
01:13:19and products you're building.
01:13:21What was that that journey like?
01:13:24So you now have a type system to help
01:13:26with many things, but I suppose it still
01:13:29has not given you the silver bullet that
01:13:32makes it super easy to build production
01:13:34grade software.
01:13:36So what are some of the challenges you
01:13:38were still facing and possibly still
01:13:40face today and were
01:13:41you reaching for Effect?
01:13:43So if I have to reflect back on the
01:13:45time when we were introducing TypeScript
01:13:47at guide for the first time, I think
01:13:49obviously what we wanted to avoid where
01:13:51all of these problems that come with, uh,
01:13:53shared monoliths. We just wanted some
01:13:56some service, which is nicely isolated
01:13:58and we have our own
01:14:00deployment schedule, which
01:14:02is basically on demand.
01:14:03We don't need to deploy it on a
01:14:05weekly or biweekly cycles.
01:14:08And then of course the maintenance,
01:14:09improvements,
01:14:10because now you have a type
01:14:11system, so if you make a change in one
01:14:13place, the compiler
01:14:15will aid you in updating
01:14:18all the other call sites.
01:14:20So that, that was
01:14:21obviously one thing.
01:14:22But we also wanted to make sure that
01:14:25we don't get into these like reliability
01:14:27issues that we were having with the box.
01:14:29So like type safety was
01:14:31really important for us.
01:14:33Then we're looking into how to, because
01:14:36there are many different ways how you can
01:14:38write TypeScript, right?
01:14:39Like you can be really
01:14:40lenient and allow any.
01:14:41Right.
01:14:42You can typecast here and there.
01:14:45The language is quite flexible.
01:14:47You can use as much type safety as
01:14:49you want, or you can
01:14:51go towards the other end
01:14:52of the spectrum and use like the most
01:14:55brutal compiler
01:14:57options that are out there
01:14:59and make it super, super type safe.
01:15:02And then you even start thinking about,
01:15:04okay, how do we do
01:15:04end to end type safety?
01:15:06Right.
01:15:06Because there are certain things that
01:15:08come out of your system.
01:15:10Like on these boundaries of your system,
01:15:12you have a HTTP request coming in.
01:15:15Maybe HTTP request going out.
01:15:17Kafka message coming in.
01:15:19Like you need to parse these and at
01:15:22the inbound of your system, you have to
01:15:26be able to work with
01:15:27it with a static type.
01:15:29Right.
01:15:30So, so how do you do all of these things?
01:15:32Rolling it manually is really tedious
01:15:34with all the type checks at runtime.
01:15:38Especially if you have like really
01:15:39complex objects it
01:15:41is really hard to do that.
01:15:43So obviously you can compose like start
01:15:45at the leaves and then
01:15:46build up all of these,
01:15:47but that's a lot of work.
01:15:48So we started looking into other,
01:15:51like maybe even, even other programming
01:15:54paradigms like with, with Ruby, like of
01:15:56course there's like a
01:15:57ton of OOP stuff, but
01:15:59then with TypeScript, we were realizing,
01:16:01oh, okay, maybe we can actually leverage
01:16:04like, some functional programming
01:16:05concepts to build
01:16:07more composable software.
01:16:09Because one TypeScript
01:16:10service was not our goal.
01:16:13We were already thinking in multiple
01:16:15TypeScript services and in the end it did
01:16:17become reality and then we wanted to
01:16:19share code in between them.
01:16:21And then how do you do that?
01:16:22Well, we came up with a mono repo of
01:16:26different libraries that we can use that
01:16:29implement like Zendesk concerns, things
01:16:32like sharded database
01:16:33clients that know how to
01:16:35connect to our sharded database and yeah,
01:16:39many, many other
01:16:40libraries like this, these
01:16:42internal ones, these
01:16:43productivity booster ones.
01:16:44So we started implementing those and then
01:16:47we're like, okay, but
01:16:48they are like different
01:16:49libraries like suddenly they have this
01:16:52library has this API.
01:16:53This library has another one.
01:16:54I want to use them in combination.
01:16:56And then you think about how to
01:16:58hype all the APIs
01:16:59in the way that they
01:17:00nicely flow.
01:17:02So that's when one of my colleagues found
01:17:04fp-ts and that sounded really great.
01:17:07Obviously it had a huge
01:17:08learning curve for us.
01:17:10None of us were really much into
01:17:12functional programming.
01:17:13I only remembered some stuff from
01:17:15university, but definitely
01:17:17have it, haven't had like
01:17:19hands-on experience and then learning fp-ts
01:17:22like people who
01:17:23learned it, they probably
01:17:24know how hard it is because you don't
01:17:27have like real documentation.
01:17:29You have like API
01:17:30interface documentation.
01:17:32What gave you the confidence to take the
01:17:35leap of faith to go
01:17:36to reach for fp-ts and
01:17:38make that the
01:17:39foundation for your libraries?
01:17:41Um, desperation.
01:17:44I don't know.
01:17:46I was just really, I think we all just
01:17:48wanted to avoid another monolith.
01:17:52And obviously we, we cared a lot about
01:17:55these tiny libraries
01:17:57that were meant to be
01:17:58shared across the different services and
01:18:00different services need to do different
01:18:03things, right?
01:18:04Like they're in a different domain. So it's really hard to
01:18:06predict what API is the right one.
01:18:09So as long as we can stick to something
01:18:11and make it
01:18:11composable, that should work for
01:18:15most of the cases.
01:18:16I mean, that was at least our idea.
01:18:18The execution was rough.
01:18:21We were iterating
01:18:22on this group of
01:18:23libraries and we followed,
01:18:25versioning a strategy that would version each library.
01:18:30At the same time.
01:18:31So even if we make a change in one
01:18:32library, we would bump
01:18:33the version of all the
01:18:35libraries just to make it easier for the
01:18:38consumers to understand what version of
01:18:40one library works with another.
01:18:41So we opted for this and then the
01:18:45iteration was so fast on these APIs.
01:18:48We just kept in introducing breaking
01:18:50changes all the time because we
01:18:51discovered new and new ways
01:18:54of using these libraries.
01:18:58And so within the span of three years, I
01:19:00think we went from
01:19:01version zero to version
01:19:0327. Our consumers were
01:19:05not happy about this.
01:19:06Let's just say this. Right.
01:19:09So I suppose fp-ts at that point was
01:19:11already quite the pill to swallow for
01:19:14you all where you convinced yourself to
01:19:16do it, but then to have other API
01:19:18consumers that did not intentionally say
01:19:21like, yes, we want to bring in fp-ts
01:19:23into our life, but that's just the way
01:19:25how you offered it to them.
01:19:28That was probably even, even trickier.
01:19:31So, but that's what you started out with.
01:19:33And I suppose you, you chose that for
01:19:35the, for very
01:19:36understandable reasons, such
01:19:38as the dream of composability and code
01:19:41reuse and making all your systems more
01:19:45resilient, but it came at a price of
01:19:48like a rather esoteric flavor,
01:19:50particularly for the ones who were not
01:19:54getting up in the morning saying, yes,
01:19:56I want to do functional programming, but
01:19:58you just want to do proper programming,
01:20:01uh, maybe in TypeScript.
01:20:03So, and if I understand correctly, this
01:20:06is where you have been kind of like
01:20:09running into growing pains of fp-ts and
01:20:12building larger systems out of this.
01:20:14And at some point you found Effect.
01:20:18So tell me about that.
01:20:19Oh yeah.
01:20:20So that, yes.
01:20:22So basically with this fp-ts we
01:20:24were trying to build
01:20:25something similar to Effect.
01:20:27We wanted to have a system which allowed
01:20:30our consumers to
01:20:32do proper dependency
01:20:33injection with all the config that we
01:20:36provided so that when they start their
01:20:38program, like if the config is wrong, it
01:20:41will just not deploy.
01:20:43We want it to eliminate as
01:20:45many foot guns as possible.
01:20:47Obviously resource management was
01:20:49another big thing that
01:20:50we were looking into.
01:20:51Like how do you properly handle like all
01:20:54the interrupt signals coming from
01:20:56Kubernetes when it's trying to kill
01:20:59or restart your container.
01:21:00These things.
01:21:02They require a lot of effort and they're
01:21:06not easy things to do, especially if you
01:21:08want highly composable solution.
01:21:11So I think one of my colleagues,
01:21:13was my partner in crime when it came
01:21:16to introducing fp-ts to the
01:21:20organization at
01:21:20large, he found Effect.
01:21:23I don't know how he found it, but he
01:21:24found it and it was maybe in 2021.
01:21:28I don't remember.
01:21:29I'm so bad with years, especially because
01:21:31it was like the pandemic there.
01:21:33And suddenly like two
01:21:35years felt like one or half.
01:21:40But around the time, it was weird.
01:21:43Time flow flew, flew differently.
01:21:46But he did found it and it wasn't
01:21:48like we were jumping on it immediately
01:21:50because at the time there wasn't really
01:21:54such a huge buzz around it.
01:21:56Like it is nowadays.
01:21:58Also
01:21:58didn't have a stable API.
01:22:02So we were for about at least a year, we
01:22:05were mostly observing Effect from the
01:22:06sidelines, we didn't talk to also no
01:22:08documentation at that point yet.
01:22:11Yeah, exactly.
01:22:12It was just another fp-ts for us
01:22:15from the sidelines looking at it, but
01:22:17it looked way better than fp-ts it
01:22:20looked like, okay, this is not just
01:22:23abstractions, this is
01:22:24also some implementation.
01:22:26Finally, something that
01:22:27makes our lives easier.
01:22:29It's like a general programming
01:22:30framework, how to build like resilient
01:22:32services and all the dependency injection
01:22:37resource management,
01:22:39configuration management,
01:22:41building the layers of dependencies.
01:22:43That's all taken care of for you.
01:22:45So, so that looked really promising.
01:22:49And as I mentioned, like for a year, we
01:22:51were just looking and watching,
01:22:53Effect and its development.
01:22:55And then later when it felt like, okay,
01:22:58now, now it seems like it's, it's
01:22:59like stabilizing
01:23:00around some sort of an API.
01:23:03We still don't really agree with some
01:23:05namings, of some concepts, which
01:23:08then also changed name and everything.
01:23:10And now it's like much, much better.
01:23:12But we were, that that's, that's when
01:23:14we started to seriously
01:23:16consider adopting
01:23:17it on some, some project.
01:23:20We didn't really know
01:23:21which project should it be.
01:23:22We didn't really want to go right into
01:23:25the migration of an existing fp-ts
01:23:27project, because we
01:23:28didn't know how to do it.
01:23:30It was a little bit weird because
01:23:32from fp-ts we had all these reader
01:23:34task, eithers, and we, we could
01:23:37intuitively see how it would map to an
01:23:39Effect, but we didn't quite understand
01:23:41how, how it would work with our flavor
01:23:45of fp-ts if you know what I mean?
01:23:47Like we built those abstractions for
01:23:49managing dependencies and
01:23:52resources and whatnot.
01:23:54Like how would that, how would we make
01:23:55the step from that to Effect?
01:23:58So what we ended up doing in the end, my
01:24:01team got this opportunity to rebuild
01:24:04the existing customer satisfaction
01:24:06feature and we are making
01:24:08it like more flexible, like it's almost
01:24:11on our end in the backend,
01:24:13we treat these customers satisfaction
01:24:15surveys as, as generic surveys,
01:24:18because like, what is the customer
01:24:19satisfaction survey?
01:24:20It's like you ask a bunch of questions
01:24:22and one question has to be how satisfied
01:24:25you are about whatever you're measuring
01:24:28against in our case, like satisfaction
01:24:30about how your ticket was
01:24:32handled by the support agent.
01:24:33But in the end, it's just a survey.
01:24:35It's a bunch of questions and different
01:24:37types of questions and whatnot.
01:24:38So it looked like a perfect opportunity
01:24:41for us to try Effect.
01:24:44Especially because there were, there
01:24:46was already like Tim Smart's
01:24:48SQL package, SQL effect, which is like
01:24:51the predecessor of effect SQL.
01:24:53So that, that was really good because our
01:24:55service needs to,
01:24:57interact with the database for sure.
01:24:59So, so that, that gave me
01:25:00a lot of confidence there.
01:25:02obviously, and now
01:25:03we're using Effect SQL.
01:25:04I'm trying to like being lockstep
01:25:08with all the development
01:25:09with Effect itself, the core
01:25:12library, and then also like all the
01:25:14satellites that the level
01:25:16one and layer one abstractions.
01:25:19So it sounded like this was like the
01:25:21initial prototype where you gave Effect
01:25:24or like the initial trial project where
01:25:26you went from observing the Effect
01:25:29development to actually getting your
01:25:31hands dirty and seeing, okay, is this
01:25:34fulfilling all of our dreams, how
01:25:36our world already got better through
01:25:38fp-ts but we've introduced a couple of
01:25:40like new problems and maybe some of our
01:25:42teammates or some of the other teams, uh,
01:25:45have a hard time with it.
01:25:46And that could be addressed by Effect.
01:25:48And so now you've adopted it.
01:25:50How did that go?
01:25:50How quickly were you up and running?
01:25:52How quickly were you productive?
01:25:54And, uh, also very
01:25:56importantly, what did other teams think?
01:25:59So before I actually get into that, let
01:26:01me just tell you that for us getting rid
01:26:05of fp-ts or moving towards something else
01:26:07is, was existential.
01:26:09Like there was no universe where we would
01:26:12be able to push for fp-ts, at
01:26:15least in our usage of fp-ts in a way we
01:26:19did at a larger scale.
01:26:21Like if we wanted this TypeScript service
01:26:23framework to fly and be useful for not
01:26:27just our two teams that used it, but also
01:26:30outside of our org for all the TypeScript
01:26:33native teams, who we acquired
01:26:35through the business deals and stuff.
01:26:37We really had to get rid of it.
01:26:38We had to find like an alternative and
01:26:40unfortunately there was like no real
01:26:44alternative, beside Effect.
01:26:46But I'll get into why this is
01:26:48actually a pretty good alternative also
01:26:50for teams that only
01:26:52use native node JS TypeScript.
01:26:55But yeah, so, after I
01:26:58tried Effect for the first time, so I
01:27:00think it was last year in June that I
01:27:04made the first Effect commit ever at
01:27:07Zendesk, getting up and running was
01:27:09fairly easy because I could get a
01:27:11skeleton of an application using our fp-ts
01:27:15based service framework.
01:27:17And then, yeah, I think one important
01:27:19thing that I need to mention is that,
01:27:22we're mostly building these services
01:27:24on graph QL and then we have graphQL
01:27:26Federation, so yeah, like lots of
01:27:29microservices, each owning their own
01:27:31domain and we call them sub graphs and
01:27:33then they compose into a super graph through
01:27:36the Apollo
01:27:36Federation solution.
01:27:38So this survey service
01:27:39was just another sub graph.
01:27:41So once I got to the point where I could
01:27:43start implementing the resolvers for the
01:27:47different graphQL objects and
01:27:49mutations and queries and whatnot, um,
01:27:51I was already, at that point I could
01:27:54finally use Effect.
01:27:56So I was using Effect in the beginning
01:27:58only at the resolver level of my
01:28:01application.
01:28:03So, so that went pretty well.
01:28:05Startup was very easy.
01:28:06And then obviously like I created like an
01:28:09application skeleton that I'm familiar
01:28:11with, and then the resolvers were Effect.
01:28:14And that nicely adapted into the
01:28:17promise based resolver because with
01:28:19an effect, you can run it as a promise.
01:28:21So that was perfect.
01:28:22And then after that, it was just
01:28:24like, okay, let's, let's start with this.
01:28:26Let's start with a simple Effect.
01:28:28Let's start with a dummy resolver.
01:28:30And then next step was
01:28:32let's add some validation.
01:28:33So we brought in Effect Schema and yeah,
01:28:36now that I mentioned Effect Schema,
01:28:37I think that's probably the
01:28:39best gateway drug into Effect.
01:28:41Like everybody needs input validation.
01:28:45Everybody that it's almost impossible to
01:28:48imagine a piece of software, like a,
01:28:51you know, an HTTP service that doesn't
01:28:54need input validation unimaginable.
01:28:57Yeah, I definitely agree.
01:28:58I mean, this is where, why Zod as a
01:29:00standalone library is also getting so
01:29:02popular, but I think people
01:29:05will see that their
01:29:06requirements will grow beyond just input
01:29:08validation where you maybe need to run some
01:29:12effectful
01:29:13code, like some, some
01:29:14code that can't go wrong,
01:29:16et cetera, as part of this validation,
01:29:17but then also critically, not just
01:29:20parsing and validating the code, but at
01:29:23some point you might also want to
01:29:25re serialize it as you, you don't just
01:29:27receive data, but you want to ship it
01:29:30over the wire to another
01:29:31service or to your front end.
01:29:33And then you're scratching your head
01:29:35because, okay, you have now this beautiful
01:29:37sod system that can validate and parse
01:29:40data, but now you want to go the other
01:29:42way around and that is impossible.
01:29:45And if you use a whatever, like you've
01:29:48created a class, a user class that you
01:29:50parse things into, and now you have your
01:29:52data expressed through like those
01:29:54classes or more complex data structures.
01:29:58And you want to call
01:29:58JSON.stringify on it.
01:30:01And suddenly stuff blows up.
01:30:03And this is where Effect Schema comes
01:30:05in and I completely agree.
01:30:07This is going to be my primary bet for
01:30:10what will be the, the main gateway
01:30:12drug that brings people to Effect.
01:30:14And it's has gotten so nice.
01:30:17I think this is where in the past where
01:30:18you've been using fp-ts
01:30:20you've probably used io-ts
01:30:21Effect Schema is written by the same
01:30:23person, but I feel like
01:30:25It's a new incarnation, of the
01:30:28same person who just made everything
01:30:29so much nicer to use so
01:30:31much easier to understand.
01:30:33So yeah, huge fan of that part.
01:30:35Absolutely.
01:30:36Same.
01:30:37I'm a huge fan of Giulio who does
01:30:39all of this, this work.
01:30:40It's just amazing.
01:30:41-big shoutout to Giulio. -yeah, absolutely.
01:30:46fp-ts and io-ts helped us so much in the
01:30:48beginning and now seeing him also do all
01:30:50of the work, for Schema at Effect and
01:30:54doing a lot of Effect documentation
01:30:55work as well, it's just, uh, yeah, it's,
01:30:58it's amazing to see that.
01:31:00So sounds like last year, last summer
01:31:02you've written your first Effect code at
01:31:05Zendesk, and I think you've been
01:31:08by the end of that year, you've been
01:31:10getting to a point where it could be
01:31:12rolled out and we've been just chatting
01:31:15before where you mentioned that this year
01:31:17it's getting released in GA.
01:31:19So, I suppose across like all
01:31:22production traffic, et cetera.
01:31:24So how's that gone?
01:31:26And how did your team like it?
01:31:28How, how was your experience?
01:31:30Yes.
01:31:31So my personal experience was, was great.
01:31:33Let's start with me and
01:31:34then we can go to the team.
01:31:36And then we can go
01:31:36like outside of the team.
01:31:40Yeah, I was taking
01:31:41really baby steps with effect.
01:31:42So after input parsing and
01:31:45validation the next big step was to
01:31:48interact with the database, obviously
01:31:50relying just on SQL effects was not
01:31:53enough because we have
01:31:55a sharded database.
01:31:58We have like this big shared sharded
01:32:00database instances that every
01:32:03application interacts with.
01:32:04So we had to write like a wrapper,
01:32:07for SQL effects that would read
01:32:09the configuration, create one SQL
01:32:12pool per shard node.
01:32:15So basically one for a writer, one for a
01:32:18reader, and then we would have like this
01:32:20big collection of writers and readers
01:32:22group by shards, and then every time a
01:32:26request comes in, we would have to figure
01:32:27out what is the shard ID reaching to the
01:32:30collection handle like short shard not
01:32:33found errors and stuff like this.
01:32:35Finally getting the shard, getting the
01:32:37pool for the writer or the reader
01:32:38that you currently need at the
01:32:40point where you need to
01:32:42like call the database.
01:32:43And then that's when we get the SQL
01:32:46effects, like the SQL client from the
01:32:48library at the time, like the pool is
01:32:51basically provided by that.
01:32:52And then that was great.
01:32:54once we got there, because then we
01:32:56could persist events.
01:32:58So one thing that I want to mention is
01:33:00like, we use event sourcing where exactly
01:33:04this two way bi-directional schemas,
01:33:07work really well, because on
01:33:10one hand, like when the request comes in,
01:33:13we do the input parsing and then that
01:33:17input represents almost the exact
01:33:21payload that we then write to the
01:33:24database which represents our event.
01:33:26So once we did the parsing, obviously we
01:33:29need to serialize it into, into a
01:33:32string that we can then push into a,
01:33:35into a text column in SQL.
01:33:38So yeah, that was a big thing.
01:33:40And then obviously the next step
01:33:42after the database client, there was
01:33:44like the HTTP layer where we might
01:33:47need to call like different HTTP
01:33:49services, especially around the feature
01:33:52flags and stuff like that.
01:33:53So yeah, really baby steps.
01:33:54And then eventually we added some
01:33:56level of observability,
01:33:59logging, tracing metrics.
01:34:01In the beginning.
01:34:02It wasn't really anything sophisticated.
01:34:04We were relying mostly on the data dog,
01:34:06tracing library defaults, which
01:34:08provided some level of detail.
01:34:12It didn't work very well.
01:34:13We didn't get very detailed traces,
01:34:15but it was good enough to see some
01:34:17traffic and what's going on at the, maybe
01:34:20let's say the GraphQL level.
01:34:22So everything that is an Effect,
01:34:24obviously we couldn't get any visibility
01:34:26into that, but then we switched to
01:34:29Otel eventually, and then things
01:34:30improved from there and then as the more
01:34:34I learned about Effect, the closer
01:34:36I was getting to turning the application
01:34:39into an end to end Effect.
01:34:42And today it's like fully Effect.
01:34:44So it's effect from top to bottom.
01:34:46Right.
01:34:46And I think this is a pattern that I've
01:34:49seen a lot both in the apps that I've
01:34:52been building and where I take, I've
01:34:53taken my first steps with Effect, but
01:34:56also in what I see how other people are
01:34:59approaching effect is like how
01:35:01nicely it can be adopted incrementally.
01:35:03Where if you think about your program as
01:35:05a tree, you can very easily start
01:35:09at like any layer of the tree, really
01:35:12like at any position, you can start
01:35:14out with the leaves and
01:35:15write those as effects.
01:35:17And then at some point, just run them as
01:35:20promises and assuming your, your other
01:35:22code is already like promises or
01:35:25async await based, you can just call your
01:35:28new effect code as good old promises.
01:35:32Or you can do it on the other way around.
01:35:35And at the root of your program, you
01:35:37can rewrite some
01:35:39parts that are maybe more
01:35:41for governing and overseeing the
01:35:43execution of your program.
01:35:44You can rewrite that with Effect, for
01:35:46example, request handlers, but then,
01:35:49still call out to promises and everything
01:35:51else of your program is still promises.
01:35:54Or you can do it somewhere in the middle
01:35:55and say, okay, at some point we're like
01:35:58in async await, we're going to rewrite
01:36:00some part in with effects, but then the
01:36:03stuff way further down,
01:36:05we'll call again as promises.
01:36:07And so you can mix and
01:36:08match as much as you want.
01:36:10But what I've typically seen is that
01:36:13people get very
01:36:14productive very quickly
01:36:15with like some incremental adoption.
01:36:18And then they see
01:36:19like, Oh, wait a second.
01:36:20That part is still not as nice.
01:36:22And that is some of the
01:36:23leftover promise code.
01:36:25And then in no time
01:36:27that's rewritten to effect as well.
01:36:29I think what is typically
01:36:31the case is the more
01:36:32you rewrite to effect
01:36:33that kind of collapses the amount
01:36:36of code typically like by half and
01:36:39shines a very bright light on some of
01:36:42the holes that you haven't yet
01:36:43covered such as error handling very
01:36:46often, like Effect kind of shows
01:36:48you a mirror and say like asks you like,
01:36:50Hey, here stuff could go wrong.
01:36:52Right.
01:36:53What have you done so far about it?
01:36:54Not really much.
01:36:56And so it forces you to do the right thing
01:36:59That sounds very familiar.
01:37:00What you've described.
01:37:01Absolutely.
01:37:02Writing Effect has
01:37:03a lot of knock on Effect.
01:37:06Pun not intended. On how you write
01:37:09maintainable code on a day to day basis.
01:37:12Things like obviously the error
01:37:13handling it's amazing.
01:37:15Very recently I implemented a Kafka
01:37:19consumer with
01:37:20effect, um, using Kafka JS.
01:37:23So I just wrapped Kafka JS in an Effect,
01:37:25API and then had like an
01:37:28abstraction for a consumer and then
01:37:30obviously the consumer can consume
01:37:32things, um, either message
01:37:34by message or in batches.
01:37:35So I just needed a message by message,
01:37:38type of consumption.
01:37:41So that's what my abstraction does.
01:37:44It creates a consumer and you pass in
01:37:46like the effect that hand a function
01:37:48that returns an effect that handles like
01:37:50the incoming message, the payload.
01:37:53It was just really beautiful to see
01:37:55how the different error cases
01:37:57all bubble up to the very root of
01:38:01your message handler.
01:38:03And then in Kafka, like when you consume
01:38:06the messages, it's super important to
01:38:08make a decision at that point.
01:38:10Like, do you drop the message
01:38:12or do you retry reprocess it?
01:38:14Right.
01:38:14You need to be able to make this decision
01:38:17for every single error case.
01:38:19And you know, you just have effect dot
01:38:21catch tags and then you have like a big
01:38:24dictionary, like a big, big object
01:38:26containing the tag of
01:38:27the error on the left side.
01:38:30And the error handling basically die
01:38:33or, or succeed with some error
01:38:36logging or whatever.
01:38:37So if you die, Kafka
01:38:38will reprocess the message.
01:38:40If you, if you succeed and you log it,
01:38:42well, you can either put it into
01:38:45like a dead letter queue or something.
01:38:47If you want to keep
01:38:49those messages around.
01:38:51But if that's not necessarily
01:38:53important because
01:38:54it's like time sensitive
01:38:55and if you don't process it now, then it
01:38:58doesn't make sense to process it like
01:38:59five days later, then you
01:39:01just discard the message.
01:39:03And before I would normally implement
01:39:06Kafka consumers like in Ruby or maybe in
01:39:10fp-ts, it was also, it was better, but I
01:39:14don't think I had it to this level
01:39:16of granularity because what we ended up
01:39:18doing in fp-ts was taking like the
01:39:21shortcut route where we would just return
01:39:23a generic error interface.
01:39:25Just to have like, yeah, you
01:39:26know, it can error, but we didn't know
01:39:29what kind of error later on as I got
01:39:31better with fp-ts, then obviously you
01:39:33would have different types of errors,
01:39:34which would also compose.
01:39:36but I haven't written a Kafka
01:39:38consumer with that,
01:39:39approach in fp-ts,
01:39:41but with Effect, it was just like so easy
01:39:43and it's so useful because you don't
01:39:47think about all these different kinds of,
01:39:51ways your program can fail.
01:39:54And my consumer is very simple.
01:39:57It receives a message.
01:39:59It parses it.
01:40:00writes an event and
01:40:02then calls another service.
01:40:03So basically three things, but there's
01:40:07like 15 or 20 different ways it can fail.
01:40:10And it's just like, wow, now I know
01:40:12everything every single way, how it can
01:40:14fail
01:40:15so what took me the most
01:40:16time was thinking about whether to
01:40:20discard or reprocess the message in the
01:40:22whole implementation
01:40:23proportionally the most time,
01:40:25but that makes a lot of sense.
01:40:27And I think that makes a difference
01:40:28between resilient and
01:40:30non-resilient software.
01:40:33I think a lot of TypeScript programmers
01:40:35are blissfully ignorant of the
01:40:40unhappy path of a program, but this is
01:40:44what ultimately makes your users very
01:40:46unhappy if stuff goes wrong.
01:40:49and a lot of times that is completely
01:40:51unrelated to whether
01:40:52the user has done something wrong as
01:40:54whether your servers have a bad day or
01:40:56whether you've migrated some infra and
01:40:58like some things is like hitting capacity
01:41:02or you're just hitting a blip somewhere
01:41:04and things go wrong and a user gets like
01:41:08an endless spinner or gets like undefined
01:41:12is not a function in their face.
01:41:14This is where like some backend
01:41:15engineers haven't done their homework.
01:41:17And I get it.
01:41:19It's really tricky.
01:41:21If you, if you're just like dealing
01:41:23with like catch error and then
01:41:26you have an any or unknown
01:41:27thing and what do you do with it?
01:41:29Yeah, maybe you bubble it around, maybe
01:41:32you log it, but to work with it as
01:41:36nicely as like structured type data that
01:41:39you return from a function, that's what
01:41:41you get with Effect and
01:41:42you can handle it so nicely.
01:41:45That was actually fun to
01:41:46deal with the non happy path.
01:41:48Yes.
01:41:49And I think you
01:41:49touched upon it very well.
01:41:51It's fun.
01:41:52You don't feel like it's something that
01:41:56you have to do, but the language or the
01:41:59library like doesn't really provide a
01:42:01good way for you to manage.
01:42:02And then it's like just a headache.
01:42:04It's really fun.
01:42:05To handle these cases in Effect.
01:42:08And it just has such a great effect on,
01:42:12on your reliability, on the
01:42:16reliability of your software.
01:42:18The other thing that I noticed was also
01:42:22in terms of
01:42:23maintainability and testability,
01:42:25like the dependency injection,
01:42:27like dependency management as well.
01:42:30It's just so great with effect.
01:42:33I don't have to worry
01:42:34about mocking things extensively.
01:42:38I just build a fake dependency and
01:42:41provide that instead of, instead
01:42:43of the real one, the live one.
01:42:44And I feel like I'm much more
01:42:48incentivized to write unit
01:42:50tests and I don't know how other people
01:42:53think about engineers at companies like
01:42:57Zendesk and like Facebook and Google,
01:42:59like big, big companies, like how they
01:43:02deal with these things
01:43:03deal with these things
01:43:03on a day-to-day basis.
01:43:06In the end, like it doesn't matter
01:43:07how skillful or experienced you are.
01:43:11It comes down to incentives all the time.
01:43:13Like you do things that you
01:43:15are more incentivized to do.
01:43:17So if a language or a framework or a
01:43:21library makes
01:43:22something really easy to do,
01:43:24you will do it regardless, whether it's
01:43:27the right thing to do
01:43:28or the wrong thing to do.
01:43:29It's just like this.
01:43:30I don't know if there's like a law or
01:43:32this, but it's
01:43:33definitely a psychological effect.
01:43:36This, this is one of my favorites
01:43:38paradigms or
01:43:39guidelines in programming
01:43:42or in life, in principle,
01:43:45which is like make the right thing easy.
01:43:48And that is, I think Effect makes
01:43:51some really hard things
01:43:54that are the right thing
01:43:56as easy as they can be.
01:43:58And so easy that it's fun doing things
01:44:02like error handling or structuring
01:44:04the hierarchy of your program in a
01:44:06nice way, in the as nice way as you could
01:44:10possibly do it in TypeScript, that's a
01:44:12huge lift and that's
01:44:13what Effect enables you.
01:44:15And I think sounds
01:44:16like dependency injection.
01:44:17That's probably if you're in your Effect
01:44:20adoption journey, that typically happens
01:44:22sort of like maybe in the second week
01:44:25when you're using Effect
01:44:26after you've like rewritten
01:44:27a whole bunch of like
01:44:29promise code, et cetera.
01:44:31Maybe you've now like finally cleaned up
01:44:33some of your tech depth
01:44:34around error handling.
01:44:36And then you realize, okay, there's still
01:44:38like some
01:44:38global state we mutate
01:44:40to kind of pass things around, or we just
01:44:43have like this big blob of
01:44:45like properties we're
01:44:46like kind of pulling
01:44:47through like all of
01:44:49our function vacations.
01:44:50Or maybe we have this like monster
01:44:52monstrous context object,
01:44:55which maybe has a whole bunch
01:44:57of like, either it's untyped or it has a
01:45:00whole bunch of like
01:45:00nullable properties and you
01:45:02kinda pray that it's there.
01:45:04That's like all like CME principles.
01:45:07I'd argue this, the most principled
01:45:08approach about that is
01:45:10like having like a bag of
01:45:12properties that you just like lift
01:45:14through your function
01:45:15calls, but Effect gives you
01:45:17the best of both worlds.
01:45:18It gives you a very principled approach
01:45:20and a very convenient approach.
01:45:22And I think dependency
01:45:23injection has a kind of a bad rap.
01:45:26I've used it in
01:45:27various programming language.
01:45:28I've used it like a lot
01:45:29of in PHP in the past.
01:45:31I've used it like in GoLang and
01:45:34other programming languages.
01:45:35It never, it felt like, okay, this is how
01:45:39things should kind
01:45:40of, there is a solution
01:45:41somewhere there, but all the solutions
01:45:43I've used so far where
01:45:45it kind of like had such
01:45:46big foot guns that at some point I said
01:45:48like, okay, no, I've hurt myself too much
01:45:50with that.
01:45:51I'll do it manually.
01:45:53And I think Effect finally gives you the
01:45:55cake and lets you eat it.
01:45:57And I think that's
01:45:58really hard to explain.
01:46:00And I think you have to build a little
01:46:01thing, refactor it and
01:46:03like, then throw in a
01:46:05little bit of like type save context,
01:46:06which is all there is to it.
01:46:08Really.
01:46:09It's like react context,
01:46:10but type save and much nicer.
01:46:12So that's, I think something you have to
01:46:14try for yourself to
01:46:15see that how nice it is.
01:46:18But I agree.
01:46:18This is one of the best things about it.
01:46:20Yeah, absolutely.
01:46:22And why does it have a bad rep
01:46:24if I think
01:46:25about it, I think it's
01:46:26again, comes down to incentives.
01:46:28If the language makes it hard to do
01:46:30dependency injection,
01:46:32because it's never just a
01:46:33singular case, like, Oh, I'm going to do
01:46:35dependency injection on this function.
01:46:37And this one function will be, you know,
01:46:40they're written the right way.
01:46:41Well, you know, your program usually has
01:46:44a certain depth, like there's like a
01:46:46function and then that function calls out
01:46:48that of other functions.
01:46:49Those functions call out other functions.
01:46:51And then the dependency needs to travel
01:46:53all the way down because it's
01:46:54called somewhere at the leaf.
01:46:56For example, a database call is made
01:46:58somewhere at the leaf of our program and
01:47:01wiring through all these layers and then
01:47:04adding the dependency in the list of
01:47:07arguments all the time.
01:47:09Well, I'm not surprised
01:47:10that people get tired of it.
01:47:12And I started thinking about it a few
01:47:14weeks ago, you know, like, what are these
01:47:16approaches?
01:47:17And I started calling them just
01:47:19internally for myself,
01:47:22my own, for my own sake.
01:47:23Like there's this explicit dependency
01:47:25injection where you like to do all the
01:47:27wiring and like yourself.
01:47:29Then there's some languages like Scala,
01:47:31which somehow give you like some, some
01:47:35language features, which allow you to
01:47:37implicitly wire through it.
01:47:40You need to have a big brain for that.
01:47:42And it feels a little bit magical, right?
01:47:44This implicit dependency injection.
01:47:47I don't know if it's
01:47:47through traits or something.
01:47:48I'm not a big Scala user,
01:47:51but I did see some, some of it.
01:47:53And then you have Effect, which is like,
01:47:56it's somewhere in the middle.
01:47:58Like it's, it's kind of implicit, but
01:48:00it's also very explicit in a sense.
01:48:02Like you, you do declare, you see where
01:48:05you inject the dependency by providing
01:48:08the implementation.
01:48:09And then you also see the place where
01:48:11you're calling the functions and the
01:48:14stuff that's on the dependency because
01:48:17you have to yield it or yield star.
01:48:20So it's, it's kind of implicit because
01:48:22you don't have to wire it manually.
01:48:25You just use it at the, at the, at the
01:48:27site where you need it.
01:48:29I think it's the best of both worlds in a
01:48:31very similar way.
01:48:32How I think TypeScript is the best of
01:48:35both worlds where it very elegantly
01:48:38does type inference in
01:48:40most places where you can.
01:48:42a lot of static languages,
01:48:44like ask you to write type annotations
01:48:47everywhere, and that I think also causes
01:48:51like some fatigue when
01:48:53you use a typed language.
01:48:55And I think TypeScript makes it so nice
01:48:57that you can get away with
01:48:59like just type annotations in
01:49:00the minimum amount of places.
01:49:02Sometimes even for argument types, if you
01:49:05have a default value, for example.
01:49:07So most things where possible can be
01:49:10inferred and that's totally fine.
01:49:12And so think about the context, the type
01:49:15dependencies of an Effect of a
01:49:16function, think about it the same way like
01:49:18if it's
01:49:19used, it can be inferred.
01:49:21If you return something from a function
01:49:23that looks like an object with a property
01:49:27user, then the type can be inferred.
01:49:29That's because you return it.
01:49:31And what's so cool about Effect is
01:49:33like, if you use a thing in a function
01:49:36and using, like you said, like if you
01:49:39yield something, so the equivalent
01:49:41of like an await, then Effect and like a,
01:49:45on the type level wires things up
01:49:47nicely with TypeScript that in the type
01:49:50signature, you say like, aha, here
01:49:53we need the database client.
01:49:55And also during runtime makes sure,
01:49:58okay, there's behind the
01:50:00scenes, the context objects where we have
01:50:01the database client.
01:50:02So it picks it up and not just even that,
01:50:04but also when you finally get to run your
01:50:07program, it makes sure that at some point
01:50:10you supply your database client.
01:50:13And I think that is so elegant when you,
01:50:16when you use it, but it's, it's hard to
01:50:19to kind of grasp it if you, if you
01:50:20haven't take a look at that with
01:50:22code and like try to refactor a little
01:50:25something, but I agree.
01:50:26It's one of the most
01:50:27elegant things about Effect.
01:50:29Absolutely.
01:50:29People just have to
01:50:30get their hands dirty.
01:50:31There's no other way of learning and
01:50:33understanding Effect.
01:50:34Like obviously you could read the
01:50:36documentation all day long, but then
01:50:38you get fatigued because there's just so
01:50:40much that Effect provides.
01:50:42I often see people being very confused
01:50:44about what is Effect?
01:50:45Like, "I don't understand it.
01:50:47it seems to do
01:50:48everything", because it's such a big
01:50:51departure from the tiny libraries with
01:50:54very well-defined responsibility
01:50:57in the JavaScript ecosystem.
01:50:59And then you can like pick and choose and
01:51:00you can build your own tech stack,
01:51:03upon certain libraries, and then that's
01:51:05your definition of production
01:51:08grade software, but then
01:51:09you have Effect, which seems
01:51:10to be like the glue code.
01:51:12It's a really a generic
01:51:14programming framework
01:51:15Right.
01:51:16And I suppose in a parallel universe
01:51:18Effect would have been a different
01:51:21programming language, but I think
01:51:23now we sort of have the best of both
01:51:26worlds in that regard as well, because
01:51:28TypeScript is darn good.
01:51:30Like, and so many people
01:51:32already love TypeScript.
01:51:34I love it.
01:51:34It has so much structure and has so much
01:51:37amazing tooling around it.
01:51:39VS code just works super well with it.
01:51:41You have like LSPs that
01:51:43work in other places.
01:51:44So at this point, you need to have a very
01:51:47good reason to create a new
01:51:48program language, and I think good
01:51:50reasons could be superior runtime
01:51:53performance, what like Rust is giving you
01:51:56or what other program languages give you.
01:51:59But if you can't provide those unfair
01:52:02advantages, then I think you
01:52:03gotta stick with TypeScript for now.
01:52:05And TypeScript is so elegant and
01:52:07so flexible that you can bring all of
01:52:10those semantics that you would get from
01:52:12something like reason or a re-script.
01:52:15But you can bring it
01:52:16directly into TypeScript.
01:52:17This is where Effect has
01:52:18struck this really nice balance.
01:52:20But I agree you need to rewire
01:52:22your brain a little bit.
01:52:24And people maybe
01:52:25don't immediately get it.
01:52:27And I've seen an interesting correlation
01:52:29that people have the easiest time
01:52:31getting what Effect is about if they've
01:52:33experienced the problems that Effect
01:52:36solves before and they
01:52:39have sort of like a lot of scar tissue
01:52:40from trying to solve those problems
01:52:43themselves, like trying to do proper
01:52:45error handling, trying to do
01:52:47observability, trying to do interruption.
01:52:49What you've mentioned
01:52:50before with Kubernetes.
01:52:52So the more problems an engineer has
01:52:55experienced in the past, particularly
01:52:57TypeScript engineer, I feel like
01:52:59for them
01:52:59Effect clicks
01:53:00most quickly, but yeah, I'm curious, what
01:53:03was the experience talking to other
01:53:05engineers at Zendesk so far?
01:53:07What have they been confused about?
01:53:09What has clicked for them?
01:53:11So far I mostly talked through
01:53:13my own experience.
01:53:15Then I had my immediate team members and,
01:53:19with them, obviously it's a journey
01:53:21because, they have to learn it.
01:53:23It's also different from fp-ts.
01:53:25Also fp-ts, they didn't
01:53:27really bother learning that much.
01:53:29Like as long as they could kind of
01:53:32understand in terms of the code
01:53:34review, what's going on, that was
01:53:36already a good enough level for them,
01:53:38To be productive and
01:53:40help me with the reviews.
01:53:41If I write some code, also my team in the
01:53:46past one, two years, like we've had this
01:53:50unfortunate situation where
01:53:52we had some churn in the team.
01:53:53So often I was like the only backend
01:53:56engineer on the team while being
01:53:57the tech lead as well.
01:53:59So I really needed like my front end
01:54:01engineers to be able to review my
01:54:04code, and Effect is just doing
01:54:06really well in this regard as well.
01:54:08Because once you have the generator
01:54:12syntax, where you have the gen and
01:54:16yeld star, which you can easily map
01:54:19in your mind to async and
01:54:20await, you can build up this
01:54:22adapter layer, in this mental
01:54:24model for you once that clicks,
01:54:26it's very easy for them to review code.
01:54:30I'm not talking about stuff like,
01:54:32you know, database queries and, you
01:54:34know, how to set up proper indices for,
01:54:37for your table and like these backend
01:54:39concerns, purely backend concerns, but
01:54:41like all the business logic that you
01:54:43write on the backend and there's a ton of
01:54:45it, that's not an issue in terms of
01:54:47review.
01:54:48So that's sort of like the 10 second
01:54:50onboarding like, Hey, this stuff going
01:54:52to look a little bit weird.
01:54:53Just everywhere you see yield, think
01:54:55that's await everywhere.
01:54:57You see that gen thing, I think that's
01:54:59async and you should be able to like,
01:55:01just read that code as like your
01:55:03traditional async, await code go.
01:55:06I think that is sort of like the hail
01:55:08Mary 10 second onboarding
01:55:10where someone can get really far.
01:55:12Yeah, exactly.
01:55:13And that's like totally
01:55:15Pareto, like, this 20% of effort
01:55:19gives you 80% of the results.
01:55:21Like after that, obviously they're going
01:55:23to have questions
01:55:24like, what is this layer?
01:55:27What is this runtime?
01:55:29Uh, what do you do when you catch tags?
01:55:31What are tags?
01:55:32Like there will be questions like this,
01:55:34but they're, and yeah, they require maybe
01:55:38more nuanced explanations, not just
01:55:41like a one-to-one mapping from a
01:55:43new concept to a well-known
01:55:45well-established other concept.
01:55:47But, but it's that
01:55:4920% of the, of, of the productivity
01:55:53that you're achieving
01:55:54with the 80% of the effort.
01:55:56So already with the 10 second onboarding,
01:55:58you're so far ahead that the
01:56:00reviews just work already.
01:56:02And then I like this idea of like,
01:56:04exposing someone
01:56:06to Effect first through
01:56:07like reading
01:56:07code and doing code review.
01:56:09Since this is where someone through
01:56:11the context that they are already
01:56:13familiar with, maybe through a refactor,
01:56:15maybe through a new feature, they
01:56:18have all of the context that they need to
01:56:20understand what the problem is about.
01:56:22And now they can focus
01:56:23on the implementation.
01:56:24And I think what's also so nice is
01:56:26depending on where someone
01:56:28reviews the code, possibly ideally in
01:56:30their IDE, this is where you can also
01:56:33use all of like the type inference
01:56:35benefits to help you understand
01:56:38what's going on, if you hover over an
01:56:40effect and see like, Oh, this is where
01:56:43we can have an error that is about maybe
01:56:46the user wasn't found or maybe
01:56:50another service is done.
01:56:52This can add so much to the picture to
01:56:54understand what's going on.
01:56:56Where before everything was just like,
01:56:58an implicit sort of wake
01:57:01thought, and I feel like this is where
01:57:03someone just by also being exposed
01:57:06can pick up so much.
01:57:08And then you have seen at the end of the
01:57:10day, a lot of code users are
01:57:13very similar to each other.
01:57:15And this is where in someone get now
01:57:17takes that step to writing their own
01:57:19Effect code, they probably have already
01:57:21seen two or three places that are very
01:57:23similar, so you can go copy some of that
01:57:26code, go over there, adjust it, and
01:57:29bring the usual programming muscle.
01:57:31And it's works going to work just as well
01:57:34and probably even better
01:57:35since you have improved type safety.
01:57:37Yeah, absolutely.
01:57:39Also, I really love the way you can work
01:57:42with generators because anything
01:57:44that's within the function body of a
01:57:47generator, it's basically your happy
01:57:49path because all the error cases just
01:57:52short circuit the happy path.
01:57:54And then you just do a quick pipe after
01:57:56the Effect where you
01:57:57handle all the
01:57:58possible failure cases.
01:58:00And I don't know why, but I just love
01:58:03this style of writing programs.
01:58:06Here's my happy path.
01:58:07Everybody can understand what's going on.
01:58:10And then now in this pipe, I'm going to
01:58:13handle all the errors.
01:58:14Right.
01:58:15This way can like, sprinkle a little bit
01:58:16of like extra sauce on top of it, where
01:58:19you can, I often do
01:58:20also like timeouts there.
01:58:22I add a little bit of like Otel
01:58:24instrumentation around that, or maybe do
01:58:27like a retry for an error
01:58:29but yeah, as you say,
01:58:31like in the generator,
01:58:32this, and I think this is so beautiful
01:58:34about it is like, you can nicely separate
01:58:36sort of like signal from the other stuff
01:58:39and say like, okay, here's my business
01:58:41logic and here's like,
01:58:43here are those other concerns.
01:58:45I think like in the future, if we have
01:58:47like a next
01:58:48generation of IDEs, et cetera,
01:58:50and maybe like even more AI assisted,
01:58:53maybe that can help you and say like,
01:58:55Hey, hide everything that is not about
01:58:57the business logic or
01:58:59hide everything that,
01:59:00or like highlight everything that is
01:59:02about concurrency or highlight everything
01:59:04that is about error handling with Effect.
01:59:06You already put in sort of like the
01:59:08structural effort and I think we're going
01:59:11to see some, some big rewards even beyond
01:59:13what we have right now.
01:59:16That's very interesting.
01:59:16I never thought about this, but, uh, it
01:59:19makes it enough sense.
01:59:20Yeah.
01:59:21The, the tooling that you can build on,
01:59:23on, on top of these like static
01:59:25descriptions of a
01:59:26program is just like limitless.
01:59:28Yeah.
01:59:29Interesting.
01:59:30Yeah.
01:59:30This is something I'm
01:59:31very, very excited about.
01:59:33And we've, we talked briefly before about
01:59:35the launch of the Effect Playground.
01:59:37I think it's super nice to have like an
01:59:39environment where it can just play
01:59:41around a little bit, get
01:59:42familiar with something.
01:59:43I use it on a daily basis to maybe
01:59:45understand an API surface a bit better
01:59:48and just play around with it, have fun.
01:59:50And we also threw in support for some of
01:59:53the effect dev tools in there,
01:59:55notably also the trace viewer.
01:59:59And this is where you can get real time
02:00:01feedback for what does it mean for
02:00:03my program to run this is where it may be
02:00:05a certain thing took like a second
02:00:08and then should just time out, et
02:00:11cetera, like visually
02:00:12see what's going on.
02:00:14There's so many tooling possibilities
02:00:16that are coming.
02:00:18And that's gonna just kind of like the
02:00:20gift that keeps on giving as like
02:00:22you adopt Effect, and there's like so
02:00:23many benefits that just fall out of that.
02:00:26I think we're still at the beginning and
02:00:28it's already very rewarding for at
02:00:31least in my experience
02:00:32and what I've seen so far.
02:00:33So you shared your
02:00:35experience using an adopting Effect
02:00:38and also how you help your own team adopt
02:00:42Effect and be productive with it
02:00:44through code reviews and helping them to
02:00:46refactor code and build new Effect
02:00:48programs.
02:00:49But given that you built this service
02:00:51framework that is used, I think all
02:00:53across Zendesk when it comes to
02:00:55TypeScript code, there's now more and more
02:00:58people that are exposed to effect.
02:01:00So how was their experience?
02:01:02Maybe you got a little
02:01:03bit of like questions.
02:01:05What is that thing?
02:01:06Uh, maybe some similar concerns that
02:01:10people asked about fp-ts
02:01:13So which sort of questions did you hear.
02:01:16Yes.
02:01:16Uh, well, that's a great question.
02:01:18So let me start with another
02:01:20team, uh, not my team.
02:01:21That's the closest to our team.
02:01:24And they have some services that are
02:01:27fully written in fp-ts
02:01:28and using our service
02:01:30framework, so they're looking and
02:01:33watching us from the
02:01:34sidelines, writing Effect
02:01:36code line, because we're enjoying this
02:01:38opportunity of building a completely
02:01:40new service from scratch.
02:01:42And, uh, they're, they weren't so lucky.
02:01:43So they're still stuck
02:01:44with their fp-ts project.
02:01:46And they're just looking at us, uh,
02:01:50and are maybe a little bit jealous,
02:01:53of us that we're writing effect
02:01:55already because they've been looking
02:01:56forward to writing effect as well.
02:01:59But, but I'm helping them try to
02:02:01figure out how to migrate, fp-ts to
02:02:04effect also incrementally
02:02:05it's, it's a bit tough.
02:02:07Especially if you have your own
02:02:08abstractions and own ways of doing things
02:02:12with fp-ts, so it's really slow.
02:02:15And also it's really hard to justify, to
02:02:17spend the time to fully migrate a
02:02:20rather large project in one go.
02:02:23So it really has to be incremental.
02:02:25So that's, that's a
02:02:26positive feedback from them.
02:02:27But then we also have teams that are
02:02:30outside of our immediate organization
02:02:33and they are, let's say more TypeScript
02:02:36native teams and they have completely
02:02:40different requirements from, from my team
02:02:44and from the other Guide team.
02:02:46Because Effect was not their choice.
02:02:49It was our choice for, for the
02:02:51TypeScript service framework.
02:02:52Right.
02:02:53And the service framework does
02:02:55provide a lot of value, but without
02:02:58knowing Effect necessarily or fp-ts
02:03:01even it's really hard to tap into
02:03:04that value and, and use it immediately in
02:03:06your project, which knows nothing
02:03:08about fp-ts or Effect and the engineers
02:03:10know nothing about fp-ts and Effect.
02:03:12So here Effect actually brings some
02:03:15really good tools, that can
02:03:17help bridge between the two
02:03:20requirements and
02:03:21that's the adapter layers.
02:03:24So basically when you have an Effect, you
02:03:25can run it as a promise or you have
02:03:28a promise and then you can wrap it into
02:03:29an effect using different APIs.
02:03:32So in our service framework, this is
02:03:35something that we're going to be leaning
02:03:37on more and more because we want to
02:03:41provide the benefit to all the users
02:03:44regardless whether
02:03:45they choose effect or not.
02:03:47So for every effect API, we can have a
02:03:49rule that we will also be able to a
02:03:51promise based API, which is fully built
02:03:54on top of the effect, because we're just
02:03:56going to satisfy all the dependencies at
02:03:58the time and, and run it as a promise.
02:04:02And then they can always look up what
02:04:04kind of failure
02:04:05modes there can be because they can just
02:04:07follow by convention, or by
02:04:10inspecting the implementation.
02:04:12They can see which effect APIs,
02:04:14rather which service framework effect
02:04:16based service framework API is wrapped
02:04:18and then discover the
02:04:20type signature there.
02:04:22So that's, that's one way how they can
02:04:24reap the benefit of knowing
02:04:25what kind of errors there are.
02:04:26They don't have to
02:04:27inspect all the depths.
02:04:30I don't know how even people were doing
02:04:32it with like regular
02:04:33type script libraries.
02:04:34You know, how do you discover what
02:04:35kind of errors you may encounter?
02:04:37Like, I think typically you don't and you
02:04:39discovered during runtime and logging.
02:04:42Yeah, exactly.
02:04:44It will be so nice to know like, Oh,
02:04:46here's the documentation page.
02:04:48It lists all the 150 ways of my program
02:04:52failing or my library failing.
02:04:54But this, this doesn't exist.
02:04:56I at least I have not seen a library
02:04:59documenting their
02:05:01implementation or
02:05:02their API's to this level.
02:05:04It would also be really terrible to
02:05:05maintain the documentation for this.
02:05:07I mean, we have the perfect primitive for
02:05:09that, which are types and I
02:05:11guess more modern programming languages,
02:05:14such as Rust, et cetera, they have
02:05:16figured this out and they return results
02:05:19in case something can go wrong.
02:05:21And I mean, Effect is about the same idea
02:05:24that you don't just return
02:05:26just the success value, but also you're
02:05:29returning the, the errors just through
02:05:31the return channel as, as other things as
02:05:34well, but coming back to
02:05:35the point you were just making, I liked
02:05:37that approach that basically for
02:05:39the folks in your organization who are
02:05:43already excited and interested about
02:05:45Effect, they can already start consuming
02:05:48the effect API's for the ones who
02:05:50are still on the fence or are not quite
02:05:53ready to make the jump yet.
02:05:55They can still stay in the Promise land
02:05:58and need to deal with,
02:06:01errors, et cetera, the, the good, bad
02:06:03way, um, the old bad way.
02:06:07Which sort of questions do you typically
02:06:09hear when someone is as
02:06:11confronted with Effect, I suppose
02:06:14there's a full spectrum of people.
02:06:16You immediately get it and are excited to
02:06:19dig in to people who are maybe curious,
02:06:23but don't quite get it.
02:06:25And then maybe people who are much
02:06:27more skeptical and maybe this
02:06:30reminds them of like some other bad time
02:06:32they had in the past and why they have
02:06:35reasons in mind, why
02:06:36they don't want to adopt it.
02:06:37So tell me more about the different kinds
02:06:39of reactions that you've seen.
02:06:42Yes.
02:06:43So I've done a few
02:06:46Effect related presentations
02:06:48at Zendesk already.
02:06:49I presented at our annual tech
02:06:52conference in May.
02:06:54So I had the opportunity to actually
02:06:56get some of those questions and lots
02:07:01of people are actually skeptical.
02:07:03Maybe due to their own
02:07:05experience with something
02:07:06similar that they tried or
02:07:07just, it just looks too functional for
02:07:10them and they're more familiar in the
02:07:14OP and dynamically typed languages.
02:07:18They don't necessarily understand it.
02:07:21Like at Zendesk, we have lots of
02:07:23engineers who have experienced all
02:07:25the issues related to scale
02:07:27maintainability,
02:07:29testability, reliability,
02:07:30all these things, but still this alone is
02:07:35not necessarily
02:07:36not a huge selling point for them necessarily
02:07:38because they already
02:07:39have their ways around it.
02:07:41Like they have years of experience doing
02:07:43Ruby years of experience doing whatever.
02:07:45And they, they know their way around it.
02:07:48Maybe they don't even care necessarily
02:07:49about super reliability because
02:07:52there's like feature flex.
02:07:54So you can basically not break
02:07:55everybody at the same time, but you just
02:07:57break a tiny bit of, uh, of the
02:08:01customers, which is understandable.
02:08:04If you don't have any other option
02:08:07because you're limiting the blast radius.
02:08:10But it's also not something I'm
02:08:11really a big fan of.
02:08:13Like I really want to catch the errors
02:08:16and possible failure cases even
02:08:18before I commit my changes.
02:08:20Like that's the ideal thing.
02:08:21I don't even want to push it somewhere to
02:08:23a CI and then waste CPU cycles,
02:08:26of a CI just to make it fail.
02:08:29Um, and then repeat rinse and repeat many
02:08:32times possibly, because also sometimes
02:08:34it's really hard to run all the things
02:08:36that the CI runs locally due to different
02:08:39limitations, but yeah, so we have these
02:08:42people who know their way around.
02:08:44So for them, maybe a bigger concern is
02:08:47usually, okay, but
02:08:48listen, we have so many
02:08:50different technologies at Zendesk, we have
02:08:53to consolidate like, why should this be
02:08:56the thing that we consolidate on?
02:08:58How will you align with
02:08:59all these hundreds of engineers
02:09:02on the single one technology?
02:09:03Obviously we have some processes like
02:09:05ADRs and whatnot, but if it comes
02:09:09to a big change like this, obviously
02:09:12there's going to be also resistance
02:09:13because people just are accustomed to
02:09:15to the status quo.
02:09:18And they're their way of operating and
02:09:21they don't necessarily want to switch.
02:09:23Which is totally reasonable.
02:09:25And I don't want to change anybody's
02:09:28mind or I don't want to force
02:09:31anybody to now, you know, forget about
02:09:34promise land and
02:09:35start incorporating
02:09:37Effect into your code
02:09:38base starting tomorrow.
02:09:40I truly believe it should be like a
02:09:43choice that everybody
02:09:45can make for themselves.
02:09:47But then you have, you know, the company
02:09:49incentives to try and consolidate to,
02:09:52to not go into too many directions
02:09:54because if you want to be productive at,
02:09:57at the top level, you know, at an
02:09:59organizational level, like the more
02:10:02people pull in the same direction, the
02:10:05better you are and the more productive
02:10:08you are.
02:10:09So these are also a little bit
02:10:10political, uh, you know, influence
02:10:13and political, it's a
02:10:16question of politics as well.
02:10:17Like how can you influence
02:10:18without being in a big leadership
02:10:22position and stuff like that.
02:10:24Have you found some arguments like from
02:10:26the many things that Effects can offer
02:10:28that has resonated still with the people
02:10:32who are more in the skeptical spectrum?
02:10:34Yes.
02:10:35Um, so sometimes I do, because let's say
02:10:39you're a company and then now you
02:10:42had this financial crisis where the
02:10:44interest rates went up and now, uh, you
02:10:48figure out that money doesn't grow on the
02:10:50trees and you have layoffs and whatnot.
02:10:53And suddenly you stop backfilling for
02:10:56positions, you know, which, which
02:11:00came up because of churn
02:11:01and you're not used to pairing.
02:11:04So you have hiring
02:11:04freeze or whatever suddenly.
02:11:06And, but the expectations of productivity
02:11:08are staying the same.
02:11:09So basically you have
02:11:10more workload per person.
02:11:13That's, that's the final result.
02:11:15The company still expects you to deliver,
02:11:17but now you are fewer people to do so.
02:11:20It's, it's a hypothetical one.
02:11:22Right.
02:11:22So what do you do?
02:11:25Well, I think TypeScript is positioned
02:11:27really well because
02:11:28you can have TypeScript
02:11:30both on the front end, which in many
02:11:32cases you do, and then
02:11:34you can have it on the
02:11:34back end as well, which
02:11:35is, isn't a terrible option.
02:11:37Especially like, you know, you have NodeJS
02:11:40or Dino or whatever, nodeJS with
02:11:42its event loop runtime, perfectly suited
02:11:46for i/o heavy operations.
02:11:50And as far as I'm aware, like 90% of what
02:11:53Zendesk does is i/o heavy.
02:11:55We take a message, no matter where it
02:11:57comes from, we do some processing and
02:12:00we send a message somewhere else.
02:12:02Like maybe it's like you, you, you start
02:12:05a record in the database or you emit a
02:12:07thing in Kafka, maybe you have like a
02:12:09MySQL connector with Kafka, so you can
02:12:11do these things
02:12:13in a single transaction.
02:12:14So basically you manage your distributed
02:12:16transactions this way.
02:12:17So you do a ton of like taking things
02:12:20from here, pushing there.
02:12:22A lot of waiting time, a
02:12:23lot of i/o, what do you do?
02:12:25Like with Ruby, obviously.
02:12:27And this is another thing
02:12:28that I often mention is cost.
02:12:30Like if you have nodeJS handling
02:12:34traffic, like large concurrent
02:12:37traffic, heavy traffic, you can save a
02:12:40lot of cost because with Ruby.
02:12:44What's your option there?
02:12:45Well, yes, you can use threads, but then
02:12:48your memory consumption goes up because
02:12:50threats are not for free.
02:12:52Or you can scale horizontally.
02:12:54So when you put the horizontal pod
02:12:56autoscaler max it out at 24 replicas
02:12:59or whatever you figure out the rules
02:13:02around how to increase the
02:13:04replica count by how much, when, what is
02:13:06the signal that you're looking at?
02:13:08You know, you can figure out all of these
02:13:10things, or you can
02:13:12just have a few replicas,
02:13:14maybe one per availability zone, 2
02:13:17per availability zone for extra
02:13:19redundancy
02:13:20of a node, uh, process.
02:13:22And then suddenly you
02:13:22have a throughput of what?
02:13:24Tens of thousands of requests per second.
02:13:27So, so it's also money, you know?
02:13:30So when you, when you talk to high, uh,
02:13:32to the leadership, you have to
02:13:35convince them with some
02:13:36hard hitting facts.
02:13:38And it's not just, obviously you can say,
02:13:40ah, in theory, this works.
02:13:43No, you have to sit down, do the
02:13:45analysis, maybe set up
02:13:46some project which can
02:13:48demonstrate how much more cost
02:13:51efficient it is compared to other similar
02:13:54workloads, put it into
02:13:56money, uh, values, right?
02:14:00Uh, convert it into dollars or whatever,
02:14:02and then show the difference.
02:14:05And then once you do this, you know, you,
02:14:08you, you won the golden ticket or
02:14:10something because it comes down to
02:14:12money in the end always.
02:14:13Yeah, totally.
02:14:15And I agree with that approach that
02:14:18you can basically like, let the
02:14:20actions, actions speak louder than words.
02:14:22And you're doing
02:14:24the right work already.
02:14:26You're are shipping things in production.
02:14:29You're appreciating and leveraging all
02:14:32the benefits that
02:14:34Effect provides to you.
02:14:35And I think the, your team and some other
02:14:39peer teams have a great
02:14:41experience already with Effect.
02:14:42And I think those will show the results
02:14:46and that might make a case for itself
02:14:49and prove out that it's not just words,
02:14:52but it's actually an improved
02:14:54reality that makes teams more effective,
02:14:58more efficient, happier, and
02:15:00possibly also then saves resources and
02:15:04money when it comes to running those
02:15:06services,
02:15:07saves down times, et cetera.
02:15:09So I'm sure the, the more time continues,
02:15:13the more all of those arguments
02:15:15going to resolve
02:15:16themselves in your favor.
02:15:18And I applaud you for being
02:15:20on the early adopter train.
02:15:24Thank you.
02:15:24I, I do hope that it
02:15:26plays out really well.
02:15:28I'll do my part for sure.
02:15:30Perfect.
02:15:31So maybe that leads me to the last
02:15:34question that I'd love to hear your
02:15:36thoughts on, which is what gets you most
02:15:38excited about the future with Effect.
02:15:43Yes.
02:15:44Ah, that's a good question.
02:15:47I haven't put a lot of research into
02:15:51Effect Cluster, but it's definitely
02:15:53something I'm observing again from the
02:15:56sidelines and look forward to using
02:15:58in the future, maybe for some
02:16:00use cases like backfills, let's say.
02:16:04I have my event sourced service and now I
02:16:07evolve my, uh, event schema from version
02:16:11one to version two,
02:16:12maybe two version three.
02:16:14And now I feel like, okay, my switch
02:16:18statements where we, where I, where I
02:16:20switch between the versions of the schema
02:16:22and then, uh, the way I'm reducing the
02:16:25events into a single aggregate, it's
02:16:28getting a bit cumbersome.
02:16:29So let's just migrate some of those old
02:16:31schema versions to the latest one.
02:16:34So having like millions, maybe billions
02:16:37of records, it could take quite
02:16:40some time to do this sequentially.
02:16:43So having like a solution where I can
02:16:45have set up some workers, which can agree
02:16:48on, you know, the scheduling and how
02:16:50they're going to partition the database
02:16:52table among each other, uh, and do it in
02:16:56parallel, that, that would be just the.
02:16:59You know, perfect dream come true.
02:17:01I don't want to start the backfill in
02:17:03every cluster one after another, or even
02:17:06in parallel, and then like having to like
02:17:08watch tens or dozens of, you
02:17:12know, monitors to see the progress of
02:17:14each individual
02:17:15backfill on every Kubernetes
02:17:17cluster and then managing that for hours.
02:17:22You know, if that could be like maybe a
02:17:2410 or 20 minute thing, that would be
02:17:28just the perfect dream, right?
02:17:29So I'm looking forward to Cluster.
02:17:32Yeah, me too.
02:17:33This is, uh, one of the, as I said, like,
02:17:35uh, be the, the gift that keeps on giving
02:17:38and we're going to have like many layers
02:17:41built on top of the foundations that
02:17:43we already benefit from and the Effect
02:17:47Cluster and Effect workflow primitives
02:17:49that are in the work and the
02:17:50systems that are in the work.
02:17:52Uh, I think that's gonna, yeah, that
02:17:54that's going to be literally next level.
02:17:56This is going to unlock some benefits
02:17:59that you see from systems like Temporal
02:18:02Temporal IO, not the new time standard,
02:18:05but temporal IO, which is about durable
02:18:07workflows and, and workflow scheduling
02:18:09and running long lived things.
02:18:13You can already do that in Effect
02:18:15combined with temporal, but Effect
02:18:19is the perfect foundation to do that, uh,
02:18:21natively with the effect primitives.
02:18:24When you think about rerunning something,
02:18:27if something has failed scheduling, some
02:18:29work, um, processing work across multiple
02:18:33workers and massively
02:18:35parallelized systems.
02:18:37This is where we have like amazing
02:18:39foundations for that.
02:18:41And that's being systematized with the
02:18:43effect cluster and effect workflows
02:18:45project, which is now
02:18:46in development for, I think also like in
02:18:49research for a few years now.
02:18:51And I think it's alpha grade right now.
02:18:54I think some people are
02:18:55already starting to use it.
02:18:57I'm actually also planning to give it a
02:19:00shot soon for the music app that I'm
02:19:03building, and I think it will take a
02:19:05little bit of more time to be fully
02:19:07production ready, just because it's also
02:19:08a very ambitious project, but it's very
02:19:11principled and I'm very
02:19:12excited about the potential for it.
02:19:15And I think we're going to hear a lot
02:19:16more about that in the months and years
02:19:19to come and possibly the next year's
02:19:21Effect Conference already.
02:19:23So yeah, super excited that
02:19:25you're excited about that.
02:19:27Because I think you have some really
02:19:28interesting use cases for that.
02:19:30So, Attila, thank you so much for
02:19:33taking the time today to doing the
02:19:35initial episode of the Cause & Effect
02:19:38Podcast with me and taking the time.
02:19:41So that's much appreciated.
02:19:42And thank you so much.
02:19:44Thank you.
02:19:44It's been a great honor to be the first
02:19:46guest of this amazing podcast.
02:19:50Perfect.
02:19:50Thank you.
02:19:51Take care.
02:19:52Take care.
02:19:53Thank you for listening to
02:19:54the "Cause & Effect" podcast.
02:19:56If you've enjoyed this episode, please
02:19:57subscribe, leave a review,
02:19:59and share it with your friends.
02:20:01If you haven't done so already, you can
02:20:03join our Discord community.
02:20:04And if you have any questions, feedback,
02:20:06or suggestions about this episode or
02:20:09about Effect in general,
02:20:10don't hesitate to get in touch.
02:20:13See you in the next episode.