Sign in

Matteo Collina

@nodeland.dev
4.6K followers 374 following 1.8K posts

Platformatic.dev Co-Founder & CTO, Node.js TSC member, Lead maintainer Fastify, Board OpenJS, Conference Speaker, Ph.D. Views are my own.

PostsRepliesMedia
Matteo Collina @nodeland.dev · 11h
yay! 🚀
011
Reposted by Matteo Collina
Nico Kaiser @nico.kaiser.me · 12h
📸 #NodeConfEU @nodeland.dev: Next-Gen Flame Graphs: Making Node.js Performance Profiling Actually Work
061
Matteo Collina @nodeland.dev · 29/09/2026
Thanks to the Booking.com team for the writeup and for pushing this upstream. This is exactly the kind of validation Watt needed. Real production numbers, published in the open.
020
Matteo Collina @nodeland.dev · 29/09/2026
Full writeup from the Booking.com team 👇 medium.com/booking-com-...
121
Matteo Collina @nodeland.dev · 29/09/2026
The result, across production test runs: wattpm pods handled at least 30% more traffic than pm2 pods: same CPU, lower memory. Then they scaled pods down 5% a day until they hit a 30% reduction.
100
Matteo Collina @nodeland.dev · 29/09/2026
Wattpm runs your workers as worker threads and lets the kernel hand out connections with SO_REUSEPORT. No supervisor, no IPC pass-through. Each worker accepts straight from the kernel.
101
Matteo Collina @nodeland.dev · 29/09/2026
The big move was swapping the process manager. They were on pm2 (Node's cluster module). A supervisor process accepts every connection and hands it off. That's an extra hop per request, plus a full duplicate of everything V8 builds at startup.
110
Matteo Collina @nodeland.dev · 29/09/2026
Here's what Booking.com shipped, from their own writeup: → 30% fewer pods → 20% less memory per remaining pod → Up to 10% off latency at p75 and p99 And they got there without touching a single line of their rendering code.
100
Matteo Collina @nodeland.dev · 29/09/2026
booking.com just cut compute costs on their biggest Node.js service by 38%. No new hardware. No code changes in the service. All of it from the platform layer. And the heart of it is @platformatic Watt. 🧵
booking.com
https://Booking.com
3196
Reposted by Matteo Collina
Ruy Adorno @ruyadorno.com · 29/09/2026
Thanks @vlt.io for contributing! 🔈 audio on to hear it from @nodeland.dev
0114
Matteo Collina @nodeland.dev · 29/09/2026
I would have never have expected @bengl.dev to put an AI slide on a talk 🤣❤️
030
Reposted by Matteo Collina
Nico Kaiser @nico.kaiser.me · 29/09/2026
📸 #NodeConfEU @nodeland.dev kicking off NodeConf EU 2026, Bologna, Italy.
0227
Matteo Collina @nodeland.dev · 29/09/2026
Do you know you can watch NodeConf live at live.nodeconf.eu ? Join now!
nodeconf.eu
NodeConf EU 2026 | Bologna, Italy
NodeConf EU 2026 returns to Bologna with tickets, venue info, and conference links in one fast single-page experience.
051
Matteo Collina @nodeland.dev · 28/09/2026
I object to making this automatic. I'd happily raise the pool where measurements justify it, but test on a busy host and watch slow requests, not just throughput. And you still need backpressure. blog.platformatic.dev/more-threads...
000
Matteo Collina @nodeland.dev · 28/09/2026
Waiting on storage is different from computing. A filesystem worker waiting on I/O uses little CPU, so starting another request can be worthwhile even with more workers than CPUs. Bcrypt spends its time computing, so it can't offer that.
100
Matteo Collina @nodeland.dev · 28/09/2026
One correction for small containers: Nub doesn't set the pool to ten. Ten is the nice value for workers beyond the first four. On one vCPU or less it leaves you with four workers at their original priority, just like Node.
100
Matteo Collina @nodeland.dev · 28/09/2026
The request side also has a cost. A bcrypt job already started on a low-priority worker can wait longer. Freeing another worker won't move the running job over to it. Protecting neighbors can come at the expense of completion latency.
100
Matteo Collina @nodeland.dev · 28/09/2026
Nub lowers priority beyond the first four workers to nice 10, and its busy-host measurements show less interference. That's useful. But nice isn't an instruction to wait for an idle CPU: the scheduler still hands those workers a share when the host is busy.
100
Matteo Collina @nodeland.dev · 28/09/2026
For bcrypt that matters right away. With no spare CPU, a dozen more hashing jobs take time from what's already running — including the event loop. Context switches and cache contention can cut overall throughput.
110
Matteo Collina @nodeland.dev · 28/09/2026
"available" doesn't mean "free". If `os.availableParallelism()` reports 16, those CPUs could already be busy with other apps. Let several processes each make that sizing decision and they all start their workers, competing for the same CPU time.
100
Matteo Collina @nodeland.dev · 28/09/2026
Nub's thread-pool PR has good bcrypt numbers for bumping the pool on the tested machines. But I disagree with auto-sizing it from CPU count. Before adding threads, we need to know what else is using the machine. 🧵
120
Matteo Collina @nodeland.dev · 25/09/2026
Paper: "State Without a Landlord" — arxiv.org/abs/2609.17645 Full write-up: blog.platformatic.dev/state-withou...
arxiv.org
State Without a Landlord: An Architecture Proposal for Peer-to-Peer Replication of Durable Workflow State
Durable-execution frameworks commonly journal execution steps of a long-running function and reconstruct state by deterministic replay; the journal is therefore the workflow's authoritative state,…
020
Matteo Collina @nodeland.dev · 25/09/2026
Exactly-once external effects still aren't possible. Code stays the same, the engine doesn't. Adoption is a Mirror World in three phases: mirror, custody flip, native. Node.js isn't a sandbox, so step ownership keeps you from running someone else's effectful code.
110
Matteo Collina @nodeland.dev · 25/09/2026
Fencing by topology, not by promise. A run is a chain of epoch cores with closure certificates. Four invariants carry the safety argument; I3, "durable means survivable," only holds at the "survivable" ack level, and it's priced per run, not hidden.
111
Matteo Collina @nodeland.dev · 25/09/2026
Resuming a run you didn't start takes 5 steps: fetch the journal from the DHT, pin the workflow code, authorize succession, replay through two gates (transcript hash + next-intent check), then advance in a fresh epoch core.
110
Matteo Collina @nodeland.dev · 25/09/2026
The proposed architecture splits into two planes joined by hashes: Hypercore/Autobase cores for live coordination, BitTorrent v2 swarms for bulk distribution. The journal holds 32-byte infohashes, not 2GB checkpoints.
110
Matteo Collina @nodeland.dev · 25/09/2026
The problem with a landlord: state lock-in (can't move a running workflow), availability coupling (can only resume where the journal is), unverifiable history (rows in someone's DB can be altered), and multi-party runs that need a landlord to hold everyone's approval.
100
Matteo Collina @nodeland.dev · 25/09/2026
The observation: a durable workflow journal is already, structurally, a peer-to-peer log. Append-only, single writer per run, deterministic replay. Same shape as Hypercore, right down to the fork-proof on history rewrite.
110
Matteo Collina @nodeland.dev · 25/09/2026
We published a new paper on what happens if the journal becomes an authenticated, append-only log shared by everyone in the workflow. 🧵
110
Matteo Collina @nodeland.dev · 25/09/2026
Durable workflows survive crashes, deploys, and sleep("7d"). But their journal lives in ONE place: a vendor's store, a cloud service, or your own database. Whoever runs that store has the only official copy. We call that role a landlord.
171
Matteo Collina @nodeland.dev · 21/09/2026
node —install, in C++?
230
Matteo Collina @nodeland.dev · 21/09/2026
I’m thinking of C++.
100
Matteo Collina @nodeland.dev · 21/09/2026
I’m starting to feel I need to write a npm client, in TypeScript, and optimize every part of Node.js that slow for it.
3280
Matteo Collina @nodeland.dev · 18/09/2026
The full article is available at blog.platformatic.dev/introducing-...
010
Matteo Collina @nodeland.dev · 18/09/2026
Threat model, API docs, and test suite are in the repo 👇 🔗 github.com/platformatic...
github.com
GitHub - platformatic/secure-eval-worker
Contribute to platformatic/secure-eval-worker development by creating an account on GitHub.
110
Matteo Collina @nodeland.dev · 18/09/2026
`secure-eval-worker` ships first as source for Node.js 26.3.0+, using `process.permission.drop()`. If your app needs generated transformations, programmable workflows, or stateful JS components, this is a practical way to run code with least privilege.
github.com
GitHub - platformatic/secure-eval-worker
Contribute to platformatic/secure-eval-worker development by creating an account on GitHub.
110
Matteo Collina @nodeland.dev · 18/09/2026
A timeout isn't enough to control resources. Defaults lean safe: 4 concurrent workers, 64KiB source, 1MiB messages, 1s timeouts, 256 host calls. Each worker costs ~12–20MiB on Linux x86-64, so measure before raising limits.
110
Matteo Collina @nodeland.dev · 18/09/2026
Need Node's native ESM loader or relative imports? `runUntrustedFile()` / `createUntrustedWorkerFromFile()` copy the allowed files into a private temp snapshot so the guest can only read what you staged.
110
Matteo Collina @nodeland.dev · 18/09/2026
The protocol authenticates messages with a per-session HMAC + monotonic sequence numbers, and rejects shared memory, class instances, ports, sockets, and even plain `Error` values. Bounded at every stage.
110
Matteo Collina @nodeland.dev · 18/09/2026
Capability-oriented design: expose `records.find(id)`, not `fetch(url)`. Host functions give authorization through your own trusted closures, not by handing over a database or network client.
110
Matteo Collina @nodeland.dev · 18/09/2026
4️⃣ Drop nested-worker authority 5️⃣ Close ambient communication 6️⃣ Harden known escape surfaces 7️⃣ Then compile and run the guest Order matters. Permissions dropped after import = a window where the code has more authority than you want.
110
Matteo Collina @nodeland.dev · 18/09/2026
The key security idea: remove all permissions *before* compiling, importing, or running any caller-supplied code. 1️⃣ Acquire admission before inspecting caller input 2️⃣ Validate the boundary against allowlists 3️⃣ Build a restricted worker with the Permission Model on
110
Matteo Collina @nodeland.dev · 18/09/2026
Need stateful components? `createUntrustedWorker()` gives you a persistent component with a set lifetime that handles messages one at a time via `send()` and `onMessage()`.
110
Matteo Collina @nodeland.dev · 18/09/2026
`secure-eval-worker` uses Node's Permission Model + worker threads. The simplest API is `runUntrustedCode()`:
110
Matteo Collina @nodeland.dev · 18/09/2026
A regular eval() has the same power as its host. Even a worker thread starts with wide access to filesystem, network, env, and Node features unless you strip them yourself. The goal here isn't a perfect sandbox: it's making least privilege the default when running code natively in Node.js.
110
Matteo Collina @nodeland.dev · 18/09/2026
Today we're introducing @platformatic's new library, `secure-eval-worker`, which runs JS in Node.js workers with only the permissions you choose.
110
Matteo Collina @nodeland.dev · 18/09/2026
Running JavaScript at runtime is everywhere now: AI-generated changes, user automation, plugins, programmable app parts. The problem is that a regular `eval()` inherits all the host's permissions. We built something to help.
2112
Matteo Collina @nodeland.dev · 17/09/2026
The worst part is that if you don't engage with the AI slop horde, they will escalate, and you get a CVE slapped on your project that you then need to dispute (and it will remain disputed).
0111
Matteo Collina @nodeland.dev · 17/09/2026
Last night I received "5" potential vulnerabilities. How many were actual vulnerabilities? 0. How many were bugs? 5. How many were from the same slop-bot? 5.
2210
Matteo Collina @nodeland.dev · 16/09/2026
What I see thriving is human-related: support and forward engineering. Humans like to talk to other humans when they have a problem, not to soulless machines. I don't have an answer to any of this yet; we are in such interesting times!
170