← все видео

Workflow Wars: From Kafka Chaos to Durable Dreams

Platformatic · 2025-11-06 · 49м 31с · 187 просмотров · YouTube ↗

Топики: durable-execution

🎧 Аудио

📝 Summary

model=deepseek-v4-flash · prompt=summary-v7 · 9 678→2 530 tokens · 2026-07-20 14:59:34

🎯 Главная суть

Обсуждение эволюции инструментов для долгоживущих транзакций в распределённых системах: от Enterprise Service Bus и очередей через Kafka к современным workflow-движкам вроде Temporal и use-workflow от Vercel. Основные критерии сравнения — надёжность, наблюдаемость и developer experience.

Проблема долгих транзакций

Любая реальная операция (покупка в супермаркете, начисление бонусов, перевод денег) — это мутация состояния, которая может длиться неопределённое время. HTTP-запрос не может висеть минуты или часы: соединения рвутся, file descriptors кончаются. Поэтому систему проектируют так, чтобы быстрый запрос (миллисекунды) запускал асинхронную обработку, состоящую из нескольких шагов. Эти шаги должны быть идемпотентными, транзакционными и устойчивыми к сбоям.

Эволюция: от ESB к очередям

Двадцать лет назад задачу решали Enterprise Service Bus (ESB) — тяжёлые брокеры (Oracle ESB, Microsoft BizTalk) с проприетарными DSL и XML-конфигурациями. Они обеспечивали транзакционность и логирование, но были крайне вендор-локальными. Затем пришли очереди сообщений (ActiveMQ, RabbitMQ): более лёгкий подход, где сообщения пишутся в очередь, потребители забирают их и обрабатывают. При сбое сообщение возвращается в очередь на повторную обработку, а после нескольких неудач попадает в dead letter queue.

Ограничения очередей

Для сложного процесса из нескольких шагов с задержками между ними приходится вручную разбивать логику на отдельные очереди и обработчики. Например: шаг 1 → очередь A → обработка → шаг 2 → очередь B → обработка. Если на шаге 2 произошёл сбой, нужно корректно откатить предыдущие шаги или сохранить промежуточное состояние. Это превращается в сложную ручную работу: каждую подоперацию нужно отдельно развертывать, мониторить и обрабатывать ошибки. Разработчик фактически строит state machine на очередях.

Kafka — не панацея

Kafka — мощный инструмент для стриминга событий с высокой пропускной способностью, гарантией порядка и возможностью воспроизведения лога с начала. Однако использовать Kafka как единственный брокер для workflow-задач — «эффект крутого парня». Он не решает проблему хранения состояния между шагами, не предоставляет транзакционности на уровне шагов и требует дополнительных хранилищ (Cassandra или Postgres) для фиксации мутаций. Kafka — скорее «прославленный хореограф», который координирует обмен сообщениями между микросервисами, но не управляет самой логикой долгоживущей операции.

Temporal: клиент-серверный workflow

Temporal (коммерциализация Uber’s Cadence) предлагает принципиально другой подход: разработчик пишет код workflow на обычном языке (TypeScript, Go, Java, Python), а Temporal server гарантирует, что выполнение будет устойчивым к сбоям. Workflow-код исполняется в worker-процессах, а server хранит состояние и восстанавливает его при перезапуске. Это даёт высокий developer experience — пишете нормальный async/await, а за надежность отвечает runtime. Минусы: vendor lock (хотя код открыт под MIT), необходимость разбираться в SDK, специфичные концепции (workflow, activity, сигналы). Кроме того, Temporal — это отдельный кластер, который нужно администрировать.

Use-workflow от Vercel: компиляция и «worlds»

Vercel представила use-workflow — workflow-движок, основанный на компиляции. Разработчик помечает шаги директивой use step (или use workflow), и на этапе сборки компилятор преобразует их в долговечные объекты: сохраняет входные и выходные данные каждого шага в хранилище. Для хранения используется «world» — адаптер, реализующий интерфейс долговечного выполнения. Встроены world-ы: in-memory (только для разработки), Vercel World (для production на платформе Vercel), и community-версия на Postgres.

Сравнение Temporal и Use-workflow

Temporal — это runtime + SDK. Workflow-код исполняется воедино с worker-ом, а server управляет состоянием. Use-workflow — это SDK + разделение на compile time и runtime (world). В Temporal код выполняется динамически, можно добавлять шаги на лету. В use-workflow шаги фиксируются на этапе компиляции; версионирование и обновление workflow требуют перекомпиляции. Use-workflow не предоставляет такого же набора enterprise-функций (наблюдаемость, управление версиями, повторный запуск с точки сбоя) — они ложатся на реализацию world.

Критика use-workflow

Необходимость компиляции выглядит избыточной: в Java или .NET аналогичное поведение достигается атрибутами времени исполнения (reflection). Для JavaScript/TypeScript компиляция может быть оправдана техническими ограничениями (сложно сериализовать замыкания и closures), но альтернативные реализации (например, проект Армина Ронахера) показывают, что можно обойтись без компиляции, используя TypeScript и Postgres. Также остаётся вопрос, насколько use-workflow будет надёжным вне экосистемы Vercel: community-адаптеры могут не достичь уровня Temporal.

Альтернатива: простая реализация на TypeScript и Postgres

Армин Ронахер (создатель Flask) опубликовал реализацию durable workflow на чистом TypeScript и Postgres — без компиляции, с минимальной обвязкой. Код выглядит чисто и не требует отдельного шага сборки. Это показывает, что концепцию durable execution можно реализовать достаточно просто, не прибегая к тяжёлым фреймворкам или проприетарным платформам.

Нерешённая проблема: поиск идеального примитива

Несмотря на множество решений (очереди, Kafka, Temporal, use-workflow), в 2025 году всё ещё нет единого, общепринятого примитива для долговечного выполнения. Каждый подход находит компромисс между надёжностью, developer experience и вендор-локализацией. Возможно, следующим шагом станет создание легковесного, открытого runtime, который будет «выводить» workflow из обычного async-await без дополнительных аннотаций — но пока это остаётся предметом экспериментов и обсуждений.

📜 Transcript

en · 6 312 слов · 103 сегментов · flagged: word_run (1 dropped, q=0.99)

Показать текст транскрипта
Hello, hello, hello. We are back, Theo. Hello, hi, Luca. And we are back. Wow. Another week at the banter. How are we doing? After a week that we were a little bit busy, finally we are back. Great to be on the ground, even if I don't think I'm going to last long on the ground. But I was excited about the chat that you're going to have today. It's a dear topic. Absolutely. Distributed systems. We started more or less this podcast with distributed systems in mind and we keep coming back to distributed systems. So it's well, everything is a distributed system. Yes, bread and butter. So yeah. And well, where to start? Let's start from Where? I think our chat should start from once upon a time. Yes. That is the old, old time ago when I think we are going back probably 20 years when we were in the world of the ESBs, right? Enterprise Service Bus, the world of SOAP, when systems needed to communicate with each other and we started to kind of like put a broker in between, the so-called Enterprise Service Bus. And clearly we remember the famous Oracle one and the Microsoft version. So let's talk. And the goal of the systems was to basically handle coordination between integration systems and system of records within the organization. Yes. But also to create like a common layer of communication between them. And the. The main topic was that the task might take an indeterminate amount of time to be executed because we don't know exactly the length of the state change, but that we make stateless system and we try desperately to do it. Every system goes back to a state. If you think, for example, that when you go and buy some groceries in a supermarket and you collect the points. Right. This is like a state mutation on your wallet, right? Yes. Yes, it is. Yes, it is. Even the banks, right? When you add the money, it's a state mutation on your balance. So there's always this thing of state mutation over time. And the fact that the transaction then is a very long lasting transaction, right? It's incrementing, it's mutating a long time. So, yeah, and we came to 2025, the area, the moment when we saw many, many systems kind of like, you know, joining the open source ecosystem, joining the front end ecosystem. But I think before we delve into that, I think it's interesting to bring to surface that there was a company that back in 2016 kind of like figured this thing out a little bit ahead of. many others was Uber when they basically said when you order a cab ordering this cab is a state mutation and all the status of these cabs to be available or not these drivers is also based on state mutation so they were the first one to kind of like approach this this problem at distribution but let's uh jump into the world of node by the way uber was node at the time no clearly go uh but yeah and the when the magic world of workflow engine because that's been become from n8n to node red to many other they kind of like took you know they became popular and now especially with ai and agents they became even more popular but Yeah, let's go there and probably Kafka is going to be still there. And then, yes, we have Kafka, of course, in between, which is probably the most modern thing for doing those kind of stuff. Then we got Temporal, which is very interesting. And finally, the latest addition to the show, the workflow dev kit from Vercel, which wants to be the next JS for backend. So... We have all of those things and it's a long journey. OK. Yeah. And first of all, let's talk a little bit. What is the key problem that all those tools kind of solves to some extent? OK. And I think you touched briefly into that. OK. Which is, you know, when you are implementing a digital system. okay, an application, an agent, whatever it is, it doesn't matter, an API, okay, you have, you need to respond quickly, generically, which, you know, quickly depends on the system, but typically in the scale of milliseconds, okay, might be in the scale of minutes, but you know, that's slow, okay, definitely not in the scale of hours, okay, because we all know that there are the big scissors of the net that are passing by and cutting connections. and connection can fail at any given time. So having a request that lasts for a long time is really bad for user experience, as well as it's very high likely or failing. Also as a physical limitation, right? Because then I title couple the number of file descriptors with the number of people on the planet. Absolutely. So we want to be very quickly open and close. This means that if my processing cannot be done in just a few milliseconds of processing, I need to do it. I need to start some asynchronous computation and finish that later on. A lot of this is, to some extent, it falls in the topics of... A lot of this has been explored by domain driven design, CQRS, common query, responsibility segregation patterns, and so on and so forth. Event sourcing, all of those things follows a little bit of that kind of pattern of I have data that I can more or less read very quickly. And then if there is any mutation on the data, it's done over time. It takes a long time to process that. So it's a little bit long time to do the processing. Why? Because I need to very often to do a lot of things after the fact. So I think there are a few key ways in which this kind of system could be done and implemented. And they have been done in a lot of different ways. And a lot of the discriminator here is the The various axes, I think, in which you can evaluate all the techs, all the various technologies are reliability. You don't want to miss anything. I would call it observability. You need to know what's happening and you need to know what happened and when and how and why and all sorts of things. A lot of those systems work in regulated fields. So you need to keep an audit log essentially of what things happen or what happened. Okay. Last is essentially developer experience or developer velocity. Okay. How much time it takes for a team to get this shit done essentially. Yeah. Because to be honest, developers are not cheap. Okay. And you need to have experienced engineers to build those kinds of systems. So, first system, first queue system that I used to interconnect things was, I think, ActiveMQ and then RabbitMQ. Okay, I think those were kind of the first, but it was a long time. Apart from now, there was the ESB, of course, the Oracle ESB. Yes, there was the Oracle ESB. There is something right there that probably we forgot to mention that that is the kind of like concept of transactionality, right? Yes, yes, exactly. So the thing is that when I mean, the reality is that there are two major problems. The first one is that every single operation in the real world is still transactional. Right. I mean, that we like it or not is a composition of different actions that they result in cause and effects or causality. The other thing that is kind of like pretty interesting to address is that, and you said it, is the reliability, right? So how do I do transaction rehydration in case of failure? How do I actually, how can I make sure that the system doesn't go in a faulty state because I'm trying to reprocess operation or my state is pending, you know, hydration? So I think... what Bitstock at the time kind of like was extremely strong was the concept of transactional hydration so if I stop an operation I can restart exactly the point where it was stopped and continue I mean this kind of like modern systems especially with agents this is kind of like extremely common as you said because there is the concept of time like you know an operation goes for an undefined amount of time and i don't know if it will succeed fail what what's going to happen right so uh i think that's a very important kind of like uh uh thing um but yeah no please continue in potency idempotency that's yeah so idempotency the the the yeah because currently we are um we are in a system where concurrency is uh in place right uh and ergo we want to actually operate on idempotent operations but the the thing that is interesting is a lot of people they told me yeah it's very simple i i embed everything in a in a store procedure uh in a database and i do a transaction which kind of like is not it's not false But it doesn't work in a distributed system, right? So probably it's interesting to deep dive into that. Maybe not, just don't. Yeah, no, but basically what these workflows are doing is kind of like the same, right? So if a step fails, they roll back the state and therefore each step they have a status checkpoint, right? Yes. So they implement the concept of transactionality per step. they do commit only at the end of the workflow or when you tell the workflow to commit. But I mean, probably let's go into the connection between like I know the workflows. I wanted to chat a little bit on using first of all, using queues of one side and then using what the name using queues, then using Kafka as a broker. as a broker, and then using the complexity in developing those systems, and then using Temporal, and then finally using user flow, and so on. So Temporal, by the way, just open in close bracket, is the commercial version of a product that the Uber product I mentioned is called Cadence. So if anybody, they come from the same source. But if anybody wants to check, Cadence is the system that Uber uses. So the problem, part of the problem is when building this kind of queue based systems. OK, so how do they work? You have one process, one one part, one process, one Lambda, whatever that write a message to a queue. OK, that queue. And then you have another process somewhere, another program that pulls the message from those queues. OK. and do some processing on those things. If things fail, they go back into the queue to be reprocessed again in the future, very often. After a little bit of time, they go in what is called a dead letter queue, which is another queue at the bottom, which keeps accumulating things. We get the error to avoid infinite retries problems. So that's the queues. However, you typically don't have one queue. Let's say that you have a complex state machine or a complex program that needs to be, you know, that has, I don't know, four or five, six, ten steps that happens with some significant delay of time between each other. So typically it can be, oh, me showing processing on a queue. There is some kind of long, long time operation that needs to... complex operation that needs to happen. Then it goes into another queue because I want to save the intermediate step. The key part here is if I have a long chunk of processing that, I don't know, it's maybe will take five, ten minutes to do because it's a lot of work. It might be a lot of work. I am interleaving it inside in steps in between so that and having those systems communicate with the accused. OK, so that the intermediate steps are always saved and can be resumed. If one fails, I'm not losing everything, but things can be debugged and restarted. I built in Incredibly complex system in this way, using SQS and using SQS or Rabbit and so on and so forth. You could go as complex as you want in these systems. They work very well, but they require... You need to manually break the execution down and handle all these individual steps separately, essentially a separate deployment almost. well plus there's the the complexity that you are basically taking a set of operations that they are atomically a transaction break it down into steps if a step fails along the way you need to handle the rollback or state alerting and then kind of like dismiss everything put in the dead letter queue it's i mean i think cues they are interesting but they are a little bit kind of like lame, if you mean, building all the thing because, yeah, at the end of the day is a queue. But I mean, is there any better system to do that? Oh, you know, there is a better system, right? Kafka, is Kafka better system? But Kafka is not enough, right? Exactly. OK, Kafka is not enough. Kafka is a phenomenal thing to stream events. It's a phenomenal thing to stream things that happen and replay those things that happen. It's phenomenal for that. You can increase massive throughput. It's a clear way to guarantee that given an incredibly high amount of data and input, all that data gets processed in order and everything is managed correctly. For that, Kafka is one probably of the best tools on the planet. Okay. It's also given it's a log, essentially, it's, you know, and you can replay. So you can go back from the beginning of all the messages being sent and replay all of them. Okay. It is essentially the ultimate write log type of thing. Okay. You could essentially use Kafka as your essentially source of truth and replay it from the beginning. Having said that, this sounds very cool in theory. You are probably not rebuilding your production database from scratch. Okay. Replaying all the luck. Okay. I have, I seldomly, I minus very dangerous situations. You're probably not doing that very often. Okay. So there is that. Okay. Kafka has a system for sending messages across. microservices across processes. I don't know. It feels the wrong tool for the job or in other terms, it seems, oh, let's put Kafka everywhere because it's so cool. And be done with it. What do you think? I think the modern engineer suffers of the cool boy syndrome. It's cool to build a system with Kafka clearly because it's a cool toy. But like you said, it's just, I think we need to kind of like go back to basics and explain. I don't think many people really understand what Kafka is to be honest with you. Like we saw it also with a lot of customers, a lot of people. It's a very complicated system. It understands perfectly the concept of distribution, event consistency. A lot of people, they might say, but I can say the state in Redis, right? And continuously mutate through event, that's the status, right? But what about concurrency in the distributed system? You don't have a single node. What about if the step that you design has multiple sub-steps execution, right? I think if I had to pick a combo, I would probably do Cassandra or similar. and Kafka just because you still need to persist somewhere, right? You still need to have a place where this state is end-all, is persisted, mutated, retrieved. So yeah, it's a cool toy, but not enough. It's like going into a kitchen and try to cook with just a knife, right? Might be enough, but you need something else. Okay, but so we have Kafka that basically becomes a glorified choreographer, right? So it's the so-called choreography pattern. So, okay, Kafka is on top and we know that Kafka, there is some sort of like entity, we call it the entity, and like in James Bond. And this entity knows how to unpack basically the concept of transaction and uses Kafka to broker it across different workers that are executing the work. Correct? Some sort of like high level? Yes. But I mean, we spoke about cadence, temporal. So what's the difference between like... The major difference between temporal and building something on top of Kafka of queues is essentially the level of abstractions. Specifically, the SDKs. There is a lot more going on in the SDKs. for Temporal. Temporal allows you to set it up, allows you to write more or less ergonomic code. The developer experience is essentially fixed. was essentially fixed by Temporal for those kind of use cases that you can essentially write your workflows more or less in normal code and Temporal will make sure to make everything work correctly. Well, because it's a client server kind of like model, right? So the code that you write is the client and Temporal is the runtime, right? So yeah, it's slightly different. Okay, so basically... The code is divided between the workflow definition and instead of using, I don't know, in the ESB lingo, a very complex workflow definition in XML or with a DSL, without defining the workflow with a DSL, it defines the workflow with the code in code. You can define your workflow just using typescript or python or whatever you you you want to okay and i could do the same with promises right i could do the same in javascript uh chaining uh promises that's a workflow right When I do a waterfall? No, you can't because the difference between the SDKs, this kind of system as the SDKs is a client server model. And while you write yourself a nice promise and so on and you do a wait, in reality, what happens is that the client talk to the server and restore the calls to the exact moment. So you can essentially pause a workflow for a long time. while everything is being resolved correctly. Okay. Yeah, because you have all the client, the workflow code that basically gets shot to temporal. Temporal understand the concept of what at the time, at the old good time of Nojitsu, you basically run inside of your probes or your Carapachis and then you basically execute so he basically goes and pick up a worker that can do it and associate that code that's that with a worker so he basically does all the the coordination and the complexity of handling you know the chain of state the the routing and so on and so forth yes right yes not that the um the My understanding is that the code runs in your worker. You only pass the definition down to the system, to the broker. Which is very cool, to be honest. I find it extremely... I think it's a very novel way and it solves the developer experience kind of approach. for this. However, those SDKs are a little bit complex to use. You need to know exactly what's happening. You need to know a lot of temporal things to make them work. So it's very, let me say, it's very vendor locking. Yes, it's very vendor locking. Yes. So the ESB was super vendor locked. Super vendor lock. Then you have the queue mechanism that is more kind of like do it yourself. Yes, and that you could use whatever. You can replace whichever queue you wanted and everything will work correctly. And then we have Tempora, which is vendor locking. Yes. Even if it's open source, right? Most of the code is open source. It's open source, but let's see the license. Actually, I have no idea. I have not checked. This is interesting, right? like live checking on things written go not surprisingly and the license is mit okay so they are very fair i can they're not so vendor locking i can just like run it myself probably with a lot of features that are missing and so but but but let's say it's the same model that kind of like we do in a nutshell right okay super cool and then And it's language specific, right? Because every SDK can run multiple run times, but every SDK is... This is something, yeah. Yeah. You need to use the SDK, but you have the Go SDK, the Java SDK, the PHP SDK, the Python SDK, the TypeScript SDK, the .SDK and Ruby SDK. No zig. There is no Zig, Luca. I think I know very few interesting open source processes that are all very cool. But an OCaml, no OCaml support. No OCaml. Well, no Alixir neither, Luca. So that's an interesting question because I was going to ask you another thing, right? What do you think they use behind the scene to execute the sandbox to run the step? Because the step isn't a sandbox, right? No, I think the steps are running down in the process. They're not executed up. So I have this humongous temporal cluster with probably primary, secondary model. They only maintain the state. So they're writing a database? Yeah, I think so. They are a database. That's my understanding. yeah so true i was actually i was going there so for by analogy every workflow becomes a database you know because they write and read state from yes exactly yes so my question is so this one they're all right inside of this process like they spawn processes on machines basically yes okay cool Cool. And so they do also the orchestration of all the processes in the distributed system. Yes, exactly. So they assign, oh, there is this step that is now can be, let's say there is an await step or a step that finished for whatever reason, then it can be resumed, then you can, you can, it restarts the workflow from that specific point and so on and so forth. Cool. So can we simplify saying that basically they adopt a model where they put a developer friendly interface on top of a system that handles kind of like processes in a cluster, basically? Yes. To simplify, right? And then those processes, they do read write operations. They are basically an input output function. We are oversimplifying, but yes. So can I make an oversimplification and analogy that probably will trigger everyone in the universe to kill us? But lambda then absurdly is a workflow primitive, could be a workflow. It's a step. So it's not a workflow, it's a step. It's a step primitive. Sorry, you're right. It's a step primitive. OK, OK. But then, OK, we are talking about Temporal, that is a system that is massively used in back end system for massive scale. Netflix uses Uber, our customer media set is huge, right? It's huge. And now last week, right? Yeah, last week, last week, there was the use workflow. I know because you guys wanted to send me there. I wanted you to go there, but you didn't. But no, I didn't. The use workflow. Was announced at the next JS conference. Ship AI conference. Ship AI. Ship AI. Okay. So now we have use workflow. Okay. So we temporal runs all at runtime. There's no compile time, right? Yeah. It's very dynamic. I can add steps. Yeah. Yeah. Yeah. And how does it work with Vercel? Can you tell us something more? It's actually very interesting. I think it's, by the way, UseWortflow is a very interesting and very well executed idea, experiment. I don't know if it's going to... if it's going to stick, but it's really interesting. Let's talk a little bit. Let's unpack it what it is. At the source, at the high level, top level, it provides a durable workflow engine similar to Tempora. At the very high level. You write JavaScript code. You write TypeScript code. You have your TypeScript code that you write. You write the workflow in TypeScript. You write the steps in TypeScript. Those things are durable. Okay. So essentially the process can crash, restart, and the steps will continue executing. Okay. That is what it is and at the very high level. So you can see it seems it's quacks the same thing, but with a very nicer developer experience. Hold on. Sorry. Just for me to understand. Use workflow. Right? Yes. So, a directive. So, what it does, okay, so you write the workflow file, let's put it, you have to write the workflow files and the steps, okay? In Temporal, you have the workflows and the steps, okay? Conceptually, in that size, it's similar. In Temporal, the client, the way you need to write those two things, okay? It's very explicit, okay? You need to use the SDK, okay? You use their SDK to do those things, okay? Yeah, I was actually reading to have some code in front of me, okay? Yes, okay. So you write the SDKs, okay? You use the SDKs. With UseWorkflow, okay, instead of using the SDKs, you put this magic directive. And it all magically happened at compile time. So the code that you write is very different from the code that is going to be executed. There is a massive delta between the two things. But sorry, just a question. How does he kind of like capture like it's because sorry, just like for dummies. I do use workflow and then I have all my code with the async await kind of like model, right? And at compile times, it basically takes every async await. Yes. Yes. It converts. No, not exactly. It converts the use step. Okay. Instead of returning just the function. It converts it into some sort of durable objects that stores the input and output, the input and the result of that execution in the database. But basically I could build the same, having a function called USTEP that wraps... Okay, sorry, but it's developer experience. The key focus on use workflow of the workflow dev kit is developer experience. Yeah, but that the price of basically being handcuffed with the whole Versailles ecosystem. Let's dig a little bit into that for a second. Because it's very different, the model. And it's compile time, you said, right? This is compile time. All of this is compile time. Then you need to store those things somewhere. Sorry, Teo, why didn't they make it the runtime if they have a used app? Yes, but you... Sorry. I have not finished. This compile time creates this step and workflow abstraction to execute your workflows. Then you have the concept of word. The one where we live, basically. Yeah, that's the thing that actually does everything. That's the runtime. The word. You can have in-memory word, which of course, if the process cache is gone, you can have a Postgres word. you can have a Vercel world, you can have now people have created a AWS world. Basically, in this nice globe, this is the world, the responsibility of that is to store, it's actually providing the durable execution for your workflows. So it's an adapter pattern. It's exactly an adapter pattern. But it's cooler to call it a word. Yes, it's cooler to call. It's cool. It's a cool. It's a cool. It's an interesting idea. OK, I'm just mentioning it's an interesting idea. Now, in... Sorry, I'm reading the code because it's kind of like... I want to stress the difference between something like this and something like temporal. Okay, because I think there is a... So the complexity of those systems, okay, and it's in providing the durability and reliability. So in essence, the complexity of those systems are in the runtime. Okay. What do you mean? Sorry. So it's how do you handle versioning of your workflows? Okay. How do you upgrade your workflows? How do you make your workflows observable? How do you do all those things that are absolutely that are very important for the lifecycle of the workflow itself. OK. And in fact, Temporal is a server plus some SDKs. OK. Use workflow. OK. Does not have that, does not follow that pattern. OK. Use workflow is an SDK, essentially. And then where you inject the word. The world provides the runtime, which provides all the nice enterprise level features. I don't know. I think it's just a bunch of not reinvented year syndrome with a nice UI. Like, sorry, experience. Yeah, it's a DX, developer experience. Yeah, but sorry, just not to make it too... A, you don't really need the compile time to do that because you could do a version of control at runtime. Right? I mean, Java did the same. Come on. In theory, yes. In practice, it will be way more clunky. Okay? Way more clunky in JavaScript to do that. But why? Because I think, I mean, I understand the whole thing, right? But I'm thinking... in dotnet or in Java, I would probably write my step function and put a nice attribute and say, so decorated as a step, right? And then you take advantage of the compile time there. That is a little bit more. Well, it's not compile time, though. Those are interpret can be interpreted at runtime. Correct. Correct. True reflection. But the thing is, I don't really understand. And maybe it's my it's me, I don't really see the compelling advantage of using this. Okay, so there are two bits. So if you, for me, the way I see it, the compelling advantage is Vercel needed a durable execution, a durable workflow execution pattern for their cloud, and they developed it. And for that, it's very... It's essentially the SDK. Yeah, but because behind the scene what they do, they will discriminate by the word, right? Yeah, from some some AI or some some machine learning that will basically recommend you which machine to use. And so they go into the promise of optimizing cost. Exactly. Okay, but okay. But I can build my own world, right? So I can basically write my own world around. Exactly. But then the question at that point is, will it be as reliable as Tempora? No, on that one, I don't have doubts, to be honest. I'm not doubtful on the skills that, you know, Vercel's team put into building that. Yeah, no, but sorry. I'm... You said you can write your own. You said you can write your own. Did you write your own? Like this is what I mean. You write your own. Okay. So far. Like of your own word or your own? Your own word. Your own word. Yeah, I'm just kind of like thinking maybe it's me, right? Like so far there are two built-in words which is embedded file system based which is useless. OK, for production. And there is the Vercel word. There is a community provided built on top of Postgres. So it means that in the world SDK, they have all the different steps for saying save step. It's just an adaptive pattern. So you just load an NPM library that does implement the work. Yeah. And you need to write your own kind of like logic and so on. Yes. My only concern, I mean, I like the developer. I like the idea of the developer experience, right? I think it's pretty compelling, like you were saying. But at the same time, my kind of like problem there is, do we really need to define it as a stat? But like my ideal world is where developers don't have to think about the constant workflow. it's it's inferred in in it's inferred by the runtime. Right. But that's the that's exactly the premise of the workflow. But you need to write the user stuff. Yes. Well, so I need to declare. But why not actually having something that that can I mean, if you already have compile time, why not actually have a normal sync await mechanism and let the user kind of like take every single function and throw it into a durable execution. You can't really because there are serialization boundaries between it and you cannot. You could doing with, I don't know, some JIT, doing some JIT magic, doing some language level, runtime level type of, you know. Or I am serializing the closure. How do I serialize a closure and save in a database and then deserialize that in the future? OK, do I even want that to do that? OK, but I don't, by the way, this is a bad idea. And the reason it's a bad idea is because I want to be able to change the implementation of that function over time. OK, so that, you know, if there is a bug, I can fix the bug. Oh, there is input that I didn't know how to handle. Oh, I'm fixing the bug. OK, but that's but that's I mean, To me, I mean, I'm just thinking, you know, it doesn't it doesn't take much to basically even if do something ugly, evil of the of the text. Yeah. And every time that you reprocess in a deployment of the code, you traverse all the code, the three and apply new deltas to all the functions. So you build a graph. on the function dependency. And then you call eval. I know that is bad. I'm not saying that is good. But absurdly, I think it would be probably easier to build a sandbox function execution. Right. I think because they don't do memory. Do they do memcopy or other stuff? They serialize. All those systems, even temporals, serialize the input and outputs of the workflow, the individual step execution. Okay, but that's easy, right? Because we know that... Yes, it's just a JSON user storage somewhere, yeah. No, but even if I do mem binary, it's fine because I know the size off, right? I don't know. Look, I'm thrilled by the developer experience. I am skeptical on any execution that's not... that's not Vercel based, essentially. They're great engineers, so I presume that their execution on their platform will work very well. But it's... But think about step functions. Think about simple workflow engines. The Java one that everyone uses, I don't remember the name, is a commercial product. There are plenty. Now, I just wanted to throw a last, something that we didn't plan to talk about, that was just published today. I'm passing here, Luca, in the chat. Let me see if I can pass in the chat. I'm passing this in the chat. In the chat. Here we go. I'm passing it in the chat. No, I can't. where is it sorry i'm passing it in the chat it's the it's a post from armin ronacher i don't know if you know armin is um he works at century created um a lot of open source um and he is is probably one of the greatest engineers of of our time okay um He created Flask, I think, or worked a lot in Flask in Python. It's very big in the Python ecosystem. Okay. I saw the article, right? So basically, he created a similar implementation of that system just by using TypeScript and Postgres. Okay. And it's very interesting. It's a very interesting implementation. And that system does not require a compile step. And to be honest, the code looks pretty good. Yeah, what I really like is, I mean, you and I have been talking about an idea that I think we're going to just hack together because it's too interesting not to do it. But I don't think I don't think we should. Well, I'm surprised that in 2025, we are still on the quest of finding of defining even an execution primitive, which is kind of like absurd to me. Like I was expecting that that those things was like an out of the box, an out of the box kind of like functionality, right? Of distributed runtime. So. Maybe what we should do, you know, after you and I design it and we're ready to release it, we should kind of like, I don't say stage it, but almost not to kind of like, but we should have like a banter where we go through a live design that we will already have done of the system and try to basically for our launch. Let's see if we end up building the thing. OK, if we do, let's see how it goes. Yeah, that would be interesting. Well, we chatted for our usual more than three quarter of an hour. It was extremely interesting. If we had no time limit, I think we would talk about it for like six hours. A little bit like Lex Friedman's podcast when he interviews Elon Musk and other people that it takes hours and hours. So, yeah. Till then, let's chat next week. Bye. Bye. Bye.

⚙️ Pipeline jobs

StageStatusAtt.UpdatedError
download done 1/3 2026-07-20 14:58:38
transcribe done 1/3 2026-07-20 14:59:04
summarize done 1/3 2026-07-20 14:59:34
embed done 1/3 2026-07-20 14:59:35

📄 Описание YouTube

Показать
Every Node.js developer has, at some point, built a “distributed system” that turned into a distributed headache. You start with Kafka and a few services, and before long, you’re juggling retries, compensations, and correlation IDs like it’s 3 AM in production.

In this episode of The Node (& More) Banter, Luca Maraschi & Matteo Collina break down the workflow orchestration wars — from traditional message queues to modern “durable execution” frameworks like Temporal and Vercel’s new “use workflow” directive.

We’ll explore:
✅ Why every complex Node.js system eventually reimplements a workflow engine
✅ The pain points of Kafka-style event choreography (and how we got here)
✅ How Temporal brings “workflow as code” to JavaScript
✅ Why Vercel’s “use workflow” might make durability a language-level concept
✅ When to choose Kafka, Temporal, or “use workflow” — and how to mix them

If you’ve ever asked yourself “Why is this microservice talking to that one?”, this episode will help you see how the next generation of workflow tools is making distributed logic finally… durable.