🏗️ Load Testing loadtest
AlmeríaJS, 2023-12-27
🦍 Your Host Tonight
Alex "pinchito" Fernández
Silverback Backend Developer at Tinybird
🗂️ What We Will See
🤔 What Is loadtest
💃 Bringing It Up to Date
⏱️ Microprofiling Demo
☁️ Performance in the Cloud
🫓 Bun.sh: the Future?
🧓 Some History
10+ years of history no less
🚫 JS Didn't have
ES Modules
Classes
Testing package
async/await
Command-line processing
2.5M modules
✅ JS Had
🦕 Node.js v0.10
📦 30k modules
to choose from
🤔 What is loadtest?
👯♂️ Send a lot of requests per second
⚡ Verify performance of your endpoints
🔌 Has a very complete API
⭐ 2500 stars on GitHub
⚡ Welcome to the wonderful world of requests per second
loadtest v5 was not recommended over 1 krps
1 krps = 1000 rps
1 krps = 1 milisecond (ms) per request
⛷️ Competition
🥞 Secret Sauce: --rps
Option to send a fixed number of rps
Forces the server to respond in time
Does not allow for wiggle room
🧟 loadtest was so-so
Not dead, not alive
🛝 Had some downtime...
💃 Decided to have some fun
🍇 Use Multiple Cores
Virtually all modern computers have multiple cores
Use the cluster module
Half for the test server
Half for the load tester
Configurable with --cores
🔌 Use TCP Sockets
An idea by Matteo Collina
It is what autocannon does
Implement HTTP 1.1
Is it so hard?
⏱️ Micro-profiling
Use microprofiler
Start with this commit
See where every microsecond goes!
60 krps: 16.7 µs
80 krps: 12.5 µs
~4 µs of difference
📊 Performance Comparison
performance vs price
⚡ tcp-performance.js
☁️ Performance in the Cloud
🫓 Bun.sh: The Future?
🛠️ Fixed loadtest for bun
😲 Took me 1 hour 😲
🔭 Preliminary Impressions
runner | mode | krps |
---|---|---|
bun | http | 14 |
node | http | 19 |
bun | tcp | 62 |
node | tcp | 60 |
🔬 We Got Those Pesky µs
Ready for the nanoseconds?
⚡ Use performance
The performance package can measure nanoseconds, example:
$ performance Running benchmarks for 1000 ms Function nil running for 1.00 seconds: 9.65211e+8 iterations per second, 1 ns per iteration Function util._extend() running for 1.00 seconds: 7.1558e+7 iterations per second, 14 ns per iteration Function Object.keys() running for 1.09 seconds: 6.4279155188246095e+3 iterations per second, 155571 ns per iteration Function sha1-token running for 1.00 seconds: 3.19e+5 iterations per second, 3135 ns per iteration Function sha256-token running for 1.00 seconds: 3.1137724550898204e+5 iterations per second, 3212 ns per iteration Function replace-regexp() running for 1.00 seconds: 1.654e+6 iterations per second, 605 ns per iteration Function match().join() running for 1.00 seconds: 2.211e+6 iterations per second, 452 ns per iteration Function for().toLowerCase() running for 1.00 seconds: 2.101e+6 iterations per second, 476 ns per iteration Function for().charCodeAt() running for 1.00 seconds: 3.065e+6 iterations per second, 326 ns per iteration Function timestamp running for 1.00 seconds: 2.565e+6 iterations per second, 390 ns per iteration Function array-access running for 1.05 seconds: 6.653992395437262e+3 iterations per second, 150286 ns per iteration Function object-access running for 1.09 seconds: 6.433823529411764e+3 iterations per second, 155429 ns per iteration Function string+ running for 1.00 seconds: 1.9588e+8 iterations per second, 5 ns per iteration Function string-replace running for 1.00 seconds: 3.1248e+7 iterations per second, 32 ns per iteration Function string-replace-regexp running for 1.00 seconds: 1.4403e+7 iterations per second, 69 ns per iteration Function parseInt running for 1.00 seconds: 1.96069e+8 iterations per second, 5 ns per iteration Function |0 running for 1.00 seconds: 1.96167e+8 iterations per second, 5 ns per iteration Function Math.random() running for 1.00 seconds: 5.194e+6 iterations per second, 193 ns per iteration Function buffer-concat running for 1.00 seconds: 1.079e+6 iterations per second, 927 ns per iteration Function string-concat running for 1.00 seconds: 1.332e+7 iterations per second, 75 ns per iteration Function string-array-concat running for 1.00 seconds: 3.833e+6 iterations per second, 261 ns per iteration Function for-loop running for 1.01 seconds: 1.0515873015873016e+5 iterations per second, 9509 ns per iteration Function forEach() running for 1.01 seconds: 3.766105054509416e+4 iterations per second, 26553 ns per iteration Function for..in running for 1.32 seconds: 3.02571860816944e+3 iterations per second, 330500 ns per iteration Function for-function running for 1.02 seconds: 3.428011753183154e+4 iterations per second, 29171 ns per iteration Function Date.now() running for 1.00 seconds: 1.2858e+7 iterations per second, 78 ns per iteration Function process.hrtime() running for 1.00 seconds: 1.1091e+7 iterations per second, 90 ns per iteration
🤯 Conclusions
⏱️ Use benchmarks when needed
🛠️ Learn to use (and create) your tools
🫰 Cloud: rip-off unless you are careful
🔥 Intel's 13th generation is smoking hot
🫓 Bun: needs more time in the oven
Vendo Seat Panda 🚙
<a href="https://librecounter.org/referer/show" target="_blank">
<img src="https://librecounter.org/counter.svg" referrerPolicy="unsafe-url" />
</a>
📈 LibreCounter
🙏 Thanks!
🗣️ Let's Talk
Load Testing loadtest
By Alex Fernández
Load Testing loadtest
Talk for AlmeríaJS, 2023-12-27
- 239