 Welcome to this webinar around event-driven systems. I was thinking, talking a little bit about my thoughts of how to design events first, microservices and APIs. Really event-driven, but with an emphasis on events. That's why it's called events first, microservices and APIs. My name is Jonas Bonier. I'm the CEO and founder of Lightbed. I created Acca. It's like a long time ago now in 2009. And you know, the last product we've been pushing out, we've been working on the last four years we've pushed out. Last year is Calix. But this is sort of a general talk that is generally used for regardless if you use Calix or not. But I'm also going to, you know, lead in how Calix can fit into the picture and making things a lot easier at the end, so to speak. So I hope you stick around for that. Let's get started. So I assume a lot of people at least want to do microservices. And hopefully you're doing it for the right organization, microservices, APIs. And hopefully you're doing it for the right reasons, you know, that a lot of focus I think personally should be about scaling the organization. You know, there's a lot of benefits as we will, in most of this talk, we're going to be on the technical benefits. And I just want to have it said that scaling the organization is likely one of the primary drivers for for my for microservices and having multiple independent and fully autonomous teams being able to build and deploy. And in a features without getting in each other's way, so completely independent independently. The problem though with microservices, if you're not ready for it is that it's a quiz, it's quite a big shift from the from the monolith. When you know when we when we move to microservices we enter the world of distributed systems and that's really the world. I'm not determinism, you know, in a way, we sort of exit the boundary of the service, you know, we enter through this wild ocean, so to speak, of not determinism. And this is the world where, where systems can fail in the most spectacular in an intricate way when information get lost and reordered and garbled. And we're, you know, failure, failure detection, which is one of the better tools in distributed systems is, you know, it's, it's more or less a guessing game. And this, this is the world that might sound terrifying. If you're not used to it, you know, if you're if it's all new to you, but I have to say, you know, that is, this is also the world that gives us solutions for a lot of the hard problems. You know, there are, there are, you know, it sort of enables us to accomplish things that we can't do to just working on in a single machine, you know, on a single core or on a single part, etc. Because it gives us solutions for resilience, you know, for elasticity for true isolation and a lot and a lot and a lot of other things. You know, I mean, too often in my, in my, in my experience, companies end up with, with, with an architecture, something like this, you know, set of what I call microliths, you know, so you sort of stumble and fall halfway towards, towards micro services. And what I, what I mean by microlith is that you have, you have this method calls that are replaced by synchronous RPC calls, and you're still using CRUD, you know, in a fully blocking way. And by, by, by, by bringing, you know, blocking IO and, and, and, and, you know, blocking database calls and all these things, you know, over from from the monolith where they, where they usually work very, very well over to the world of distributed systems where we have, we have, you know, we enter in a strong, strong temporal coupling, and this, and this, and this, and this strong temporal coupling limits us in the way we can to scale scalability and availability and also extensibility and, in my opinion, it's also maintainability, you know, you sort of start piling up complexity as you, as you, as you go along instead of having it on a, on a, on the same level, you know, across the lifecycle of an application, I think we can do better than this. I know we can. And thinking in events can help. Domain driven design from an events first perspective, I really think that is, that is sort of a gateway towards really good, you know, system design and architecture. So let's talk about that, you know, what, what, what, what does events first domain driven design mean, and let's try to sort of view the world through the lens of events. Okay. So this is one of the gifts or a world of warning, you know, domain driven design is really a great tool, but it can, it can, it can easily lead us down to in the wrong, in the wrong path and Greg Young said a few, a few, a few, a few years back. You know, in the domain events, it forces you to think about the, the behavior of the system as opposed to thinking about the structure of the system, you know, the, the problem with domain objects and things where we taught with ddd but also you know programming, you know, and so is that is that it's focused you also it, it, you know, it forces you or it leads you to focus on structure too early in the, in the design process. Well, while I think that we should, we should look at the events. We should not focus on the things, you know, this is what we've been taught in all the back of university when I when I took my first C++ course and it will get got introduced all the object oriented programming. It was, it was, you know, it was, it was taught that one should find them find the nuns, you know, because these nuns will become my my my objects in the you know in the in when it comes to domain driven design and my domain objects. Instead, I think that we should focus on at least first, you know, we shouldn't ignore the nuns and the things of course but we should focus first on what happens, you know, the verbs, we try the verbs and because the verbs would lead us to the events while the nuns lead us to to our more more rigid and stationary objects. Okay. But let's, let's take a step back and look at what is really an event and what is the nature of events events represents immutable facts of information. And facts only accrue knowledge can only grow you can't sort of unlearn and for sure you can't forget something but but but but in, you know, on the conceptual level, you can only accrue knowledge and facts, you know, just accrue. This however, you know, of course naturally, certain effects can be regarded and ignored. You might not believe in something that someone said we don't we don't have to accept everything that's being that we're being told is also very important that that events or facts can't be retracted once they are accepted, you know, then they're if you accept a fact, then then then they're part of your of your knowledge or pool of knowledge, so to speak. And also events and facts they are they represent something that has already happened, so they can't be deleted once once accepted. But of course they might have to be deleted for you know for legal reasons you know I think GDPR or more more at least reasons and so on. It's important you know in the way when I say that that that facts only accrue I mean is of course natural like new facts arriving can invalidate all facts or existing facts, because we, you know, we learn and we might change opinion based on new information. So, so we should ask ourselves you know what are the facts mind the facts like a detective, and one really good tool for that is event is event storming. You know, event storming is sort of very practical has on technique when you were bringing all the stakeholders domain experts and programmers into one single room, and your brainstorm using posted notes. And with the purpose then or trying to find the domain language and how we can talk and communicate across these different groups, you know stakeholders and programmers and so on, but do that through events. And we do that by trying to understand how data flows and who's talking to who and an understanding causality I mean what is what is leading to what how facts are causally related, and so on. And the, and the whole idea here is that to really understand how the system functions how it works in real time, not just like a map of stationary objects that might communicate you know that for modeling the objects and the nuns that I talked about. I really try to understand two things. First, the intense. When when we talk about intense we mean looking for things like Sir, these are hints for intense you know communication conversations expectations contracts between parties you know transfer control from one party to another. We also look for for for the facts, and when it comes to the facts you know hints for good facts or state history causality notifications transfer of state, instead of transfer control. And, you know, the intense usually becomes our commands, while, while the facts becomes our events. So this is something that I think it can be can be helpful to to to think about. So let's try to understand how commands and events, you know, work a little bit better here so commands you know they, there are the object form of the method, or an action, or over request. Okay, they're always stated in the imperative, you know the create order or ship product like do something. Well, you know, well, then we have reactions. Reactions, you know the represent the side effect, the result of that command, you know, create the order in order might be created that that sort of causing a side a side effect. But once you have done the job of sort of executing that order, for example create create or created that or then you create a fact, representing, you know, the fact that something was done. So, so an event is really a fact that some representing something has already happened. So they so so events should be always phrased in past tense, like order created, instead of create order order created something that already happened or product shipped, and so on. Make sense. Everyone's nodding. I hope at least. Let's dig a little bit deeper here so and look at the different between commands and events you know commands are really all about intent that they are directed from one party to another from a to B, you know, they have usually a single addressable destination. They, they tend to model personal communication very very well, and they do have a distributed focus. Okay, because they move across address spaces from one component to another from one system to another from from you know into message broker and then off to somewhere else, whatever it is. And they tend to really sort of model very well command and control events are very different you know there are intent or intentless. There are usually in or or true events should be emitted completely anonymously. They just happen you know for for anyone that's interested to observe can be zero can be 10 can be 100. The one emitting the event doesn't care he missed the event and whoever's interested in listening to that can do can do so, as you know, as much as he or he like she she like events model broadcast you know sort of speakers corner, you know me talking to you here I'm, I have no idea how many are listening or if I'm making any sense but I'm making my statements and hopefully state facts, regardless. events have sort of a local focus instead of a distributed focus I only admit events locally they might be relayed in distributed fashion using some other mechanisms but but but but you know concept conceptually you should think about them as happening locally or commands usually only make sense, if I you know in the distributed setting I'm telling someone else to do something. So events really model autonomy versus commands model command and control and autonomy is good right so events really lead us on a really good path here, but but so I think that we should, you know work with the events and let the events define, you know the boundary context and define the protocols that define that you know the the promises that we make tonight or component make to NASA world and and and defines also what happens if we can't keep those those those promises and in a way sort of these are inverts that the control here it's actually characteristic in in in control, and any and in charge of his own destiny. So the question is then how can we do how how can we do that. What are the characteristics of an event driven service. First, you know event driven services they receive and react or choose not to react it's okay to disregard, you know, but event driven service receive and react to facts that is coming his way. They publish new facts. Ideally, I'd say, you know it's not religious here you know sometimes it might make sense to publish facts in a synchronous fashion but I think ideally, they should be published asynchronously you know without any expectation that anyone will ever ever do anything to listen, you know, but it just publish new facts as they as they are created to the for the rest of the world to listen and this really has said inverse the control flow. And in and as is as such you know minimizing the coupling between components and increasing the autonomy, all good things. A lot of people are asking me what about me mutable state, you know, then then if everything should be immutable and immutable you know as a reputation being hard to work with and so on. I'd say mutable state is just, it's just fine. The important thing is how you work with it. I think it's fine, but it needs to be contained. It needs to be non observable to the rest of the world, because if other if the rest of the worlds are depend on mutable state, then they will depend on things that change, you know can change at any point right under the fingers. While while another other component is using it or observing it you know that that that that calls for a very, very brittle design. So so what you want to do you know is you want to contain it in service safe haven and only use mutable state for local computations. Okay, but when you're done with your processing and you're ready to tell the world about your results then you then you can use those immutable values and publish them as facts and to communicate I did this you know this is my result in the published that to the outside world. You know this means that others can then rely their reasoning and their actions based on stable information. Instead of something that might just change at any point in time. Let's look at a little a little example here. Let's say we have we have we have a user it sends a command to this this queue this mailbox or you know in this in this service and some sort of side effect is happening now. So that generates an event. It's it's it's sent to some sort of event stream where other services then can can can pick can pick can pick that up and choose to act on these on these events, or on this event you know single event that that happened. The interesting thing here now you know that this also is a really, really good it's not just you know gives you really really loosely couple architecture and and and and all the benefits for scalability and resilience and all these things it makes it very easy to integrate, you know with with external systems and integrate with databases and other other data storage is you know because of course you can replace one of these services or add, you know instead of course place that you can add databases and then you can sort of like a sort of external systems. You know we can they can all just subscribe to this event that happened and sort of built up their knowledge base of what's going on in the system. It's very important to understand that for this to work very well, you know in terms of the of the constraints of distributed systems. I really think that you know you need to dive into eventual consistency here which might be a little bit scary but it's okay you know it's not as hard as it looks and there are great patterns and tools that will help you work with that. You know if if you do that you know that this pattern is really really good for also managing failure, let's say that that that one of the services crashes here then and loses all this state, you know, then you can just re subscribe to this event stream or pull everything that it missed, or perhaps even like pull everything from it wasn't like dribble on disk you know you can pull everything from from from from from the start of the system, you know, if you but then you need to rely on things like events or I'll talk about in a second, but but it can it can just continue you know, sort of pulling events from from from where it left off when it when it crashed. So, so it makes it very very easy to deal with things like in the partial failures and having having a sort of rigid and very structured way of recovering from failure based on based on events. Do you remember, sort of, you know this picture what has this wild ocean of non of non determinism. I really think that events can help us or craft this autonomous islands or safe islands of determinism and sort of strong consistency and also sort of safe havens in this whole wild ocean of non determinism, you know, in which we can sort of live happily under the illusion that you know time is absolute that there's a single now, you know, and that and that the world is is deterministic, because in within each one of these little islands, no we can sort of pretend that the world is is is deterministic is single threaded. You get you pick a one command after another or one event by from another and you and you and you can execute in things in a linear fashion. The interesting thing is that then you know things can throw crash and burn around you but but but you don't lose your sanity in this little small safe island, you know, of determinism, so to speak. And so, to model this, I think we, you know, we need to go back to domain driven design and and and a really good tool here is the entity. You know, the entity is really is really our, our, our, our sort of unit of, of the integrity of consistency of our unit of failure. You know if it and also our unit of determinism, you know, an entity is always atomic if it sort of it fails as a whole, it moves around as a whole is sort of brought back to life and recovering from failure as a whole. And the entity means that you know that if you if you build it, you know, using event driven design, it is fully autonomous. And the question is then, how do you then coordinate state between all of these little islands, all of these sort of entities. Okay, we ensure consistency and consensus across these these islands, because it doesn't help much if we if we if we have full control in each one of these boxes but but there's no way making them, you know, work together, because I mean all systems are comprised of many different parts of course and they're all as important. So how, how, so how can we put together systems of these little islands them. Yeah, Pat Allen this that is that is, you know, one of my heroes, I've learned so much from him, you know, he talks a lot about you know, defining sort of clear boundaries between certainty and uncertainty. And he has this nice framework, you know, I pulled from one of his papers, where he talked about, first, inside data, that is our local present, or that that is our current present, you know, that's inside this little island inside the box that's our local state. Okay, then we have outside data. That is like outside our little bubble here. He calls that blast from the past. That's our events and our facts are flowing between these islands. And then between the services we have what he calls almost, you know, practically hope for the future. That's our commands, you know how you can dictate someone to do something or order someone to do something. I think this is a really good framework how to think about about the world that at least help help me a lot. You know, and is there a embarking on it on a journey like this if you if you if you model your world using events, and you admit them into an event stream that others can subscribe to. And then then you can use that event stream as a communication fabric between components or services you can use it as an in this integration fabric as I showed you earlier. You can use it as a replication fabric, you know, I mean, means are having some active passive replication where you always have a passive hot standby because that's just consuming the events and in the case of failure. You can just flip, you can just flip over there and it's everything is ready like it doesn't cost you much at all almost anything to have to build the you know really solid replication into the model here. You can also use the event stream as a persistence fabric and that is something I'd like to dive in a little bit deeper on here and talk about event based persistence. You know, the, the problem with crowd, you know, there's a little crowd is great of course it works beautifully in them, you know, in the in the sort of safe haven, you know, say, of the monolith where you can, we can where you can assume a lot of more things than you can do in a distributor system. So I'd say, you know, you know, in the first like microservices in the microservice architecture, you know, each microservice should really own its own data. The crowd as I said is totally fine for isolated data. But the, but you know, the problem is that that that the consistency across crowd services is really, is really, really hard. And, you know, it's really hard to do joins, you know, usually end up with ad hoc or very weak guarantee guarantees and, and, and, you know, Pat Helen he in his in his great paper standing on the shoulders of giants he, you know, he's he said that to face commit essentially transactions, you know, cross across, you know, contexts is the anti availability protocol. You know, it leads to poor availability, you know, to face commit introduces a sort of temporal coupling and there's really no way, no good way of say to deal with with with partial failures, which is quite common in the distributed system you end up with poor scalability, you know, we're usually very high contention blocking way time and really bad performance, you know, because usually baller necking on those on those cues so and and and and and most of these transaction algorithms, you know, have some so have some some moments of stopping the world to ensure strong consistency. I really think that strong consistency is the wrong default in distributed systems. It's nothing wrong with strong consistency when it when it fits is beautiful it makes our lives a lot as developers of course a lot easier. But I don't think we should opt in on strong consistency as the default as the first thing we do. Why because it's really hard to make available. And you know, on the question. Okay, how does it map to the real world. Yeah, when you look at it and think about it, it's actually not how the real how the real world works at all. We never have strong consistency in the real in the real in the real world. And, you know, the real world is all bent on events flowing causality, you know one thing leading to the next, you know, spring it back from here and so on for all the asynchronous and fully autonomous, and so on. And we get by in the real world, just fine right so so so it's not so scary to dive into that world when it comes to building systems as well I think, because if we do you know if we if we use strong consistency as as as a as a default and and and you know it I think it just makes things work worse. And the question in that is then, what can we do. We have to rely on on an eventual consistency and you know I don't think as I said he says it's it's as scary as a lot of people say it's it's actually, I just encourage you to relax, and just think about how can I best model the real and because usually that's what we do as programmers we try to model the in some sort of business, business cases or business rules and you know operate you know model some some real world scenarios and, and when you really think about it it's usually all based on a strong consistency in the end. And, and, and so start with that start with try to model it using using eventual consistency and when you see an opportunity for strong consistency. Feel free to use it you know it's great stuff. But, but, but you need to be be sure that that the price for using it is not too high as effectively. But the main problem with crowd is is updating place and Jim Gray another one of my heroes. You know he, you know he's one of the ones doing most groundbreaking work on transactions and transaction processing. You know he said, in 1981 that update in place strikes the system designers as a cardinal sin, it violates traditional accounting practices that have been observed for hundreds of years. You should let us sink in. And again, you know, we should learn from the real world. Okay, if updating places so bad I mean how, how do we, how do other, other, you know, you know, so fields or, or, or, you know, industries doing it. I think we should just go back and look and relearn basic accounting principles, you know, and, and, and it's doing so, you know, we might have a lot of learning to do because we've been spoiled by computer science in this in the world of one machine one core one thread or whatever it is you have worked for too long. So, I really think that we should we should we should learn to rely on proven practices for bookkeeping you know they you know that's really technology that are centuries old, and has proven to be really good way of making sense of data. And the main concept sort of concept here is is is event logging. You know, if we translate that to our, to our, to our world here and event logging means that you store each event in the order they arrive durable on disk, just like transactions in the ledger, you know, like you can see on this picture here. And if we if we do so, you know, I think that event logging can really be the bedrock in our system that we can build, you know, that we can use to build consistency, you know, availability, scalability traceability, you know, that it can really be our source of truth in the in each system. And, you know, Pat Helen again, you know, he said in this really great paper immutability changes everything that the truth is a log, the database is a cache of a subset of the log. You know, this. There used to be a reason to use update in place in a disk space used to be quite expensive. But today is is is really really cheap. So there's really no reason why we, why we can store all events that ever happened in the system meaning all history forever. And the question is then why should we work with the cache of a subset of the real thing. Why not work with the real thing directly. And that is the event log. So, and that leads me to event sourcing, you know, that's a great pattern sits right on top of the event log, and I think that can be a cure for this cardinal sin, you know, update in place. And event sourcing is really is really easy, you know, it's just that you log every state changing event to component in the order as they as they are created. And, and, and, you know, and we use that sort to turn back up the entities. So we can have strong consistency as I talked about within each entity. You know, we have this this safe world safe haven this this island of of determinism so with which we within we can have strong consistency. And then we have an eventual consistency between the entities or the services. You know, and if you if you if you work like this then you, then you can have sort of then you have a way to replay that log, because all the history that happens to a service and the whole system if we look at a specific service, you know, everything that ever happened to that service is you put it up is stored in the order it happened, you know, so so this means that we can replay that log to bring the component back into into into into good shape after failure, we can we can replay it to do replication if we want to replicate something to some other place that we will get an identical replica because it's based on the same history. We have really rock solid audit without doing anything really. It's already we're there right in the event log, we can just look at it. You know so there's there's a lot of things we get for for for free here that actually are quite hard to build in a distributed system or in the cloud cloud based system. So let's look at an example here in events or service here we have some some users it's it sends a command, it ends up in the component, you know, and some side effect is triggered. Okay, we were talked about this out of that side effect I created an event representing what what just happened, and I'm storing that in the event log in the order as I'm doing that as a service. Okay, this is the happy path everything goes goes goes well I can I can push it out to the event bus, so to speak the event stream, and others can consume that event at their own pace. Now, now let's look at what happens. If we enter the sad path sir when we have to when things fail and we have to recover from failure from failure. It's very very easy we have we have we have the event log. The only thing we need to do we is that we bring we sort of re hydrate the events bring the the component back into into state. And that's it you know, then then it can then it can continue to serve new commands and trigger new events that we then emit out. So, event sourcing really gives us a single source of truth. You know, with all history that that's ever happened. And it allows for this for this pattern, you know, I encourage you to Google it memory memory image Mark and Fowler talks about that. You know, where you sort of have a way to have durable in memory state is sort of inverse the database in a way so your source of truth. You know becomes what you have in memory instead of what you have in memory is usually just a cash and the source of truth is in the database. You know, this is this are really event sourcing allows you to really invert that. So your source of truth. And the state that you can rely on being always correct is in memory. And you have sort of backup down on this. And just think yourself with what that opens up for when it comes to performance, for example, and, and, you know, if your data is always available in the memory and it's always correct. You never have to go down to the database to fetch it and causing all kinds of contention and then you're relying on a single point of bottleneck and single point of failure and so on. Of course you need that for the event based system but that can have but these things can be completely decoupled. Sorry, I got some notification from from zoom. Are we still running. I hope so. Okay. Another thing that it avoids is this, you know, in famous, you know, object relational mismatch in which you, you know, if you have a component models and for object oriented model you're always have to match that to tables in the day in the in the database. And that's why we got tools like, like hard, like higher hibernate and so on. It's, it's quite the hassle, both to map that correctly and efficiently but also maintain it. And then sourcing, you don't have to think about that you can you can work with your, with your domain model, you know, in the component in memory. You know, completely, you know, you know, oblivious, say, of how it's being stored, because, because it's all just events in the vent law. There's really no mapping at all happening which means that you that you can you can just have the ultimate way of working with state, as you would as you would like. Okay. Which is really beautiful. It also allows others to subscribe to state changes, as I talked about. And that's a really good side effect. It has really good mechanical sympathy mechanical sympathies or is a term that you know Martin Thompson often uses. And it and it and it means that it lends itself very well to modern hardware, you know, and in this in this in this particular case, you know you have the, you get sort of the single right to principle for for free where we can just have one thread just writing very very in a to disk in order just depending on pending and pending and pending, which means that you can move very, very fast. So that's all good but what about queries then, you know, I, so we use the event log for storing the events that is our source of truth queries is harder, you know, an event log is hard to query, you know, that's that that's one of the downsides here and CQRS can can really help you know because that's why you often see events working used together with CQRS CQRS means command query, responsibility segregation or separation. And, and you know the interesting here is that is that CQRS allows you to separate the right from the real model, you know they usually have very different characteristics in terms of consistency availability, you know scalability, and by separating the read and the right model from each other it allows you both sides to be stored in the optimal format on the right side I already talked about you know the only good things you get with restoring the right side in an in an event log. The read side you have many options, you might want to store it in a relational database in a no secret database in a graph database you might want to push it into the spark or flink or something like that. So it really gives you a model for polyglot persistence because you might want to mix these you might want to put into SQL database and graph database for different ways of looking at the data, for example. If all this is abstract, let me try to illustrate this here so let's say you have a user it sends a command to this to this service. This service now serves the right side model here is where we write to the event log. Okay, once we've done that was omitted to our event stream or our event bus here now, the read side model can pick that up and read from the data store, or actually, you know, the data store picks it up and stores it that can serve their the read model that that's a more accurate way of talking about it and this and this data stores it can be any type of database, you know, it can be a do if you like that or whatever. And then you, and then you, and then you can serve those that you know the queries from the read side completely independently of the right side. And this gives us a lot of a lot of good things you know it gives us increased resilience you have, you have, you have temporal decoupling of rights and side effects. And, and, and, and you know, and you know one good thing is a service doing the right and the service performing the side effect, they don't need to be available at the same time. It also helps you with increased scalability where you have like scale and you can scale the reads and writes completely independently of each other. For example, you might have a right mostly system, you know, where versus another situation where you might have a read mostly system so it gives you sort of more knobs to turn and to tweak, and not having sort of one getting each getting in each other's way you know sort of with a always ending up with the smallest common denominator. It also allows you to have multiple events subscribers as I said you can have multiple views of the data success, you know how the other systems pick picking it up at the services other database and this answer true polyglot persistence as well. One, one important aspect here though is is is that you know to get most of the benefits of resilience and scalability you should rely on eventual consistency in in practice it usually in in my experience it usually is not a problem. It might be sometimes you know, if there is a delay in the event propagation it might be that you sort of don't read your rights in a way you know you send a command and then update it and when you and when you read the query, you know it's still not there, so to speak. There is a solution for that though and that is that you can use a single database for for to serve both your region and your and your rights and then rely on on the database you know, you know functionality for strong consistency and transactions. And we should try to illustrate this here you might replace it with a single database here where you can write to the event log in the database and in the same transaction up to update through the real side the query side in the same database so you can serve both the right side and the right side, you know, using the same database, you know this if you if you have I'm only bringing this up, it's not something that I will I will recommend you start with. But but if there are use cases that absolutely demands strong consistency you can still use that in a in a in a in a CQRS event sourcing type of type of setup. You know, you know, all these sounds great and and and I hope at least I think it's great. But then the, you know, some of some of you might wondering, you know, okay, how do I go about and implement this for real in the cloud or on prem but let's let's look at the cloud here now. The problem with with with cloud native as we are. You know, it's not that all of these things that I just talked about might be hard but we are, you know, in terms of infrastructure is drowning in complexity, you know, Kelsey higher tier post this is sort of amusing tweet a few, a few months, a couple of months back. You know what he says you're rolling your rolling your own platform has never been easier. All you've got to do is pick 200 items from this list and you're, and you're good to go. You know, and this this image is taken directly from the from the CNCF website. You know, it's it's it can be it can be overwhelming. There's so many products, all good, you know, not all good but many, most of them I think are really really good. How do you choose which ones fit your use cases, and how do you stitch it all together into into single in a coherent working system how do you maintain guarantees across all of this all of these products how you how can you ensure to your to your customers and user that you can maintain the place that you that you have have have promised you know things usually fail between, you know, at the boundaries, you know, and then where you need to do handle between different subsystems. And if you have to stitch it together a bunch of subsystems yourself, you know, then you're, you better know what you're doing. So I all that all that is very hard I think we need to continue to climb the ladder abstraction you know we've been doing that as an industry over and over again, you know, we started with, you know, with punch cards, you know, and then you know, and then we got to, you know, assembly and see and then more modern languages and, you know, when it comes to to to to hardware, you know, we, you know, or, you know, or sitting right on top of hardware we get into virtualization, you know, Linux containers, you know, let it to Kubernetes and Docker and hold on this whole ecosystem. You know, we're constantly trying to do to climb this ladder abstraction and, and to do more with less. And, and I think it's about time that we do that again. Yet another time I don't think you know Kubernetes and and and and and switching to get the your own stack over and over and over again it's really, it's really necessary, you know, some of some might like it, and some might feel the the necessity to do so but most I think not. So, so I think the the really important thing is then is then what is that I think we really need to provide more higher level developer experience and API for developers to building these new classes cloud cloud cloud native applications and and and all in, you know, leading to liberate the developers to focus on the essence, you know, and that is that is, you know, building business logic, building, contributing directly to business value. But that's hard, you know, in order without sacrificing things like developments the speed, you know, cost can't go across the roof, especially nowadays, you don't want to, you know, you don't want to sacrifice predictability or maintained ability. So I think, you know, the good, a good starting point is to sort of distill the essence, sort of, so coming from a different angle, sort of distill the essence of what a developer actually needs to focus on. What is the bare minimum that a developer needs to do to contribute business value every day and nothing else. You know, I think it's sort of essentially three things, defining the API. I mean, how do you communicate with the outside world, and how do you communicate between through the contracts between the different services. How do you define your domain model, you know, you know, working with these events first domain driven design if you like or, or, or, or something else but but come up with model for my how do, how do I model my business case how do I model my domain here. You know, big state, you know, flows streams and so on. And, and, and lastly, you know, the, how do I, what do I do when I, you know, react on requests from from my users and what is what what drives sort of this whole domain model is the business logic, you know, so you have the API the domain model and the business logic. I really think that the rest the rest can be eliminated and should be eliminated. So there's, there's, I think, you know, the rest can be generated from the code. And there is sort of a new class of developer passes that really tries to address this. And you know, and one of them is Calix. You know, Calix is a is a is a platform as a service, sort of a true developer pass that enables organization to build and deploy cloud native event driven and fully distributed microservices, rapidly with no operations required. What does that mean yeah it means that Calix makes it very easy to build a complete cloud native stack, you know, an improved developer product immensely, you know, and, and, and he does that by providing serving out of the box cloud native. Cloud native stack. All powered by a really, really high velocity developer experience. Where, you know, where, where you do the work right in the code. And then you ship a ship that up to to the calix pass. And then your, your, your, then your job is done. There's really no operations required whatsoever. All that is on us, you know, we have we have a 24 seven s RET that that that that making that's that's making sure that everything just constantly like constantly runs is upgraded to the latest versions. You know, making sure that you know that that everything runs runs smoothly. And, and, and, and for us as a developer you know calix gives you really best in class top class high performance and scale and scalability you know we, we can, you know, in the in the latest benchmark we ran we we were serving reads at about six millisecond and writes at about eight millisecond, you know, round trip all the way from me from me from me getting the request from from the from from the you know, from the developer all the way down to the database and all the way up again, which, which should really be enough for most use cases. So, so a way to try to understand what calix does for you is like, I want you to try to envision your application necessary of a cube. That's your cloud native stack. Okay. At the bottom we have like cloud infrastructure like AWS Google cloud Azure. The second layer, you know, is Kubernetes, you know, running on the EKS OpenShift and Rancher and whatever your, your, your poison is there. Then we have the database layer, you know, there might be one database that that you choose or multiple depending on the use cases most most non-trivial use cases are polyglot persistence today in my in my experience it might be like Cassandra, you know, Amazon, DynamoDB, Spanner or Cosmos, UGB, whatever. Then you need a layer of security and compliance, you know, zero trust, multi-factor authentication encryption, you know, usually things like JWT support, client-side certifications and compliance like things like SOC2 and so on. And GDPR, of course, and all of those things quite tricky stuff to get to get right. Once you get that done right, you know, all these first four layers, then you can start, you know, building pulling together the infrastructure that's more of the fun work for a developer to some extent because he can often be overwhelming of course. But here you have things like service meshes, API gateways, message brokers, you know, not gateways and so on. Finally, when you're done with all of that, you know, then you can start building the app. But the problem is that when then when things are moving, you know, underneath, you know, sort of shakes the whole cube, you need to go dive down there and start fixing things, you know, replacing, you know, infrastructure, you know, doing updates and whatever it might be. So, so effectively, you know, this is your cloud native stack, you need to deal with all of these things in order to build a full complete cloud native application. So where does Kalex comes in? Kalex really allows you to focus only on the top level, you know, the only thing you need to do in Kalex is to focus on writing the code, you know, collaboratively configure that code. And the rest is on us, the rest is on Kalex really and everything around integration, security compliance database, Kubernetes management, cloud infrastructure, etc, all that is on us. So it really eliminates, you know, it's effectively all complexity to bring building a cloud native application. So what are the components? I don't have too much time to dive into, you know, what Kalex is, but I just want to give you a glimpse, it's probably the most developers here. So what are the Kalex components that you can work with? At first, we have the entity that I talked a lot about here. That is sort of a stateful function, allows you for like multiple durable storage models. You can choose the right sort of shape of your data, it might be key value, event sourcing might be what works well that I talked about, where it might be in a replicated state using CRDTs, you know, key value is more like crud. You know, working with this entity is a really, really high level abstraction that removes all the complexity around data distribution, things like caching concurrency distributed locking transactions and all of those things. You know, it's sort of you most often paired up within what we call an action and action is a stateless function. And you can use that for many different type of patterns like handle entity changes, subscribe to message brokers, building sort of the API control or pattern and so on. Then you have a very interesting concept called views, you know, they are really, they're truly materialized views and allows you know streaming views in real time, all the way out to the client using HTTP or DRPC. And in it gives you a really good model for modeling CQRS that I talked about that you have the entity and then you have the view you have the right and the read side. Then you have, then you have timers, you know, they're usually they're small, but powerful. You need them, you need them. And the latest addition to the careless components is something we shipped about a month ago now that is that is high level workflows, making it possible to do this, you know, this coordination and orchestration across these are safe islands that I talked about, you know, the entities. Buildings are distributed transactions and by implementing the saga pattern. If you don't know that I encourage you to Google that it's a really good pattern to have under your belt. But workflows implements that. So, and in workflows you can declaratively just define every all the steps in the workflow, and have a structured way of doing, you know, compensating actions and go into the next step and what happens if there's an unavailability or failure and so on. So it's effectively gives you a structured state machine how to work with with with long running transactions. So I just want to give you quickly a little glimpse in in in what it won't be okay this can look at your own there on the left hand side here, you have the developers responsibility meaning your responsibility on the right hand side you know you have you responsibility. So, so let's start by writing so very simple state for microservice and that's our in this in this in this case I'm picking the event source persistence model just because we talked a lot about it and and and as you can see here we create an aggregation entity. I don't have time to go through the actual use case here but but it looks more or less the same regardless of what you're doing. I'm inheriting event source entity this isn't Java by the way, and, and, and, and the interesting thing here is this is the lowest aggregate function it takes a request meaning the command here. And, and it, you know, it, it, it, it does is logic. I've sort of omitted that code here, but when it's done is sort of creates an event is add for aggregation event it emits event to the rest of the world to see and to be stored in an event source fashion, and then it replies with an acknowledgement saying okay, you know that's a code now you can see that you think these annotations here we are declared to be config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config config out of this. You think, I mean, enable it where you can choose to enable it through HTTP or GRPC or both. So that is the entity side. Now, let's say that we want to implement CQRS here and do a query representation as well. So a read side representation. It's no more code than this actually, where we hear CQRS with this API query view, where we extend the view, this sort of materialized view. We set the request mapping here to be slash API query. It means that clients then came through our HTTP endpoints and just get a streamed, sort of get a stream with constant updates based on what's going on in this particular view. And you can see here that we have this method get aggregation key. We annotate that with query and here we're able to put in sort of a SQL query. It's actually not a true SQL. It's actually querying the entity. It's querying your object model. So if there's an object query, query, query model here, that you can, where you can, so you don't end up in having to map your object, you sort of your domain model down to the underlying database. The underlying database is really nowhere to be seen. You always work on the highest level possible, meaning your own domain model. But from the simple query annotation here, where we define our query, we're able to create a fully streaming real time materialized view for other services to use, but also for your clients to use. So that's your responsibility, right? This code declaratively annotated how you want it to operate. And out of this, you know, Kalex can then infer everything else. So we have sort of infrastructure inferred from code. And this is just sort of a simplistic architectural diagram of everything that Kalex does for you. And this is, of course, more. But, you know, in essence, you know, what you can see here, you know, it generates a complete reactive event driven platform stack, cloud native stack with ingress routers, you know, service mesh, security with secrets ACL, you know, JWT cert, you have a fully ACA based sidecar cluster, you know, that's using gossip protocols to ensure availability at the highest level. And, you know, each one of these functions is deployed on a Kubernetes pod sitting right next to the sidecars. You have extremely efficient communication between the sidecars representing the user code and the user code itself. And this sidecar then manage things like, for example, PubSub, we have broken less PubSub over JRPC that's extremely fast, or you can choose to use something like Kafka or GCP PubSub or AWS DNS. And then the sidecar also manages all the distributed storage in the event logging, these materialized views, and so on. And all these, all these, all the right hand side is completely generated for you in the optimal fashion based on your source code on the left hand side. So you have really good separation of responsibilities here, leaving the developer with only the minimum it needs to do to implement a full cloud native, super fast, you know, reactive, highly performance stack. So the key takeaway here is that I think events, events first design helps you to build, to reduce risk when modernizing applications, it allows you to move faster towards what we all want, you know, resilient and scalable architecture. And it really allows us to build highly autonomous services, you know, and autonomy means that we have a way to balance certainty and uncertainty, you know, being able to contain, you know, certainty and having really good patterns to deal with the uncertainty. Event logging, as I talked about allows you to avoid, you know, crud, avoid ORM mapping and really take control over your system's history. It allows you to time travel even when we talked about that, but it's an interesting concept. Maybe you can go back and replay certain parts of your, of your, of your, of your history and so on. But more importantly, allows you to balance strong and eventual consistency in a really good way, I think. So how do you implement that? I think KLX is probably the best platform to implement all these events first, you know, event logging, event sourcing type of type of system, truly event-driven microservices, because it really gives you, I mean, really, really low time to market while reducing the cost. And it allows you to focus, you as a developed focus on only the three things that matter. I think, you know, the API, the data model and the business logic and delegate everything else. Delegate operations, you know, true zero ops within, you don't need an SRE team or on staff, you know, to, to run this stack because all that is on life, man. And, and you can ensure that, you know, by just writing this code, pushing it up to KLX, you will run on a full reactive event driven, very high-performance infrastructure stack. So, so please check KLX out. Go to KLX.io and scan this QR code here and, and, you know, and it will, it will, it will send you to a page where you can explore KLX virtually and then you just download it and try it locally yourself, you know, no strings attached. And, you know, if you like it and you, you know, and, and you, and you built a, a, a POC or, or a, or a dam or whatever, then you can just go to KLX.io and upload it there and we run it for you. We also have a Slack channel, you know, hashtag KLX support. But go to KLX.io and scan this QR code and, and we'll, we'll be there for you answering all questions. Thank you.