How not(!) to Build Real-time Apps

Rate this content
Bookmark

Are you building a chat app, a way to see users’ online status or a real-time collaboration dashboard? 

All of these use cases have one thing in common: Somehow the user-facing application needs to be informed in real-time about events that happen on the backend of your application.

In this talk, we’ll look closely at common approaches like polling, application-level updates and pub-sub systems. We’ll explain the tradeoffs with each approach and elaborate why another approach, called Change Data Capture (CDC), is the most elegant and robust way to achieve this.

This talk has been presented at Node Congress 2024, check out the latest edition of this JavaScript Conference.

FAQ

The speaker of the talk is Nikolas Berg, a developer advocate at Prisma.

The main focus of the talk is on how to implement real-time updates between the API server and the database in real-time applications.

The three approaches discussed are: application-level updates, polling, and adding extra infrastructure.

Pros: Fairly easy to understand, no extra infrastructure needed. Cons: Doesn't scale horizontally, suffers from the dual write problem.

Pros: Fairly easy to understand, easy to implement, no dual write problem. Cons: Resource intensive, complex application logic for diffing, not suitable for high traffic.

Messaging systems like Kafka help ensure scalability by handling the distribution of messages between the API server and clients, solving the horizontal scalability issue but not the dual write problem.

Change data capture (CDC) is a design pattern based on unidirectional data flow, where updates are propagated directly by the database to the messaging system, solving the dual write problem.

Prisma Pulse offers an implementation of change data capture (CDC) using Cloudflare workers, reading the write-ahead log from a Postgres database, and delivering type-safe database changes into your application.

The dual write problem occurs when the API server needs to perform two actions: storing data in the database and broadcasting a message. If one of these actions fails, it leads to inconsistent data states.

Polling is not considered optimal because it is resource intensive, especially with high traffic, and involves complex application logic for comparing database states, making it inefficient for real-time updates.

Nikolas Burk
Nikolas Burk
10 min
04 Apr, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Today's Talk discusses different approaches for implementing real-time updates in server-side applications, including application-level updates and polling. The drawbacks of polling include inefficiency and complexity at scale. Adding extra infrastructure, like messaging systems, can ensure scalability but introduces operational overhead. Prisma Pulse is a system that simplifies change data capture, providing an easy setup for subscribing to database changes and solving scalability issues.

1. Real-time Application Architectures

Short description:

Hello everyone! Today, I'll discuss different approaches for implementing real-time updates on the server side of a real-time application. The first approach is application-level updates, where the application server handles everything. However, this approach doesn't scale horizontally and suffers from the dual write problem. Another approach is polling, where the API server periodically asks for updates from the database. This approach is resource-intensive due to the high number of queries. Let's explore these approaches in detail.

Hello, and welcome everybody to my talk today about how not to build real-time applications. My name is Nikolas Berg. I work as a developer advocate at Prisma, where we're all about developer experience for developers that are working with databases. I'll take you on a journey today where, first, we're going to set the stage about architecting a real-time application. And then I want to talk about three different approaches for how you can implement real-time updates on the server side and their trade-offs. And then we'll walk away with a couple of conclusions.

So let's jump right in and assume that you're in a job interview and this is your interviewer. And this is the question that he asks you. How would you architect a real-time chat application? Well, if you're like me, you'll probably start talking about this three-tier architecture diagram and that on the front end, you'll use WebSockets to create permanent connections between your API clients, between the browser and the IPI servers. But my talk today really is about the second part, about the connection between API server and database and how to implement real-time updates there. So how does the API server even learn about anything that's changing in the database? That's the big question for today. And I want to talk about three different approaches. The first one I call application-level updates, then I want to talk about polling and then adding extra infrastructure. So with application-level updates, you really let the application server handle everything. And let's quickly understand how it works with a simple scenario here.

So let's assume we have this chat application, we have three users that are connected to the API server, Alice, Bob and Jane, and they have these WebSocket connections to the API server. So now, first, let's assume that Alice is sending a message to the API server, the API server stores that message in the database, and next, the API server is responsible for broadcasting that message to Bob and Jane. So what could go wrong in that scenario? Once we start seeing a little bit more traffic and we'll want to scale our application and our API servers horizontally, we'll have the problem that Alice and Bob could be connected to the first API server and Jane would be connected to the second API server instance. Because these WebSocket connections are permanent, Jane now will not receive the update from the API server when Alice sends a message. So this approach doesn't scale horizontally. We also have the problem of the so-called dual write problem because the API server needs to do two things. It needs to store the data in the database and it needs to broadcast the message to all the connected clients. What if one of these operations fails? So this is a pretty tricky situation that I'll come back to in a little bit. Now let's review quickly the pros and cons of this application level updates approach. So the pros are that it's fairly easy to understand, you don't need any extra infrastructure, but the problem is that it's not possible to scale this horizontally and you also suffer from the dual write problem here. So let's take a look at another approach and that's polling. With this approach, we just let the API server periodically ask for updates from the database by sending the same database query to the database over and over again. What could go wrong with this approach? So the problem here is that it's pretty resource intensive. Assume we have N users and per user, we have M polling queries. So this becomes very resource intensive with N times M queries for every polling interval.

2. Real-time Update Approaches: Polling

Short description:

Polling is an inefficient approach to real-time updates as it wastes resources and becomes complex to manage at scale. Engineers should strive for elegant solutions that address the challenges posed by the business domain.

If you're polling every couple of milliseconds, that's very bad because then you are wasting a lot of resources, a lot of database connections on the database side, but also on the API server side. So it's very expensive and it's not really a good approach to this problem.

Let's review the pros and cons. It's still fairly easy to understand. So if you don't have that much traffic, you don't need any extra infrastructure, it's fairly easy to implement and you don't have the dual write problem, which actually is a pretty good benefit. However, the cons are that it's pretty resource intensive once you're scaling up to multiple users and the application logic for diffing also gets complex really fast because every time when the results of a database query arrive, you need to compare that with the current state of what has been stored in the database before. And that also gets really complicated. And quite honestly, I think fundamentally polling isn't the right tool for the job when we're talking about real time updates. I think as engineers, we should have the ambition to find elegant solutions to the problems that the business domain that we're operating in poses to us. And I don't really think that polling qualifies here.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Rethinking Bundling Strategies
React Day Berlin 2023React Day Berlin 2023
32 min
Rethinking Bundling Strategies
Watch video: Rethinking Bundling Strategies
The talk discusses rethinking bundling strategies, focusing on challenges such as long-term caching and improving the state of Next.js and Webpack. It explores handling immutable caching and content hashes, optimizing asset references and page manifests, and addressing issues with client-side navigation and long-term caching. The talk also covers tree shaking and optimization, optimizing module fragments and code placement, and the usage and relationship of TurboPack with Webpack. Additionally, it touches on customizing configuration and hash risks, barrel imports and code splitting, and entry points and chunking heuristics.
Domain Driven Design with Vue Applications
Vue.js London 2023Vue.js London 2023
14 min
Domain Driven Design with Vue Applications
Top Content
Welcome to this talk on domain-driven design in Vue.js application. Today we are going to look into domain-driven design, its benefits and how it works with Vue.js domain-driven design versus the MVVM model. Vue.js thrives in domain-driven design, a design approach that models software to match a domain. DDD emphasizes understanding business logic and creating a domain that reflects the language and concepts. Integrating DDD in Vue.js offers benefits such as effective modeling of complex business domains, structured code reflecting domain logic, and easier onboarding and ownership.
How to Share Code between React Web App and React Native Mobile App in Monorepo
React Summit 2022React Summit 2022
7 min
How to Share Code between React Web App and React Native Mobile App in Monorepo
This presentation focuses on sharing code between React web and React native mobile apps. The speaker demonstrates how to achieve feature parity using a Monorepo with NX. They highlight the importance of sharing non-UI code, such as business logic and state management, through shared libraries. This approach allows the apps to focus on UI code while keeping non-UI code separate. For more details, refer to the speaker's blog post.
Data Loaders - Elevating Data Fetching in Vue
Vue.js Live 2024Vue.js Live 2024
30 min
Data Loaders - Elevating Data Fetching in Vue
Data loaders provide a solution for complex and repetitive data fetching in Vue.js applications. Using data loaders allows for more independent data fetching and integrates with the navigation cycle. The data loader plug-in adds a navigation guard for data fetching and loading. Lazy loading and caching can be implemented using Pina Colada and Glada loaders. These loaders can improve the performance and speed of data fetching in applications.
The Next Wave of Web Frameworks is BYOJS
JSNation 2022JSNation 2022
23 min
The Next Wave of Web Frameworks is BYOJS
The next wave of web frameworks is BYOJS, covering the history and evolution of building web applications. The evolution of web frameworks and build systems includes popular choices like React, Angular, and Vue, as well as advanced build systems like Webpack and Rollup. The rise of performance measurement tools and the adoption of the Jamstack have led to improved web performance. The Jamstack architecture focuses on pre-rendering pages, decoupling APIs and services, and enhancing pages with JavaScript. Astro, a static site generator with SSR support, promotes the islands architecture and partial hydration.
Building Figma’s Widget Code Generator
React Advanced 2022React Advanced 2022
19 min
Building Figma’s Widget Code Generator
This Talk introduces Figma's Widget Code Generator and demonstrates how to build a FigJam widget using it. The speaker discusses the implementation of voting functionality, avatar functionality, and remove vote functionality. They also explain how the Widget Code Generator plugin works and how to access properties and modify names using the Figma plugin API.

Workshops on related topic

Web Accessibility in JavaScript Apps
React Summit 2022React Summit 2022
161 min
Web Accessibility in JavaScript Apps
Workshop
Sandrina Pereira
Sandrina Pereira
Often we see JavaScript damaging the accessibility of a website. In this workshop, you’ll learn how to avoid common mistakes and how to use JS in your favor to actually enhance the accessibility of your web apps!
In this workshop we’ll explore multiple real-world examples with accessibility no-nos, and you'll learn how to make them work for people using a mouse or a keyboard. You’ll also learn how screen readers are used, and I'll show you that there's no reason to be afraid of using one!
Join me and let me show you how accessibility doesn't limit your solutions or skills. On the contrary, it will make them more inclusive!
By the end, you will:- Understand WCAG principles and how they're organized- Know common cases where JavaScript is essential to accessibility- Create inclusive links, buttons and toggleble elements- Use live regions for errors and loading states- Integrate accessibility into your team workflow right away- Realize that creating accessible websites isn’t as hard as it sounds ;)
Build a Universal Reactive Data Library with Starbeam
JSNation 2023JSNation 2023
66 min
Build a Universal Reactive Data Library with Starbeam
WorkshopFree
Yehuda Katz
Yehuda Katz
This session will focus on Starbeam's universal building blocks. We'll use Starbeam to build a data library that works in multiple frameworks.We'll write a library that caches and updates data, and supports relationships, sorting and filtering.Rather than fetching data directly, it will work with asynchronously fetched data, including data fetched after initial render. Data fetched and updated through web sockets will also work well.All of these features will be reactive, of course.Imagine you filter your data by its title, and then you update the title of a record to match the filter: any output relying on the filtered data will update to reflect the updated filter.In 90 minutes, you'll build an awesome reactive data library and learn a powerful new tool for building reactive systems. The best part: the library works in any framework, even though you don't think about (or depend on) any framework when you built it.
Table of contents- Storing a Fetched Record in a Cell- Storing multiple records in a reactive Map- Reactive iteration is normal iteration- Reactive filtering is normal filtering- Fetching more records and updating the Map- Reactive sorting is normal sorting (is this getting a bit repetitive?)- Modelling cache invalidation as data- Bonus: reactive relationships
Build Web3 apps with React
React Summit 2022React Summit 2022
51 min
Build Web3 apps with React
WorkshopFree
Shain Dholakiya
Shain Dholakiya
The workshop is designed to help Web2 developers start building for Web3 using the Hyperverse. The Hyperverse is an open marketplace of community-built, audited, easy to discover smart modules. Our goal - to make it easy for React developers to build Web3 apps without writing a single line of smart contract code. Think “npm for smart contracts.”
Learn more about the Hyperverse here.
We will go over all the blockchain/crypto basics you need to know to start building on the Hyperverse, so you do not need to have any previous knowledge about the Web3 space. You just need to have React experience.
Build React-like apps for internal tooling 10x faster with Retool
JSNation Live 2021JSNation Live 2021
86 min
Build React-like apps for internal tooling 10x faster with Retool
Workshop
Chris Smith
Chris Smith
Most businesses have to build custom software and bespoke interfaces to their data in order to power internal processes like user trial extensions, refunds, inventory management, user administration, etc. These applications have unique requirements and often, solving the problem quickly is more important than appearance. Retool makes it easy for js developers to rapidly build React-like apps for internal tools using prebuilt API and database interfaces as well as reusable UI components. In this workshop, we’ll walk through how some of the fastest growing businesses are doing internal tooling and build out some simple apps to explain how Retool works off of your existing JavaScript and ReactJS knowledge to enable rapid tool building.
Prerequisites:A free Retool.com trial accountSome minimal JavaScript and SQL/NoSQL database experience
Retool useful link: https://docs.retool.com/docs