Skip to content

Adopting Effect at Zendesk with Attila Večerek

Nov 26, 2024

#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
Discuss this episode on Discord

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.