[Weekend Drop] Temporal: React for the Backend

My first public Temporal talk, presented at React New York 2021.

Video: https://youtu.be/Cxaf8E00GMM
Slides: https://docs.google.com/presentation/d/1sJSqNy-t-kVxzrWlqMTp_03nI7Zo8Znr7k0f0C6L9ig/edit?usp=sharing

Timestamps:

[00:00:00] Intro
[00:02:17] Part 1 - Components: Code Organization for Real Apps
[00:04:26] What we learned from React
[00:07:46] Part 2 - Architecture: Choreography vs Orchestration
[00:13:05] Retries and Timeouts
[00:14:37] Part 3 - Time: React vs Temporal
[00:16:34] Elevator Pitch
[00:17:13] Programming Model
[00:18:44] Comparing React and Temporal Principles
[00:19:11] Live Demo: Amazon One Click Button
[00:23:49] Talk Recap
[00:24:16] React and Temporal Full Comparison
[00:24:42] Conclusion: Enablement

Transcript
 
[00:00:00] Once again, I want to thank you all for tuning in and joining, React New York 2021 without further ado, I'll pass it on to Shawn. 

All right, so hi everyone. 

Hello, React new York. It is my home town in the U S and I miss everyone back in New York. I am currently based in Seattle, but I'm here to talk about React for the Backend. In 2020 I actually thought that I had given my last React talk because I was all tapped out. I had said everything I wanted to say, and then React New York came by and said, do you want to speak? 

And I was like, oh, I really wanted to speak for React New York. So here's my presentation about what I've been working on and what I think the parallels have been for React. And I think there's some generalizable lessons, even if you don't end up using Temporal. So, the inspiration for this talk came from Guillermo Rauch, the creator of Next.js. 

And he was the first person to point out that Temporal.io, does to backend and infra what React did to frontend. Temporal engine is quite complex, much like React, but the surface exposed to developers a beautiful render function and I'm a bit upset because he realized there's before me and I have been working on Temporal for a few months now. 

So important caveats before I start this talk. What I'm presenting to you is alpha for TypeScript. Temporal is typically a goal or Java based application, but we're developing TypeScript and hopefully launching it soon. And then finally "React for the backend" is an analogy, not a design goal. 

 The way I treat this is like, it's a, it's basically like crabs. And one of the most entertaining facts that I've ever found is that nature has apparently tried to evolve crabs five independent times. And in fact, there's a word in evolutionary biology for it called Carcinization. And of course, this is really good for a lot of memes. So tired convergent evolution is not uncommon, especially when species have similar selecting pressures in their environments, wired. 

Everything is Crab. And perhaps everything is React, because we have similar design space problems. So I'll tell a little bit of the story through three parts there's Components, and we'll tell it through the story of Uber, talk about architecture, we'll talk through the story of YouTube, and Time will tell you through the story of Amazon. 

So a lot to cover, I'm going to try to go really fast. Don't worry. I'll share the slides on my Twitter later on. Okay.  

[00:02:17] Part 1 - Components: Code Organization for Real Apps 
 
So part one is about components. You see this a lot on YouTube. Probably you're watching now on YouTube or live streaming. And yeah, you know, like three hour live stream and that's it. 

Very cool. I think we, we know how to break things down and React has really helped us be more productive by being able to break things down into the components and knowing how to compose them together in a predictable way. But there's a lot of things unanswered in things like this in, in full stack, clones of major well-known apps, which is the hard parts. 

What like a typical Uber trip, we'll have all these steps like search pricing match. Pick-up drop-off rating tipping, payment, email, uh, and so on and so forth. And typically the naive way of organizing all this is basically one after the other, right? Like this is search goes to pricing, goes to matching, goes to pick upgoes to dropoff goes to rating goes to tipping goes to payment, goes to email, imagine that these are all managed by separate teams and scaled independently. 

Then you realize, like, this is only the happy path. Then you have to throw in a whole bunch of things that can happen along the way. An Uber trip is basically a long running process with humans in the loop and humans are very, very messy by nature. So how would you write an Uber clone? good luck with a lot of data technologies that you would typically reach for just naively, because you will have to discover all these systems and all these use cases and edge cases along the way. 

So when people say full stack, they often really mean like this half drawn horse meme. I think this is particularly funny so I take every opportunity I can get to show it, but to be honest, a lot of us front end developers are probably the other way the half-drawn Dragon where we're frontend a very good and in the backend, we'll just like, you know, stick some stuff on Firebase and something. 

And in reality, if you look at the backend systems, most companies, especially at scale, go towards some form of very complex micro service, system. I don't have the chart for Uber, but Hail-0 is probably a good comparison. Netflix, Twitter, and It's not really avoidable. If you want to scale a company to any significant size, you probably have to break them up into independent services because you're going to ship your org chart anyway. 

[00:04:26] What we learned from React 
 
The thing I realized as a React developer, as a front end developer, is that actually we had a pretty good run in the past seven, eight years of React in terms of the fact that front end developers know how to organize code at least in terms of the component level. So we moved from the jQuery era where everything was just kind of spaghetti all over the place to at least something more organized where event handlers are strongly tied, locally tied with renders, but essentially managed by React's runtime.  

So a few key lessons from React that I personally draw [00:05:00] is that you want to have a component and a renderer model. Like, so essentially the user or the developer writes components. And then the react core team writes the render and that handles a lot of the boilerplate that you might typically forget. 

And this is everything to do with on mounting or having local states. And it gives you a very nice, non-leaky abstraction that you can write. Second, you can also guarantee work and correctness, which is originally what drew Jordan walk to make something like React because he was working on Facebook messenger and there was a lot of inconsistent state within Facebook manager because of the spaghetti code. 

So correctness, meaning that we embrace functional programming to produce a virtual DOM view is a pure function of state. If you look at the old enough React talks, you will see a lot of v = f(d), so view as a pure function of data. And finally the programming model. We like to say that it's just JavaScript. 

There's no custom syntax with templating syntax to learn. I think all these three lessons , there are actually a lot more, but all of these three lessons are where I'm going to focus on for this talk. And I think whenever you tackle any programming paradigm, any framework, any design question, you might want to run it through some of these ideas. 

So whenever I talk about React principles, I always like to bring up the fact that there's this often overlooked repo called react-basic. And it's actually in the official React organization on GitHub. And this is Sebastian Markbage, who is the tech lead of React. And he wrote down six years ago, his principles on what he thinks makes up React on a fundamental basis? No, JSX just like, what are the principles that we're designing for? We are designing for a simple, pure transformation, abstraction, composition, state, memoization. The words that he uses are very theoretical sometimes, but you feel it every single day when you write React. 

So there's a lot of things else apart from that, that reacts has done for front end programming. Apart from deterministic renders, we have useState with a reduction of boiler plate with unmounting, child components in con in the very careful design composition, um, side effects where, you know, we have used effect or use memo. 

And actually a lot of people don't know. I don't, I forget my source. I think it's Sophie Alpert, but, one-third of the React code base is actually just normalization of events across browsers. So you don't even have to worry about it. And creating synthetic events for that. They also produce a dev tool and manage a central scheduler and obviously the success of React over the past five, six years has really shown Testament to how great all these decisions have been. 

 If you want to learn more about the talks that I've done and my perspectives on some of these React principles, I've done three talks. One is at React Rally. The second at JSConf and the third, ,at React Summit. So you can check out my YouTube for more conversations on that. 

I don't have time here. Okay.  

[00:07:46] Part 2 - Architecture: Choreography vs Orchestration 
 
So that was part one where we talked about Components and the React revolution. So part two, we're going to talk about architecture. So a bit, one level higher than just components. And I'm going to motivate this question with a question of how would you write YouTube. And again, if you look on YouTube for how to write YouTube tutorials, you can get full-stack clones of YouTube, which is pretty impressive, you know, write YouTube in three hours using Firebase. That's very impressive. Unfortunately the hard parts of YouTube also come in. And there are a bunch of Googlers actually who actually went and interviewed YouTube engineers on how YouTube works on the backend. There's a bunch of work that goes on in the background. 

So you need to upload your file. You need to analyze for metadata. You need to split it up into chunks. You need to process these chunks in parallel, and then you need to stitch it back. And by the way, processing, you have to produce an array of formats, right? From like, 240 P to like 1400 P or something like that. 

And then you have to stitch all these chunks back into the continuous videos that you actually see in stream. You need to notify subscribers, you need to produce automatic captions and you need to produce thumbnails. And that is again, just the happy path. Right. So, what about all these other features? It's. For example, YouTube premiere is a scheduled release of a YouTube video or feeding into the recommendation algorithm. That must be the most craziest batch job in the world. And you need to scale this process, whatever, whatever you design for 30,000 hours of video uploaded every hour. 

That's the sheer amount of volume that's going on YouTube today, which is just insane. Like, like any design that you make at scale is going to break in some respect. So I think, I think that's, that's really interesting to consider. And I learned about this actually, and I thought more about this because I interviewed one of our users who is Descript (hi! I'm editing this transcript in Descript rn lol). Descript is a audio transcription platform and their entire business is transcribing audio and then making it easy for you to edit audio. I do it for my podcast every single day and millions of people use it. I think it's really cool.  

So their problem was that when a user hits transcribe, it kicks off asynchronous multi-stage and parallelized process that involves reading, encoding audio, chunk splitting. external API calls, merging results that may potentially arrive out of order and then verifying their alignment. 

So there's a lot of [00:10:00] nuance here that can get really tricky. And if any part of the process fails, you need to try it again. So, this is typically the kind of architectures that people build up incrementally over time, as they discover all these use cases and then find holes and patch them because it's too late to rewrite something. 

There's a lot of decisions that goes into here. And this is normal. This is natural. I think you run into basically the eight fallacies of distributed computing, which has actually discussed or discovered back in 1994 by people at Sun Microsystems. I love these cartoons but it can be a little bit hard to read. 

So here's a more organized version of them. At the bare minimum, don't forget distributed computing fallacy number one, which is that the network may or may not be reliable or compute may or may not be reliable. So, what that means in practice is that when you're calling system a, B, C, D E F G you may actually need to introduce hardening layers because at every point and you cross system boundaries, you have a chance of failure and that multiplies exponentially, as you have more and more services tied up in your systems like we saw for the Uber example, like we saw for the YouTube example. You need to add in timeouts and retries. And what that means is that you need to persist the number of times you timed out, when you timed out, what jobs you timed up. 

So you need a database every single time, and then you need a scheduler or a timer to say when the next time is going out, I'm going to try this again. And you need to write this for every service. If the ma the maintainer for every service needs to maintain both the code and the infrastructure for this. This is a lot of how I was talking about things when I was exploring the serverless world. 

So here's a real life example from the AWS blog where they said that you were using dead letter queues to replay messages when such things as failures occur. This is a fine looking example until you try to scale it. And again it looks like a complete mess, complete track, and it's very hard to keep in your head, and pretty soon when you're explaining this to your CTO you look like the Pepe Silvia meme.  

So the solution that I found is really to have a central orchestrator, right? Instead of every single system maintainer writing their own API hardening layer, which is a production requirements, as you find more and more of these bugs, you should centralize it with a centralized team that takes care of the orchestration of all these different services. 

And that's in the business, what we call choreography, which is A to B to C versus orchestration, which is a central orchestrator coordinating the dance between AB and C, and then storing both the infrastructure and the code for the scheduler and the database. So there's a really good article on this by Yan Cui in the burningmonk.com so I highly recommend checking it out where he talks about choreography versus orchestration, with real life examples that people use in AWS, but also it's not specific to any cloud. It's a architecture design pattern, which I think fundamentally, if you start off with this, it's really hard to rearchitect to this. 

I mean, it's, it's possible because people are doing it, but also it's a conscious, architectural choice that you might not know that you're making if you don't know about it. So, I guess a lot of my message here is to tell you that orchestration is a thing.  

[00:13:05] Retries and Timeouts 
 
Also, so you want to declaratively put into your framework retries and timeouts, so for example, this is actually our API. You want to be able to say, all right, here's the default retry policy. Whenever I fire off an activity, an activity is just like an external API call, for example. So when I fire up an activity, I want it to be retried every second. If it fails, I need a backoff coefficient, like exponential backoff. 

This is very similar to the TCP protocol so that if the endpoint is failing or getting rate limited, I don't keep retrying, and then building up a DDoS attack on myself, I actually back off and put more and more intervals in between until some maximum interval, let's say a hundred seconds. 

And then I give myself a maximum attempt, so I can say like, all right. I don't want any retries. I can just say have a maximum attempt of one. Or let's say, I want a linear back off and not an exponential for whatever reason. And I want to try to a maximum of five times - you want to have this all declarative so that you can tweak this as you understand your system and you scale your system. 

Right? So I think this is a really interesting programming model that just puts retries into the code that you write. And that's only possible when you have your centralized orchestrator, no matter what system, not just Temporal.  

Okay. So the case that I'm making is really for choreography versus orchestration. 

And I, the analogy that I make for front end versus the back end is that it's kind of like vanilla or jQuery versus react. React has a react as the central orchestrator, orchestrating all the components. And I think that's a really interesting architectural analogy that you can make and learn from React. 

All right.  

[00:14:37] Part 3 - Time 
 
Part three - Time. I'm doing very good on time. I think better than I thought, which means that we'll have time for a live demo, which is really awesome. So let's talk a little bit about Temporal.  

[00:14:45] What is Temporal? 
 
What is Temporal? Temporal is the open source platform for orchestrating highly reliable mission-critical applications at scale. 

I love talking a little bit about the history, the reason because our CEO started at Amazon as the tech lead for what became Amazon SQS. Our [00:15:00] CTO was at Microsoft and it was the principal architect of the Durable Task Framework, which became a Microsoft's version of Durable Functions, and then finally they joined Uber and worked on Cadence, which is the open-source version of their workflow orchestration platform and Cadence became so popular that they spun out and became Temporal. And since then it's been adopted by a lot of well-known household name companies, especially in the developer world. 

There are a lot of people hiring for Temporal developers, which I really like to see because it's not just being used, but also it's creating jobs for people and it's becoming a desirable skillset. And most recently last week we had Netflix presenting about how they used Temporal for their CI/CD. 

 Temporal has three components or produces three products that are used in sync. The main star is Temporal server, which is comparable to the React runtime that you might see, then there's Devtools, which is the UI that you might want to inspect the state of things. 

And then the SDK is, which is what you use to code. So I think all those are really comparable to what we have in React and having been in the React world for while, like, it's really amazing to see the analogies that we have. We have exactly the same thing. For me, the really sort of the seal of approval comes from Mitchell Hashimoto who, created Hashi Corp, saying that without Temporal, we would have spent a significant amount of time rebuilding Temporal, which actually to me is the best form of validation because Mitchell is one of the best developers in distributed systems and he says it's hard and he says it does it well.  

 All right. Enough social proof you want actual facts? I would just give it straight to you.  

[00:16:34] Elevator Pitch 
 
So because your workloads like the YouTube encoding, or like the Uber journey and this technology was developed at Uber i s long running and it ties together multiple services. You want to standardize timeouts and retries and you want to make it easy for every team to have production grade retries and timeouts.  

Because this work is so important. You must never drop any work. You must log all progress. In other words, you must use event sourcing. 

And then finally, because this work is so complex, you want to use generic programming languages, instead of Domain specific languages. So you want to model a dynamic, asynchronous logic, and then you want to reuse, test, version and migrated it.  

So that's the pitch in one screen. 

But I'll just break it down for what it means, and then we'll go into a demo.  

[00:17:13] Programming Model 
 
So to me, The, the closest analogy to React is the programming model, because React spends a lot of time on API design and in the workflow orchestration world there are a lot of JSON or DAG based domain specific languages. 

So you, you write a bunch of JSON or you do boxes and arrows boxes and arrows boxes and arrows, sometimes you've even write XML, which is very interesting as well. What I find with all these is that they're actually really good for manipulating visually. But they get very tricky when you need to do programming language constructs, like variables, functions, loops, branching statements and all the things that we've invented in programming languages over the past few years. 

So if you use "just JavaScript" or "just programming languages", you have all the tooling available. You can use all the libraries that are available. You can use all the testing and code version, quality controls available. If you write your own, you have to rebuild all this dev tooling from scratch for yourself. 

So that's essentially what this is. Here's an example from one of the big clouds where this is their workflow orchestrator model, where you write Jason and it's really hard. It actually goes off the screen and I couldn't really fit everything on one screen. And with Temporal literal just JavaScript you call an endpoint you use that the result of that end point to call other end points, for example. 

It's a very simple example, but in built here is default retry policies that have been worked out. So both of these handle reliability on rails, it's just, we differ in the programming model and the engineering that it takes to maintain one of these SDKs is I'm learning. It's very, very immense. So it's really interesting. 

[00:18:44] Comparing React and Temporal Principles 
 
So, again, back to the core principles that we talked about early on from React. React d ecided on using a framework, decided on correctness and decided on a programming model, and Temporal, in a very similar way. The developer writes workflows and the Temporal core team writes the orchestrator, which is Temporal server. In terms of correctness, React insists on functional programming, Temporal insists on event sourcing in deterministic workflows and then programming model, you want "just JavaScript" or just programming languages, not any custom DSL syntax.  

[00:19:11] Live Demo: Amazon One Click Button 
 
So the final example that I'm gonna motivate is which is like, I'm, I've been trying to re progressively reduce the complexity of my examples. So we met from Uber, which is like a super long running, a lot of humans in the loop to YouTube, which is not so much humans in the loop. 

You upload it once and then everything else takes over from there.  

Now I just want to build one feature, which is a one-click buy button in React or in front end. It's actually super easy. It's a button. That's the literal simplest thing you can possibly do. You put an onclick handler. You're done. If you want to do a one-click buy, you do a setTimeout, and then say like, okay, if you want to cancel this within some window, with Amazon is 30 minutes, we can cancel it. But if you want to persist it, imagine if some person clicks, closes the browser and then changes their mind, opens the browser again, and it's gone. You're screwed. You don't have any other way to implement one-click [00:20:00] purchases. 

You need to implement timers on the backend to do this. I was watching this old talk from Joel Spolsky where he talks about the engineering for the one-click buy button. And I put it up on my YouTube because this is such an old talk. 

And I was afraid to link to the timestamp, but you can check it out as it's just a three minute video where he tells the story about how Amazon moved from shopping cart to one-click buy I mean they still have a shopping cart but it's that important because in online e-commerce actually even up to today the abandonment rate for shopping carts is 70%. 

So imagine if you implement this one feature, you improve your sales by I don't what's the inverse of 70%, three times. That's really amazing. So I think it's just fascinating and it's not just about Amazon. It's not about one click buy. 

It's about user experience. It's about making things easy and intuitive and that often involves turning synchronous things into asynchronous things and in persisting them so that they persist in the background. So I have a little demo here. I'm going to go really, really fast, but you can check out the code in temporalio/samples-node. 

 There's the specific path this year but it's basically a Next.js demo where I have a Next.js folder here. This is going to be pretty standard for a lot of React developers. Hopefully you're familiar with Next.js, so you can learn it. It's got some pages and an API routes where I have serverless functions that call and send signals to my workflow functions. 

I have also a Temporal folder where I have written my workflows and activities. The activities are just a little logs obviously, cause they don't interact with any backends, but they could. And then the workflow coordinates the states in the background of all of these. 

 So I can show you the code, but essentially I kick off a one-click buy with a purchase and then I set a timer and promise.race with a five second wait. 

So if I receive a cancel signal during that timer then that cancels if not, it goes through and the purchase is confirmed. Obviously I can. And what's fascinating about Temporal is that every single step is persisted in automatically saved. So in other words, I can sleep for 30 days. I can sleep for a year. 

I can sleep for five years and it doesn't matter because it's all persisted and wakes up automatically. So the compute the, this serverless function can be. The worker or a Temporal server itself can go down. You can just bring you back up again and it carries on as though nothing happened because of event sourcing. 

So, I'm gonna, I'm going to go ahead and run this. I think it's uh, demos I'm always stressed out about live demos. Okay. I mean, I did test it before the talk. It's just that whenever I'm streaming, like it adds an extra latency thing and that goes haywire. So, Let's see if I have this demo available. 

All right. So I also want to pull this out, which is the UI layer. These are the my test runs. But I have here at one-click purchase UI, and literally, I, you know, I, I want to implement this without a shopping cart, but I want to be able to cancel within some certain amount of time. 

So if I click buy, uh, it clicks, it handles it's. It sends a workflow. And that workflow starts in starts in the background and it's running, right. It's waiting for the timer to proceed. So I'm going to hit the timer, uh, and you can see that a timer started and time of ended, uh, within that five second window that I specified, obviously I should make it longer if I, if I really wanted to show this along the way. 

Um, so, uh, this, this is, this is as is purchased, um, and we can, uh, and now we've confirmed it. Um, but if I ever want to click buy, and then I can click the. That also fires off a different workflow, uh, where it sees that it receives the cancel signal from me. Uh, so, so I signaled it to cancel. And that's a very useful model as well. 

So this actually shows off a lot of the core principles of Temporal, which is you kick off a workflow, you can set durable timers, you can send it human signals and you can get out data as well with queries. There's a lot of interesting elements behind that, but that's the core demo that I wanted to show off. 

So maybe I'll write a YouTube example and then I'll go on to an Uber example and be a billionaire.  

[00:23:49] Talk Recap 
 
So ultimately I just want it to recap again, what we covered. We covered components, we covered architecture we covered time, and these are all the three elements I wanted to compare reacts and Temporal, and explain a little bit of how we think about doing the hard parts of making clones of very popular projects. 

Why is it so interesting? It's a little bit like the crabs story, you know. Obviously the founders of Temporal are not front end developers. They didn't even know react at all.  

[00:24:16] React and Temporal Full Comparison 
 
But they independently evolved a lot of the same principles and this that's, I haven't even gone into like the full comparison. 

So we talked a little bit about deterministic functions and local state and composition, but we haven't talked about normalization and how that compares dev tools. Testing is also super interesting thing as well as the central runtime. So there's a lot here, which I think. And fascinated by, and I'm obsessed by applying the lessons from React to things that are not React. 

[00:24:42] Conclusion: Enablement

And I think overall, when I asked my CEO, like, what is the core message that we want to deliver is actually about enablements. Like we enable people to do things that they're not formally trained to do because we wrapped it up rapid all in a central runtime or central framework. So, uh, I always loved the Alfred north Whitehead quote that [00:25:00] civilization advances by extending the numberof things that we can do without thinking about it.  

 So for me, my version of it is that B2B software advances by extending the number of jobs we can perform without formal training. And the message overall here is that Temporal lets backend developers or, just general full stack developers do distributed systems right? So that's it.  

I blasted through that. I only took 26 minutes. Really great for me, cause I was worried that it would take 50 and I'm happy to answer any questions you can hit me up on Twitter at Swyx. You can read my long form blog posts about why Temporal and then you can join our mailing list, YouTube or Slack. 

Thank you. 

Alright, thank you very much things. So I think that was a really, really nice. And you did, uh, went through that quite quickly. Uh, when I see the comments, people love the, like the most right there, because I could fail because I could fail. It's always like that. So, uh, yeah. Um, the nice thank you for the presentation. 

With this talk, I think it's actually the last talk of the event and I want to thanks everyone for joining us and thanks to everyone, thanks to all the speakers, of course, for being part of this event, uh, React New York 2021 and the sponsors. Um, I think this would be a good afternoon, I guess, or good night, depending on where we are in the world. Right. Have a good one. Everyone. 
2021 Swyx