In short
Podcast Summary: Node.js in 2026 with Rafael Gonzaga
Podcast Details
- Podcast Title: Software Engineering Daily
- Episode Title: Node.js in 2026 with Rafael Gonzaga
- Episode Description: Discussion on the advancements and challenges surrounding Node.js, JavaScript's evolution beyond the browser, and the engineering challenges of maintaining Node.js as a critical runtime for backend systems.
Key Contributors
- Rafael Gonzaga - Principal Open Source Engineer at NodeSource, member of the Node.js Technical Steering Committee.
- Josh Goldberg - Host, independent open-source developer, and author.
---
Overview JavaScript has expanded significantly in the realms of backend systems, APIs, and cloud services via Node.js. The episode explores the intricate engineering challenges associated with maintaining Node.js's performance, security, and stability.
Key Topics Discussed
Rafael's Background
- Rafael started coding in his teens, motivated by the need to assist his blind father with technology.
- He transitioned from languages like Python to low-level programming in C and C++.
- Initial experiences with Node.js began in a hackathon, leading to deeper contributions in the Node.js ecosystem.
Node.js Contributions and Technical Steering Committee (TSC)
- Rafael's journey from a contributor to the TSC involved working on various Node.js core issues, including performance enhancements and addressing memory leaks.
- He emphasizes that being part of the TSC involves guiding technical discussions without holding more power than other contributors.
Node.js Performance
- Performance improvements in Node.js are largely driven by advancements in the V8 engine and migration of APIs from JavaScript to C++.
- Benchmarking challenges arise due to the complexity of JavaScript and the need for extensive testing to validate performance metrics.
- Recent initiatives focus on optimizing core HTTP modules and addressing issues with performance regressions.
Performance Optimization Experiences
- Rafael shares examples of performance optimizations that did not yield expected results due to the nuances of the V8 engine and microbenchmarking challenges.
- He emphasizes the importance of establishing baselines for performance metrics before making optimizations.
Tips for Developers
- Developers should choose efficient libraries and frameworks, such as Fastify over Express, for better performance.
- Monitoring tools and logging practices can significantly impact the performance of Node.js applications.
- The importance of using connection pooling for database interactions and minimizing synchronous blocking in code is highlighted.
Future of Node.js
- Node.js is shifting focus towards community feedback and integrating features that support modern development needs.
- The introduction of a permission model and potential future optimizations for HTTP handling are discussed.
Conclusion Rafael Gonzaga’s insights illustrate the significant engineering efforts behind Node.js and the importance of performance optimization in modern back-end development. The conversation emphasizes community engagement, open-source contributions, and the need for continual improvement in response to evolving technology landscapes.
Additional Resources
- Follow Rafael Gonzaga: Available on X (formerly Twitter) and various open-source mentoring channels.
- Node.js Performance Reports: Rafael's blog series, "The State of Node.js Performance," offers detailed analyses of performance metrics across Node.js versions.
---
Key Takeaways
- Node.js's evolution reflects a balance between maintaining stability and incorporating modern features.
- Community contributions are vital for Node.js's ongoing development and optimization.
- Performance in backend systems can greatly benefit from choosing the right frameworks and optimizing existing code practices.
Written by AI. May contain mistakes. Listen to the episode to check what was said.
Transcript
Automatic transcript. May contain errors.0:00JavaScript has grown far beyond the browser. It now powers millions of back-end systems, APIs, and cloud services through Node.js, which is one of the most widely deployed runtimes on the planet. Keeping such a critical piece of infrastructure fast, secure, and stable is a massive engineering challenge, and the work behind it is often invisible. Rafael Gonzaga is a principal open-source engineer at NodeSource and a member of the Node.js Technical Steering Committee. He spent years digging into the performance and security layers of Node's core, helping shape the direction of the runtime itself.
0:38Raphael joins the show to talk about the state of Node.js performance, how benchmarking really works, the balance between speed and stability, and what it means to contribute to one of the world's most important open-source projects. This episode is hosted by Josh Goldberg, an independent full-time open-source developer. Josh works on projects in the TypeScript ecosystem, most notably TypeScript ESLint, a powerful static analysis toolset for JavaScript and TypeScript. He is also the author of the O 'Reilly Learning TypeScript book, a Microsoft MVP for developer technologies, and a co-founder of SquiggleConf, a conference for excellent web developer tooling.
1:21Find Josh on BlueSky, Fostadon, and.com as Joshua K. Goldberg.
1:39with me today is Rafael Gonzaga, Principal Open Source Engineer at NodeSource. Rafael, welcome to Software Engineering Daily. Hello. Thank you. I'm happy to be here. Well, we're excited to have you. You do a lot of great stuff with Node.js and performance and userland libraries. But before we get into all that, how did you get into coding? Well, it started since I was a teenager. I always been in computers since I was young. I played a lot of games, but my father is blind. And back in the time, he couldn't make a few things on the computer because of the disability. And then I started creating a visual or kind of talkback.
2:18I tried to do that at least. And then my journey in the computer science started. I tried to make it happen with Python, Python 2 back in the time. I don't remember. I couldn't make it work, but then I learned, okay, this is how I could make a calculator. This is how I could make things to work. So I started there, but until now I couldn't make it. But there are plenty of good apps nowadays that he uses, and I'm still helping with some plugins and things like that. So do you have experience then with accessibility technology and writing things for folks who are, for example, blind? To be honest, my focus is on backend.
2:58So accessibility on web browsers is not my thing. But I know exactly the problem that it causes because very often my father calls me. OK, Facebook is not working anymore. They changed something. Can you help me? And then I need to write a Chrome extension that will replace the element to the old way that he's used to get and make that happen. But on frontend, I'm not that person. But you do work in an area that sometimes folks erroneously call frontend. So I think we should take a moment here to recognize that JavaScript is not a purely frontend technology. It's very possible to spend much of your career in, say, Node.js and JavaScript and be entirely backend.
3:41What do you think of the areas that your code has touched or the stuff that people use your areas for? Well, I always loved low-level programming. So I started with Python, but then I suddenly jumped to C and C++. I learned most of the things outside of university. By the way, I haven't completed my degree, so I don't have a degree nowadays. And then during the process, I learned many, many languages. I came from Elixir, Erlang, I went to PHP, C Sharp. but I still learned I have still working on personal projects with C++ and C. And then I found that, okay, there's JavaScript. People use JavaScript on Frontend, but I don't like Frontend too much.
4:23Then I saw, okay, people were running JavaScript in backend. I tried, okay, let's see how it works. And my first attempt with Node.js was in a hackathon a long, long time ago. And then I could make an HTTP server. And then I saw, okay, that's nice. Let me see how it was created. And then I saw the GitHub repository and then, okay, they use C++, so I could help in that part. Then I started looking to it, but I didn't make the contribution back in the time. But yeah. So how did you go from starting to look at Node to becoming a member of the Node Technical Steering Committee? Okay. I have started on Fastify, an HTTP framework.
5:03When I was working as a soft engineer in a company that was about to switch other PHP projects to Node.js, they were looking to a microservice approach. And then I was responsible to make that migration. So I was investigating, OK, we are about to use Node.js, but let me make some tests to see how well scale this new platform. Then I saw some HTTP frameworks like Express, and a lot of people were advocating about Express, and all the resources you find in the internet, they use Express. But I made some benchmarks, and Express was not fast as I thought it could be. And then I was looking, okay, let me see if there are other HTTP frameworks, because Express is not official from the Node.js team, right?
5:53It's a library, as well as Fastify. And then I tried Fastify and I saw the benchmarks page from that. And I saw, okay, this is nice. The results is exactly what I was expecting. But I found a bug during the process and I decided, okay, let me create that request. That shouldn't be a GIF code. I wrote the request. It was accepted. And then I saw, okay, the community was very welcome. And I decided to keep contributing to Fastify. Then I met Matteo, Matteo Colina, one of the Fastify creators during the process that told me, do you want to apply to a position at Neoform? I said, yes. I made the test, which is very curious because something got wrong in the process.
6:42And then I did the test for a senior front-end engineer and I passed, but I haven't worked as a front-end engineer at all, but I passed anyway. Then after passing, I got migrated to Mateo's team. And then I got some tickets to work on Node.js core. And one of my first requests to Node.js was fixing a memory leak on a Windows 2012 server, 32 bits. And I spent, I don't know, two weeks or three weeks working on that. And it was very hard because I had to SSH into a machine which was far away from me. And I was testing, debugging memory lakes, and I could fix that bug. After that, I learned a lot about Node.js Core.
7:30And then I started doing a lot of stuff. And I got nominated to Node.js Core. And then almost three years ago, I got nominated to Node.js TSC. What does it mean for someone to be on the TSC for Node? It's very important to be part or to have a voice in technical discussions. But to be honest, if you are a Node.js collaborator or if you are outside of Node.js team, you can still advocate, you can still share your opinion. It's more about being more proactive on helping new members or discussing new features and having more context about Node.js in general. So if someone attempts to include, okay, let's reshape Node.js.
8:19So let's remove C++ and move that to Rust. Normally, the TST team are the set of people that will say if that's possible or not. And also in case of discussions, they have a vote if we should do it or not. So it's important, but it shouldn't be something that should guide people to get that role, to be honest. It's more about having a voice. I think voice is not the correct term here, because technically the TSE was created just to guide the project, but we shouldn't have more power than any other contributor. That's what I'm trying to say. A TSE member shouldn't be anything different from an OJS core collaborator.
9:04Anything that a core collaborator does, a TSE can do, and vice versa. So I don't know if I could explain that well, But yeah, that's the idea. It's kind of amorphous being a technical steering committee member on a project that doesn't have one single tracking company or one single charter. But your area has typically been performance. And you've written quite a lot about Node performance. How do you see that evolving these days? Currently, I work on Node.js security and performance. Performance, I normally do it because all my studies, my research are in performance. However, I've been paid to work full-time on Node.js to focus on security.
9:45So I have these two fields. For performance, I have been monitoring Node.js performance for quite a while. I have a lot of projects around that. And recently, I'm leading the performance initiative of Node.js. However, due to a restricted bandwidth, I don't have much time to work on that because I'm not paid full-time on performance, but in security. I normally write some reports like the state of Node.js performance, and the Node.js have been evolving a lot, mostly due to V8 improvements. So V8 is doing a very good job in JavaScript. So some performance improvement came from V8 per se, and some of them is because Node.js is migrating most of its API from JavaScript to C++.
10:32In the past, we had a lot of discussions if we should write APIs in C++ or JavaScript. And the reason that some of them were writing in JavaScript is because it's way easier to get contributors for JavaScript than C++. So, okay, some API, let's write it in JavaScript because it's easy to get maintenance. But then we saw, okay, for these specific APIs, JavaScript will be a bottleneck. So let's move that to the C++ part of Node.js. Then we moved and then we saw, okay, we got a significant performance improvement. And if you compare the Node.js startup, for instance, we got a significant improvement and that applies to Lambda providers.
11:18If you are using Lambda on AWS or VeriCell, even CloudFare workers, you see that it's very important for them to have a very fast cold start. But I would say that those new runtimes like Ban and Dino, they have moved Node.js to get a different point of view in terms of performance. We were more stable in the past, not releasing many features and being more assertive. But now we have switched a bit our focus to hear more about the community. If community wants some modules like SQLite, let's do that. It doesn't need to be so sacrificing for maintainers. So we have that. And we have a more strict focus on performance.
12:02So we are actively monitoring benchmarks, micro benchmarks of Node.js. And to be honest, it's very hard to write benchmarks in JavaScript in general because of V8. V8 can be very tricky. Most of the times is smarter than you. And if you are writing a micro benchmark, possibly you are looking to the wrong metric. So it's very hard to make some comparisons because some API might be fast on your machine or in your workload. And with a different workload or running that for more time, it will cause more de-optimizations, optimizations or garbage collectors, and then you see a different performance.
12:39But yeah, I would say that Node.js is way faster than two years ago. I want to walk through a couple of scenarios with you just to help flesh out what you're saying. Do you recall a performance optimization you attempted at Node that did not work out after running all those optimizations and benchmarks? Yes, there are plenty of them, to be honest. At Node, there is a working group called Node.js Performance, which stores most of the issues that people find about regressions in Node.js in general. Some of them we were investigating, I believe it was from Node.js 18 to Node.js 20 or a specific version of Node.js 20, which MacLav compiler inside V8 was introduced and enabled by default.
13:27After that, we have received some issues saying, okay, my microbenchmark is telling me that my code is 50 % slower than in a previous version of Node.js. Then we came up to investigate. And the reason is that Maglev was, if you run that piece of microbenchmark for a short period of time, Maglev was being introduced. And this was causing some slow operations. But it turns out that if you run that with a production workload and running with a reasonable amount of time, McLev was being called, but then it was moved to the TurboFun, which is the optimized bytecode of V8. And then the result or the performance of the code was similar.
14:14So for short scripts, that might be a performance bottleneck, but for long-life ATP servers, the performance was the same. So it's very tricky to measure micro benchmarks in JavaScript because you might be measuring a no operation because V8 optimizes your code away. You might be measuring a non-production or an unrealistic workload because you will never run that function many times as you are measuring. And some of them, for instance, in a specific version of V8, if you were converting a string to an integer using parseInt in comparison to a plussino, the plussino was, I don't know, 10 times faster than parseInt in some V8 versions.
15:02I have shared that on Twitter. I have a repository that monitors all those micro operations. And I have also wrote about that. And it was fixed by V8. And it turns out that most of the cases, if you attempt to switch all parsing into plus sino, it will only give you 0.0005 milliseconds of performance improvement. So most of the time, it doesn't worth the change. So it's tricky. Capital One's tech team isn't just talking about multi-agentic AI. They already deployed one. It's called Chat Concierge and is simplifying car shopping. Using self-reflection and layered reasoning with live API checks.
15:46It doesn't just help buyers find a car they love. It helps schedule a test drive, get pre-approved for financing, and estimate trade-in value. Advanced, intuitive, and deployed. That's how they stack. That's technology at Capital One. One of the open source projects I work on, someone spent, I think it was about 2 ,500 words trying to explain to us why we needed to switch from one library to another. that would save about, don't quote me on this, about 104 bytes of Node module size and about a fraction of a hundredth of a hundredth of a hundredth of a second of runtime improvement at the beginning.
16:17But at the same time, as I'm sure you're going to say within the next 10 minutes, sometimes these optimizations really do result in user-in-line improvements, where something that's a fraction of a second faster compounded over time really is better. So how do we know when we're looking at, say, optimizations in Node or in user-in-line libraries, when is it worth it to make that performance investment? Okay. It's very important to have baseline. So if you're trying to optimize your code, you need to have a benchmark. So if you have most of people that use Node.js, they use as an HTTP server. So measure how your routes are responding or how they are performing.
16:57If you are getting, I don't know, 10 ,000 requests per second, if you are getting 100 ,000 requests per second, measure CPU utilization, measure memory during workload, during a benchmark tool. When a benchmark tool runs, like WRK2 or AutoCannon or Apache benchmark, it doesn't really matter. Actually, it matters, and I can explain a bit more later. But create a baseline. This is the state of art of my HTTP server. Then you start measuring. You can't optimize things without measuring things first. Otherwise, you fall into a trick role where you are spending a significant amount of time to get just a small milliseconds of improvement, as you said.
17:39But there are a lot of improvements you can do, mainly when you are comparing some HTTP frameworks. Like most of you use Express because Express is spread everywhere. but what most of you don't know is that if you switch from express to fastify you get a lot of performance i'm not saying that because i'm part of the fast fighting i'm also part of the express performance team and what i can say that fastify in the last versions it's way faster than in the i don't know a year ago so always measure fastify is still as far as i know the fastest framework in terms of stability and performance out there for Node.js.
18:25And more importantly, make sure that everything that you write to the logs, for instance, logs is a huge problem. A lot of people lose a lot of performance by just choosing the wrong log library. People are using console.log, which is a huge problem. If you're doing that, please stop. People are using, for instance, Winston. done, I wrote an article called The Cost of Logging, I believe in 2022, and it is still very popular and still applicable. As far as I know, the fastest logging library out there is Pinot.js. The reason for that is that Pinot was writing in a way that it can create a QE of messages and will not block the event loop when writing to the terminal.
19:15I wrote in depth about that in that article, so I suggest people to check that. It's very easy to find. And Pinot.js also uses Sonic Boom as a dependency, which is very important to make Pinot.js fast. So by choosing the right HTTP framework and the right logging library, I'm pretty sure your app will be way fast than nowadays. One of the advantages, as I understand it, of writing things in user land, like for example, first Express and then Fastify, is that allows users to iterate an experiment. But at the end of the day, some of the things you've alluded to, such as console.log being slow, are part of Node core and therefore the default that a lot of people go with.
19:55What would it take for Node itself to have an equivalent to an Express or Fastify or PNOT.js in core? Okay. The PNOT.js in core is to, we are discussing that, to be honest. So that might happen. Yes, a lot of people ask me why simply Node.js folks can rewrite the HTTP module to make it similar to Fastify and Fast as Fastify. And the reason for that is first one is maintenance. So Fastify, they have a huge thing maintaining that. And for Node.js, if you move things to Node.js, it's expected that you get less contributors working on a specific module because it's way hard to understand Node.js source code and fastify.
20:38The second one is that we can't break the world. Node.js is used by tons of devices and even releasing things as major, server major, which is expecting to break, we can't touch very hard on NTP modules because this will migrate people away from Node.js. If you look to the recent Node.js downloads dashboard, you see that a lot of people are stuck on Node.js 12 just because of breaking change. They don't know how to migrate. It's very hard for them to migrate. And those breaking changes are very crucial for them to stick on an end-of-life version. And this is a problem because when you stay in an end-of-life version of Node.js, you are not safe.
21:27There are plenty of vulnerabilities that affect you. And I also wrote a talk, I have delivered a talk called Five Ways You Could Have a Hacked Node.js, where I exposed some vulnerabilities that Node.js have fixed. And if you are using an outdated version of Node.js, possibly this will happen to you. And that's it. I mean, we can make some improvements to HTTP module, but we can't change it too much. How it was designed is crucial and its legacy. First, it's very hard to change. And second, changing that means that you are prone to break a lot of people. So you have two conflicting desires and needs here.
22:08One is you want to keep things stable because breaking changes hurt the community's ability to migrate, but you also want to have modern APIs and improvements. So how do you strike that balance? How do you know what's of valid or correct breaking change to make? Most of the features, they are behind flags, behind enabling flags. For instance, we brought the permission model. Permission model is a feature where when you enable that, the Node.js will restrict access to file system, to network, to V8, to V8 inspector protocol, child process worker threads. So all of these will be restricted whenever you pass dash dash permission when you use Node.js.
22:47This is a secure measure. And people ask me, why not enable that by default? The reason is that, first, it will break all the scripts out there, so people will never be able to migrate. People do not read changelogs. They just don't want to read that, or for some of them, it's hard. Some of them use Node.js behind the scenes. So, for instance, if you are using Next.js, you are using Node.js behind the scenes, And in some situations, you don't have the Node.js command out there. It's behind next run or something like that. So this will break frameworks and frameworks will need to upgrade. And then users will need to upgrade their frameworks versions to fix that.
23:31So it creates a kind of chain of breakage that will reach out to the end users. And this will be very difficult for them to migrate. So frameworks will be mad with us. Users will be mad with us. And most of the cases, if we enable the permission model by the full, a lot of people will just pass disabled permission because they don't care about that. So we decide, okay, if people, they care about performance, they will opt in. It would be much easier if we were writing Node.js from scratch. So let's say that we are releasing Node.js 2.0. Possibly those features will be enabled by the full because we will teach people this is how this Node.js was designed.
24:13If you want to use Node.js, that's how you go. But since Node.js is still the same, people are just using NVM to upgrade and they don't expect this new design, this new structure. They don't want to learn Node.js again. We can't do that. Yeah, it's also on, what's the latest major version at time of recording? 24.10 or so, or we're not quite at the 2.0 level anymore. Yes, that's correct. I'm working on Node.js 25.0 that will go out in two days. Oh, well, that's exciting. What are the major changes or features for 25? So one thing important about server major releases, a lot of people believe that server major are the most exciting releases of packages, of runtime platforms like Node.js, but turns out that it's very, very boring.
25:02Server Minors goes to server miners releases. Performance improvements, they most of the time are categorized as SemperMiner or SemperPatch, which means that it's very likely that Node.js 24.10 will be way more exciting than 25.0, because 25.0 only contains breaking changes. And for Node.js 25.0, we will have the upgrade version of V8 to the version 14.1, which will bring the major JSON stringify performance improvement. So if you look to the V8.dev, they have created a blog post about how they have made JSON stringify fast. And with this version of Node.js, it will bring the V8 version that includes that performance improvement.
25:50We will have a new built-in inside integer 8 array. It's for base 64 or hexadecimal conversion. Web assembly and GIT pipeline optimizations. We are also enabling adding a new feature to the permission model, which is the dash dash allow net. So network will be restricted whenever you use the permission model on Node.js 25. But other than that, we don't have a lot of features coming in. Most of them, they are breaking changes or considered breaking changes. So if you are using the permission model Node.js 24, it's likely that you get affected by Node.js 25 with this new network restriction. We are unflagging the experimental web storage.
26:34So web storage will be enabled by default on Node.js. And we are deprecating and removing a lot of APIs. APIs that was runtime deprecated, they were removed on Node.js 25. and some of them will be runtime deprecated on Node.js 25. So if your console, whenever you run Node.js and some API is emitting a warning to you that this will be soon removed, possibly Node.js 25 will break you. So upgrade that. That is exciting, removal of dead code. Does that attach node performance, download size, and so on at all? Yes, I mean, we'll remove code that needs maintenance. So for us, maintainers, it's very good to remove code.
27:17Is your AI model taking weeks to train? Or is it too slow for real-time inference? Fixedars AI Booster is the acceleration platform that solves both. AI Booster automatically analyzes and optimizes your entire AI pipeline. The result? Dramatically faster training. Up to 5 times faster. And compute costs slashed by up to 80%. Trusted by major companies including Sony Honda Mobility. Stop waiting on your hardware. Visit FixedStars.com to learn how. I want to take us a bit back to the second of two scenarios. We talked about a performance optimization attempt that ended up showing, well, not always optimal.
27:57Is there an upcoming one or a recent change you've made that you're excited about for a performance that did work out? There are one that the pre-request is to open. I wrote that with Robert. We'll bring a significant performance improvement to the HTTP module of Node.js. We talked about that and then I remembered. But it's an opt-in feature. So we are releasing that to not break people. It's a new flag. Whenever you create an HTTP server, there is an optimize empty request option. Basically, if you are relying on the REST pattern, which is get request should not have a body. Head request should not have a body.
Read the full transcript
28:40If you enable that option, your HTTP server will be faster because we'll clean up the string faster. We'll dump the string. However, there are people that still read body from get and head requests. So if we enable that by default, we'll break those people. Okay, so I believe that we will have that option. We will have some discussions to enable that by default, but this is a separate discussion. For now, let's bring that option. So frameworks like FastFi or Express, they can enable that if they want to. So they will have this gate. If Express enabled that by default and people were not mad with it, it means that Node.js are likely to enable that by default as well.
29:26So this request. Before you move on, just looking at pull 59778, Optimize Empty Requests, You've got a screenshot in the body of the description showing requests per second. And it looks like you're going from, in one of the cases, 32 ,000 to 69 ,500. That seems like a significant increase in throughput. Yes, that benchmark we have run for 30 seconds in a dedicated machine. So without this option, enable, we got 1 ,000 requests, let's say, or 32 ,000 requests per second in one percentile to 69 ,000 in one percentile requests per second. So we are more than doubling down the performance of HTTP.
30:13But this is specific to the get and head requests. It's pretty incredible. You can see how the decision is not easy to make of whether you and when you might want to make the breaking change and turn this on by default. If you're doubling the request per second, but also breaking so many people, Surely that's got to be a long, slow, deliberating process to turn on. That's correct, yes. And I just saw that they need to rerun that CI and land that. This is one of the problems. We run so many CIs in different environments because Node.js runs everywhere. So we have SmartOS, we have Mac OS, we have Windows different platforms, we have Linux different platforms, and we need the CI to be green in all those.
30:57I believe that we have more than 60 ,000 of assertions on Node.js for tests. So it takes a significant amount of time. So to get a green CI, it usually gets, say, six hours. If you get a flaky test, you need to rerun that. So it takes a while. Well, okay. You are about to look up some more exciting improvements that you're looking forward to with the next versions of Node. There are some improvements that we did to the Node.js core, but we don't have it optimized on a specific internal code of Node.js. So it doesn't translate to an API where people will experience that in real world applications.
31:41So there are improvements to the assert partial deep strict equal. There are improvements to the how Node.js is benchmarked. So, for instance, people always ask me, if Node.js has so many benchmark files, we have benchmarks for every feature we release, why regressions still exist? Why you don't measure benchmark? Why you don't run benchmarks after every release or before every release of Node.js to find regressions? The reason is that nowadays to run a full Node.js benchmark CI, it takes 84 hours. 84 hours. Wow. The reason for that is that because measuring JavaScript code is tricky, we can't run a benchmark just once.
32:34We rely on an algorithm called new hypothesis, which tends to be the student test approach, which is we run each benchmark for each configuration 30 times before the change and 30 times after the change. So imagine the situation where in our benchmarks we have configurations. So let's say that we want to create a benchmark file for the O2 inspect or console.log better. So we create a configuration where we call console.log with a long string, with a short string, with an integer, with an object, with other options like a long object or a small object. So all those are configurations. So we run the benchmark 30 times for each configuration before the change.
33:25So 30 times for integer, 30 times for short strings, 30 times for long strings or big strings. and then we run that 30 times again after the change. Then we produce that statistical analysis to prove the variance or if the change, if the performance is statistically significant or not. Because sometimes you run the benchmark before the change just once and run that after the change just once. And then you compare, okay, I got more requests per second or I got more operations per second, so my code is faster. but that's not the reality. Your machine is doing a lot of things in background. So if you are in a Zoom call when you are running a benchmark, it's very likely that your code will produce a lot of variance that will impact in the result.
34:14And then the operations per second you get in the end is not true. It doesn't show the reality. Brendan Gregg once did an experiment in 2018, I believe, where he shot in the data center And then he expressed that the slow disk IO operations increased just because he went right in the front end of the data center and should. So this proved the variance. So to calculate if your benchmark produce a statistical significance, which means that if the P value is greater than 0.05, it means your code, they don't belong to the same group, which means your performance improvement is valid or your regression is valid.
34:59Otherwise, they are just in the same sense of the standard variation. So that's why people normally plot data into a normal distribution. So they measure that. And that's why it takes so long to run benchmarks. But we are improving that. We are creating more machines. We are sharing that, but it will take a while. That's an incredibly statistical, mathematical way to look at this. That must have taken a long time to get to. I love that part, to be honest. Most of my research and my studies are about that. So if you look to my blog posts, to my blog in general, I talk a lot about how to prove if your benchmark is valid or not, and how to not get tricky.
35:39So I wrote talks about that. There's a talk where I created with the help of my team. It's called Lies, Them Lies, and Benchmark, which basically shows you why most of the time your benchmark is being lying to you. And this also points to when I was talking about HTTP loading tools. I mentioned that there is no difference between Apache Benchmark or DAP work or AutoCannon, but the reality is there is. There's a problem when you are using HTTP load frameworks called coordinate the mission. So, G10, once, there is a HTTP load tool called Work, WRK, and G10 Work created a second version, a fork of it, WRK2, which fixes the coordinate omission.
36:30Coordinate omission is simple, if you try to explain. Imagine that you send a request to your server. Once the server replies back, it will send another request, and then it measures the latency. But this doesn't show the reality. Once you send a request, you should send another request after X seconds. So it will show how real-world applications behave. Then you get a long latency on the second request because the server is waiting for the second response. So there is a long explanation on the WRK2 repository. I strongly suggest you to test it. And it's valid. That points are a very good solution.
37:12So I normally use that for benchmarks in Node.js. Let's talk about your blog a little bit. You're the author of a series, The State of Node.js Performance. What is The State of Node.js Performance? What does that blog post talk about? In 2023, I've been doing Node.js major release for quite a while. I believe since Node.js 18 or Node.js 17, I don't remember. I did all Node.js major releases. So Node.js 17, 18, 20, 21, 22, 23, 24, and in two days, 25. hopefully. And I have always wondered, okay, we are releasing a new merger version of Node.js, but what this means to performance enthusiasts, it means that if I migrate from Node.js 18 to Node.js 20, my code will run faster.
38:01A lot of people don't know that and they create issues on Node.js core repo. After migrating from Node.js 16 to Node.js 18, my code, my application is behaving worse. And because benchmarks takes a while, we don't run that very often and we don't have machines or capacity to run that. So Node.js core developers, they had to investigate that. They need to replicate the environment of the issue. So some of them are only replicable on Windows. Some of them are macOS. And it was very hard. So I decided, okay, after releasing Node.js 20, I want to know exactly which workload or which APIs will be affected, either by regression or by performance improvement.
38:48We can't do that as part of Node.js release process because this takes a significant amount of time. And on Node.js 2023, I did using my own time and 2024, I got sponsored by the company I'm working on to NodeSource. So they give me machines to test that, the dedicated machines time so I could do that. And I'm planning to do the 2025 version. So on this report, I utilize three versions of Node.js. For Node.js 2024, I have used Node.js 20.17.0 and 22.9.0. and also comparing to the 18 version of Node.js. So I split the benchmark setup using the Node.js internal benchmark suite, which takes 84 hours, and Node.js bench operations, which is a repository where I maintain, where I also monitor small operations like converting strings using parse int versus plus sino.
39:54Is that faster on this specific environment? So this repository where I store all those benchmarks, and specific APIs, for instance, HTTP server, Fastify and Express, it got worst or better with this new version. Because in all major versions of Node.js, we upgrade the V8 version. By upgrading the V8 version, we never know exactly which APIs will be affected because it's JavaScript in the end. If they change something in the JIT compilation, this might affect the whole ecosystem or this might affect just specific operations on Node.js. So, for instance, the V8 update got the parsing into performance upper that matches the plus sign-up.
40:39So this report is a more comprehensive study about how the Node.js benchmarks are evaluated, how we guarantee we are not measuring non-operations, and how it will affect you. So, for instance, by upgrading from Node.js 18 to Node.js 20, or better from Node.js 16 to Node.js 20, if you were relying on Node.js crypto operations, your code will be very slow now because of OpenSSL. So then we track down all Node.js dependencies. Node.js depends on LibUV, depends on OpenSSL, many other dependencies. Just to know process.versions, you will see all the dependencies of Node.js. And it got worse because of OpenSSL.
41:25Now it's fixed because we have improved, we have upgraded Node.js to the OpenSSL version 5.2, if I'm not wrong. And this report contains all the information and all the resources you need to know before upgrading, or even to diagnose your Grafana dashboard. Because when people upgrade Node.js version, they will say, okay, my app is now consuming 25 % more memory, but is using 20 % less CPU. Is that bad or good? And then on this report, normally there's an explanation and why this is good or why this is bad. Do you find that people understand the metrics as put forth? Are there ways to kind of convey the nuances and complexities of them that the common node user would understand?
42:12The reports, I normally use percentages. So it's easy for them to say, okay, this API is 15 % faster or 15 % slow. I always create two kinds of sections. One for people that just want to get the value and one for people that wants to understand how the benchmark was executed. That makes sense. Before we move on to the last area of technical topics, I do want to ask about your company, NodeSource. Your employer, they sponsor this work. What is it that NodeSource does? NodeSource, it's a consulting company, but they also create products. They have an APM which measures the performance, all the metrics of your Node.js application without sacrificing the performance.
42:58For instance, it's very weird for me as a performance enthusiast that if I want to deploy my application in production and I want to monitor that, I want to measure the performance of my app, this will reduce the performance of my app by 30%. It's weird. It's just bad. AnySolid, a product from NodeSource, exists. It's an APM. Basically, we have forked Node.js. We are still rebasing on top of Node.js, but we have added or changes that makes APM fast. So now, if you don't use APM or use AnySolid, the performance will be the same. So we have no direct impact in your app. So you'll be able to see in the console, CPU utilization, event loop utilization, memory utilization, and even creating CPU and heap profiles without losing performance.
43:54So you can do all of that in production. So that's why NSOL does exist. And that's why I like it. Is this something that could be upstream to Node as an option? Yes, we do a lot of upstrings to Node.js. but we also understand that the process of moving things to Node.js is slightly slower because it expects consensus from all members to make some changes. And some of them are too business-oriented that doesn't go to the Node.js, but go to a product like NSOLID. But yeah, we do a lot of upstream patches. Great. I love to hear that. It's good to see people in the community, companies in the community that not just work around Node, but on Node and in it itself to make it better for everyone.
44:42Yeah. Let's talk at the end of this section about user land libraries. Let's say that I am writing an app and I'm using N-Solid for logging and APM. I'm using Fastify rather than, say, Express or Core HTTP. What are some of the tips and tricks you'd use or you would give me to make sure my app is fast, let's say? It really depends on the SLO or on the expected requests per second you want. I know that a lot of people will say that I want my app to be the fast as possible, but some of them don't need to spend too much time on fine-tuning as other companies. So I would say that if you choose a good ATP framework like Fastify and makes a good usage of Fastify because it's not just using Fastify, it's creating Fastify routes with the correct expected request objects and expected response objects so Fastify can optimize that.
45:40It's creating a good pattern of projects. So most of the bottlenecks is in the business code, right? If you receive a request, you need to connect to the database. So make sure you have a pool of connections. Measure your code using trace opt and trace the ops to track, to check, if you are making use of V8 optimizations. Some people, they don't understand how hidden classes on V8 classes make your code faster. So they are creating an object and using the delete property. For instance, I have an object and I want to delete one property from this object. They use the delete keyword for that. What they don't know is that whenever you use the delete keyword, the hidden class will go away and these objects will be way slower than it should be.
46:28So instead of using delete, assign the value to undefined so you don't delete the hiding classes. So creating objects using the correct or the expected object tree. So all of these, you can get the information by using trace deopt. If you get too many deoptimizations during your code, something is wrong. Make use of a good logging library. Whenever you call an API too much, you need to make sure that this API is as fast as possible. So VinoJS is a good login library. When you create a database connection, make sure that inspect the network. Check if you are creating too many sockets. Check if the connection is being up in the pool of connections.
47:12So you don't need to create a new connection with database whenever you send a query for that. So there are more generic performance tips than Node.js tips, I would say. So measuring the errors of your machine. So check the events, check syscalls, check if you are using the correct version of Node.js, please. There is a package I wrote. It's called ismynodevulnerable. So just run your terminal. npx ismynodevulnerable. Is-my-dash, blah, blah, blah. and it will tell you if you are using a surf version of Node.js or not. I think upgrading the dependencies is very important. I always suggest to use less dependency as possible.
48:00So for instance, if you use uchu.styletext, this replaces some usage of chalk. If Node.js has now a TypeScript, Node.js has Escalade, we have a lot of built-in modules that I strongly suggest you to use that because we can make it faster. What are your thoughts on lock files as applications and as servers? I don't work on products like business products for quite a long time. I have been working with open source or libraries for the last five years. So I don't have a strong opinion on that part. I know as a maintainer that we normally don't use the lock files so people can upgrade that. we don't release log files because people can upgrade that.
48:49At least this is how we handle that on FastFi and I believe Express as well. So I don't have a strong opinion. What a rare and beautiful statement from someone who works deeply in tech. I don't have a strong opinion. Yeah. All right. We're heading towards the end of the interview. Are there any topics you wanted to bring up when it comes to Node or security or performance? Well, if you are interested on Node.js core and you want to make your contribution, I have been doing live streams on Twitch, YouTube, and also Axe, teaching people how to contribute to Node.js. So I've been planning to create a live stream during the Node.js 25 release to show people how I release a major version of Node.js.
49:32And I normally announce the live streams on the Node.js mentoring channel, either on Node.js OpenJS Foundation Slack or on the Node.js Discord server. Have you found that a lot of people have started contributing to Node through these live streams? Well, I know at least 10 people that got their first contribution to Node.js with some guidance from the live stream. So it's a very good number for me. In a sense, you've become a 10x developer. Yeah, kind of. Let's say that I'm somewhat interested. I've never contributed to a major open source project before. I would love to do it. I don't really know what that entails or what the benefits and drawbacks are.
50:12How would you pitch this to me? I would say that my career would be way boring if I didn't contribute to open source because it opened so many challenges for me that I could learn a lot. I'm pretty sure that if I haven't started contributing to Node.js, I would have stopped my C++ studies. I would have stopped a lot of performance improvements research I did. So this helps me to find good offers. I have received many, many offers because of my open source work. So I could travel through the world. I'm from Brazil. And for me to go to Europe is like 12 hours flight. And it's very far. I have been in China delivering talks.
50:59I have been in the whole Europe delivering talks. And all of these were not possible without my contributions to the open source. That's lovely. So you've become a member of a global community of people? Yes. I mean, I have more people that I know by GitHub handles than in real life. That's lovely. To close out the interview, I'd like to ask something explicitly non-tech related, and that's a great transition. Let's talk about friendships in sports. You used to play tennis, and you've recently switched what you've kindly been calling behind the scenes soccer and what others may call football. Can you tell us about that?
51:34I have recorded some fire chats at NodeConf, I don't know, two years ago, three years ago, where I told people I have started playing tennis because finding people, finding friends to play soccer is way difficult because for tennis, I just need to find one person. But for soccer, I need to find a whole team. And now, after three years, I could find a good amount of people. And now I'm playing more soccer than tennis. So yeah, I've been playing soccer, I don't know, three times per week as a good Brazilian. So we love soccer. So we do that. It's in my blood. So yeah. Do you root for any clubs or players still?
52:16I support Santos. It's the Neymar team in Brazil. But I mean, we are not good. We are not good now. We are very good, to be honest. But we are not good now. I also like a lot Manchester United. it, but it's still, it's in the same situation as Santos. A person must have hope in this world. Well, great. Rafael, you've talked about a lot of incredibly exciting and interesting things. We talked about security in Node, talked about performance, how Node's internal performance works, is improved, and has been benchmarked and optimized. We talked about tips for use in Lend libraries, and also, of course, your regular streams where one can learn how to contribute themselves.
52:58If we wanted to learn more, if we wanted to reach out to you on the internet, where would you direct us? Join the Node.js mentoring channel. I'm mostly available on X and also Slack. So if you want to send me a message on Slack or Discord, I'm happy to guide you to your first contribution. Also on X, my DMs are open and I'm happy to help. For Software Engineering Daily, this has been Rafael Gonzaga and Josh Goldberg. Thank you for listening, everyone. Have a great day. Thank you.
From the publisher
JavaScript has grown far beyond the browser. It now powers millions of backend systems, APIs, and cloud services through Node.js, which is one of the most widely deployed runtimes on the planet. Keeping such a critical piece of infrastructure fast, secure, and stable is a massive engineering challenge, and the work behind it is often
The post Node.js in 2026 with Rafael Gonzaga appeared first on Software Engineering Daily.
