V8 Blog
v8.dev · Company blog · on HN since 2018
The V8 team at Google writes about the JavaScript and WebAssembly engine used in Chrome and Node.js, covering performance and new features.
What HN saysCommenters call it awesome and link it for details on WebAssembly tail calls and V8 internals, such as how values are represented.
272HN people shared it
184linked it in comments
203stories submitted
5.7Kstory points
3 months agolast shared
2018people per year2026
Most-shared posts
- 1The cost of parsing JSON12 people · 940 points · first shared 2019 · 293 comments on HN
- 2V8.dev (new v8 website)12 people · 4 points · first shared 2018 · discussion on HN
- 3Fast Properties in V8 (2017)12 people · 2 points · first shared 2020 · discussion on HN
- 4JIT-Less V810 people · 339 points · first shared 2019 · 116 comments on HN
- 5Fast, Parallel Applications with WebAssembly SIMD10 people · 16 points · first shared 2020 · discussion on HN
- 6Introducing the WebAssembly JavaScript Promise Integration API10 people · 13 points · first shared 2023 · 1 comments on HN
- 7Code Caching for JavaScript Developers10 people · 6 points · first shared 2019 · discussion on HN
- 8Blog Posts Archive10 people · 1 points · first shared 2019 · discussion on HN
- 9There's Math.random(), and then there's Math.random() (2015)9 people · 129 points · first shared 2019 · 76 comments on HN
- 10Land ahoy: leaving the Sea of Nodes9 people · 39 points · first shared 2025 · 4 comments on HN
- 11Faster async functions and promises9 people · 12 points · first shared 2018 · 1 comments on HN
- 12Ignition interpreter9 people · first shared 2019
- 13Pointer Compression in V88 people · 29 points · first shared 2020 · 1 comments on HN
- 14V8: A Year with Spectre7 people · 352 points · first shared 2019 · 212 comments on HN
- 15High-performance garbage collection for C++ V8 (2020)7 people · 114 points · first shared 2020 · 38 comments on HN
What HN people wrote when they linked it
Zababa · 2021-12-30
Usually software architecture is not language-dependant, so your knowledge from Java could be used here. For example, you can do hexagonal architecture in NodeJS. All of what you learned about exceptions can also be applied here. Probably most of what you learned about static typing too, if you work with TypeScript.
I think another part of learning JavaScript is forgetting what you learned in other languages and embracing JavaScript. At work most of the JS/TS code is namespaces and plain functions, with the occasional object when that makes sense. We don't use much the dynamic nature of the language in application code, but for testing we use it a lot.
For the performance part, I agree, it's hard to find resources. Part of it is because JS is "good enough" for most server-side software: the language is fast and asynchronous IO helps a lot. Most high-level advice is about being nice to the JIT: write code as if it was statically typed, let the JIT make easy assumptions and don't break them (objects that don't change, arrays used as arrays). Part of it may also be because the V8 team is constantly hard at work to improve performance. Their blog (https://v8.dev/) is a great read, I learned a lot here. There's another high-level advice that works everywhere: try to make a stateless app, so that scaling horizontally is easy.
starmole · 2025-03-31
Be amazed by learning about tail calls in WASM:
https://v8.dev/blog/wasm-tail-call
the key here is that there are new, different opcodes that can be tail call optimized! Because tail call optimizing the old op code would break the spec. It all makes sense, but is kind of amazing.
madeofpalk · 2024-03-25
Semi-related - I saw this on https://v8.dev a while back, but `filter: hue-rotate(180deg) invert();` can be a neat CSS trick to 'dark mode' some kinds of graphics, while not screwing with the colours so much. The `hue-rotate` help a bit to keep 'blues blue' etc.
It's far from perfect, but it's a neat one to have in your back pocket.
cztomsik · 2022-09-29
only SMIs are passed by value (because they are actually encoded in the reference data type)
It might be a bit outdated but here's more https://github.com/thlorenz/v8-perf
Also the https://v8.dev/ blog is awesome.
asguy · 2022-08-04
Except for most of deno that's written in Unsafe C++.
https://v8.dev/
conaclos · 2022-07-06
Every JS engine has interesting design choices. V8 has more documentation than other (the v8 blog is great resource [1]). This ism ore easy to have an overview of V8 internals. It could be nice to have more internal overview from other engine, in particular SpiderMonkey. It is hard to find up-to-date info.
[1] https://v8.dev/blog
jeremyjh · 2022-06-15
I have a lot of respect for Kenton, but the facts are: v8 security team recommends running untrusted code in separate processes [1], and as described in your link, Cloudflare doesn't do that. From what Kenton said earlier on this[2], it sounded like they had already committed to their architecture before that v8 recommendation was made. They thought through a lot of possible attacks and created some clever mitigations, and ultimately decided "its probably ok".
[1] https://v8.dev/docs/untrusted-code-mitigations#sandbox-untrusted-execu…
[2] https://news.ycombinator.com/item?id=18280061
eta: Also, Chrome does use process isolation - every browser tab runs in a separate process. The whole point of Cloudflare isolates is to avoid the overhead of a fork() for each worker request.
Ruphin · 2022-03-16
Deno does not have its own javascript implementation, it uses the V8 javascript engine, and V8 happens to implement padStart and padEnd.
V8 was originally created as the javascript engine for Chrome, but it is used in many products now, including Node.js and Deno: https://v8.dev/
wruza · 2022-01-10
It depends. Bare hash tables are semi-random and get reshuffled at growth points naturally. But I remember reading in some manual that that language reshuffles iteration even for immutable hash tables. Js objects are usually based on "shapes", which do not follow hash table semantics:
https://mathiasbynens.be/notes/shapes-ics
https://v8.dev/blog/fast-properties
patrec · 2021-12-28
> That link is not an issue with json, but with javascript (that js treats keys named __prototype__ special).
JSON is meant to be (and was widely advertised as) a Javascript subset, but isn't, but almost no one is aware of this. So of course it's also an issue with JSON. It's also not the only divergence that leads to security problems, in fact if you follow the first link in the comment you will see that this was posted in the context of trying to fix another misspecification in an attempt to actually make JSON a proper subset (which turned out to be impossible to completely accomplish, although at least the paragraph separator issue has been fixed in 2019). See here:
https://v8.dev/features/subsume-json
IshKebab · 2021-09-16
That's a pretty terrible example. No way do you want temporary directories to be created just by loading a class. That violates all sorts of best practices.
There's a better example here: https://v8.dev/features/class-static-initializer-blocks
You could also use it for initialising generated constants.
harikb · 2021-06-07
While the other comments are focusing on improvements for browser, v8 is also what powers Node, Deno, and several cloud workers implementations.
While I don’t yet know if this particular change improves server-side work flow, I am hoping it does. I plan to do some tests.
I applaud the work done by v8 team, releasing it as an open source JavaScript executor, and excellent technical articles on the v8 blog [1]
Can we please separate the blaming and shaming of ads-ecosystem for a moment and appreciate the technical achievements this team is creating?
[1]. https://v8.dev/blog
SigmundA · 2021-03-24
Unfortunate but I was surprised Apple looked like they where changing it at all since it would lessen security allowing some common attack vectors.
I haven't followed it for some time however, it does look like V8 supports a JITless mode now which allows it to possibly be used on iOS and other platforms with NX set, albeit with significant performance loss:
https://v8.dev/blog/jitless
Looks like JavaScriptCore still disables JIT when run in a non entitled app. Always thought they might figure out a way to at least let their own JS engine JIT since its trusted in Safari on the open web, but I believe its an all or nothing thing for the process/app and not per module thing.
vmarchaud · 2020-06-16
In the case of NodeJS, which use the V8 Engine [0], you have access to the diagonistics API [1] that allows you profile your cpu or memory consumption.
There are some tools that make that easier (see [2] or [3]) but you often left to interpret the result yourself
[0]: https://v8.dev/
[1]: http://nodejs.org/dist/latest-v12.x/docs/api/inspector.html#inspector_…
[2]: https://github.com/davidmarkclements/0x
[3]: https://github.com/vmarchaud/openprofiling-node
PS: Disclamer i wrote one of tool i mentionned above [3]
quickthrower2 · 2020-04-27
I was lucky enough to see this live - https://v8.dev/blog/elements-kinds - but I recommend watching and reading for anyone. Half because is pretty interesting and accessible at the same time. And half because you might use it .
Also Typescript is well worth learning.
darepublic · 2020-02-19
If you want a "perfect" understanding of ecmascript as it is implemented by V8 why not study the open source code for V8: https://v8.dev/. How hard will it be? Well how good are you at reading code/ how much do you know about c++? If this seems too daunting, better stick with a less than perfect guide to get you part of the way there.
Ajedi32 · 2020-02-07
Chrome used to rely on fixed synthetic benchmarks like this for guiding their performance optimizations, but quickly realized they aren't a great indicator of real world performance and ditched them in favor of instead evaluating Chrome's performance against a collection of popular, real-world websites. See https://v8.dev/blog/real-world-performance for a discussion of their bench marking methodology.
charrondev · 2019-09-15
See
https://v8.dev/blog/cost-of-javascript-2019
JavaScript has, in a addition to download time, parse and execution time. These are non-negligible on lower end devices.
30k of JS has a far greater impact on the speed of your page than 30k of images.
daxterspeed · 2019-02-17
If you're looking for a live .dev domain (for testing purposes etc) https://v8.dev/ has existed since September 2018.
rhdunn · 2026-08-13
It can sometimes be difficult to predict what will cause performance regressions when developing an application or web server with test data. So you do your best with what you know at the time of release, and then deal with performance issues when you know what is causing regressions (e.g. saved searches) and can then make measurements and profiling to see what exactly is causing the issue.
Likewise, improving performance pushes the limit at which performance regressions happen allowing more data (documents, triangles/pixels, etc.) to be processed. This allows things like more complex game graphics. That in turn makes it harder to improve performance for the next round (more advanced triangle/face culling and pre-processing).
There can also be trade-offs with things like data layout, memory usage (caching and memoization), or implementation. For example, when processing XML/HTML data you could use DOM (more memory and upfront parsing, but easier to perform complex queries across the data), SAX (less memory, but more complex to process due to tracking state), or reader API (similar to SAX but a different processing model).
There can be challenges with various features, such as type checking with higher-order generic types. Others add various levels of overhead, such as parsing a program, constructing an AST (Abstract Syntax Tree), generating an IR (Intermediate Representation), the optimization passes and final code generation.
JavaScript evaluation for example is…
CGamesPlay · 2024-06-22
I was struggling to figure out how this could even be exploited. Following a trail of links led to <https://v8.dev/blog/control-flow-integrity#corrupted-syscall-arguments… which motivated the API. It gives the example that "if a thread calls munmap on a corrupted pointer, the attacker could unmap read-only pages and a consecutive mmap call can reuse this address, effectively adding write permissions to the page."
So, a hypotetical attack would involve 1) Corrupt a pointer passed to munmap, such that it points to some believed-executable part of the code (e.g. the MPEG decompression library code, or something like that). 2) Cause a future `mmap` to reuse that page with writable permissions, and in particular have the returned page be one that is eventually destined for being marked executable (e.g. the caller should be the JIT compiler). 3) Modify the writable page to control code you want at a known address (e.g. by having the JIT emit code you want, or by having another vulnerability that writes to this address). 4) Have the target page marked executable (e.g. by finishing the JIT compilation). 5) Finally, call the executable page (e.g. attempt to decompress an MPEG file).
In the absence of already having arbitrary code execution (which would make the whole process moot), this whole thing requires a JIT compiler (since it has to already contain a call to `mprotect` that sets a page executable), and either the JIT compiler has a bug or a separate thread performs step…
aniviacat · 2024-06-21
On the v8 engine's blog, it is claimed that most of its vulnerabilities are caused by logic issues which Rust wouldn't help with.
Perhaps it's a similar situation for Ladybird.
>Memory safety remains a relevant problem: all Chrome exploits caught in the wild in the last three years (2021 – 2023) started out with a memory corruption vulnerability in a Chrome renderer process that was exploited for remote code execution (RCE). Of these, 60% were vulnerabilities in V8.
> V8 vulnerabilities are rarely "classic" memory corruption bugs (use-after-frees, out-of-bounds accesses, etc.) but instead subtle logic issues which can in turn be exploited to corrupt memory. As such, existing memory safety solutions are, for the most part, not applicable to V8. In particular, neither switching to a memory safe language, such as Rust, nor using current or future hardware memory safety features, such as memory tagging, can help with the security challenges faced by V8 today.
See: https://v8.dev/blog/sandbox
IainIreland · 2024-03-11
(I work on SpiderMonkey.)
Benchmarking is hard. It is very easy to write a benchmark where improving your score does not improve real-world performance, and over time even a good benchmark will become less useful as the important improvements are all made. This V8 blog post about Octane is a good description of some of the issues: https://v8.dev/blog/retiring-octane
Speedometer 3, in my experience, is the least bad browser benchmark. It hits code that we know from independent evidence is important for real-world performance. We've been targeting our performance work at Speedometer 3 for the last year, and we've seen good results. My favourite example: a few years ago, we decided that initial pageload performance was our performance priority for the year, and we spent some time trying to optimize for that. Speedometer 3 is not primarily a pageload benchmark. Nevertheless, our pageload telemetry improved more from targeting Speedometer 3 than it did when we were deliberately targeting pageload. (See the pretty graphs here: https://hacks.mozilla.org/2023/10/down-and-to-the-right-firefox-got-fa… This is the advantage of having a good benchmark; it speeds up the iterative cycle of identifying a potential issue, writing a patch, and evaluating the results.
chrismorgan · 2024-02-01
> Origin Private FileSystem
Safari’s had that for more than two years. (Chromium, more than three, Firefox, almost one.)
> Import Assertions
An excellent example of why Firefox and Safari tend to be more reserved in what they ship, in contrast to Chromium which is much more fond of shipping immature stuff.
Import assertions are dead, superseded by import attributes. V8 has deprecated import assertions and will remove them soon. See https://v8.dev/features/import-assertions for more info on why.
Chromium shipping immature stuff is, from time to time, a real pain, because it makes it harder to fix problems in the spec as you sometimes have to avoid breaking real usage. Sometimes this basically makes things worse forever, because of naming things. I can’t remember a specific case in browsers, but know they exist; but a similar case is how we have some methods named includes instead of contains like they should have been because of Mootools touching stuff it shouldn’t have, and so now everyone suffers for that mistake.
tentacleuno · 2024-01-08
> If that standard library would be written in JS, a new browser (or rather a new JS engine being a part of the browser) could just use some existing implementation
That sounds great, but I'm doubtful of the simplicity behind this approach.
If my understanding is correct, v8 has transitioned to C++[0] and Torque[1] code to implement the standard library, as opposed to running hard-coded JavaScript on setting up a new context.
I suspect this decision was made as a performance optimization, as there would obviously be a non-zero cost to parsing arbitrary JavaScript. Therefore, I doubt a JavaScript-based standard library would be an acceptable solution here.
[0]: https://github.com/v8/v8/tree/main/src/runtime [1]: https://v8.dev/docs/torque-builtins -- As I understand it, Torque compiles to C++ at compile-time, which is then linked and compiled into the rest of v8[2]. [2]: https://github.com/v8/v8/blob/main/tools/torque/format-torque.py
Dylan16807 · 2022-10-13
> This post goes into some detail about how the V8 JavaScript engine creates a [0, 1) floating point pseudo random value from its underlying integer pseudo-random algorithm: https://v8.dev/blog/math-random
You'd think so but it doesn't really say. It's almost entirely about how they make the integer.
Following the commit link shows that they use the method of filling 1.0 with random mantissa bits and then subtracting 1.0
>> The number of random values it can generate is limited to 2^32 as opposed to the 2^52 numbers between 0 and 1 that double precision floating point can represent.
Not really true. That's how many numbers their algorithm returns, which is almost as many evenly-spaced floats there are between 0 and 1. But because it starts with a number between 1 and 2, that method actually wastes a bit, and that number really should be 2^53.
But floating point itself has 1/4 of its values between 0 and 1, so for double precision that's roughly 2^62!
evmar · 2022-04-30
(I work on Figma's renderer, but I don't know much of the history of it.) The speculation there about C++ vs JS performance in Figma seem about right to me.
Notably, some Figma views (like when you click the "play" button to view the prototype) render Figma documents using JS, no* Wasm. They are more or less comparably as fast as the C++ renderer, in part because much of the heavy lifting is done by GPU code that isn't C++ or JS anyway.
The main place I think we've seen a performance difference is, as the post observes, high throughput scenarios: for example, decompressing a large file, or parsing through a large binary serialization of a file. But particularly in a browser setting you end up wanting to get your data into a browser API at some point and that often ends up meaning copying data around that eats your performance.
The other main difference that's worth pointing out is memory efficiency. For example, pointers in Wasm are currently 32 bits, which means (at least in principle) a massive graph -- such as a Figma document DOM! -- can be represented with 32-bit C++ pointers rather than 64-bit JS pointers. But even that distinction is not so clear in the presence of pointer compression [1] and there are other graph representation options etc.
In all, my conclusion is that performance does not obviously derive from tool choice because there are so many confounding factors including algorithm choice and path dependence. For another example of this, I often…
inoop · 2022-02-07
> Even my preferred IDE, the Jetbrains suite which I love, are resource hogs
Ok, so you're saying that because a large, complex desktop application uses a lot of memory and is also written in Java that therefore the JVM is a memory hog?
Well then, given how much of a memory hog Chrome is, I guess we can all shitcan C/C++ as well.
Look, in any reasonable apples-to-apples comparison the JVM blows anything PHP has out of the water, including haxe, hiphop, etc.
And even if you write a PHP-to-bytecode compiler (e.g. https://github.com/jphp-group/jphp) then there are certain limitations to how fast and efficient any dynamically typed language can be. Look at all the shit V8 has to go through to do field lookups: https://v8.dev/blog/fast-properties
And then there's so much useless request-level overhead to PHP, even with pre-cached bytecode, you're never going to get even close in terms of latency to a well tuned JVM running something like spring boot.
And if you really hate Java as a language, you can always use something like Kotlin.
jrandm · 2021-12-31
My biggest pointer would be to remember that Java & JavaScript aren't named that way by coincidence. They're two different approaches to a similar problem. Java suffers from Enterprise Development (eg: Enterprise FizzBuzz[0]), JavaScript suffers from Ultimate Accessibility (eg: how many questions on Stack Overflow conflated jQuery and JS?).
> How should exceptions be managed? [...] Has there been a debate about best practice? Where can I find it?
I suggest you handle the errors you can and otherwise let it crash.[1][2] Debates in NodeJS-land have steered towards more monadic/Result-like structures and working synchronous-looking try/catch onto async/await. NodeJS and its various components are open source, you'll have a lot of luck looking around on GH for issues & PRs related to a feature -- same for the language, ECMAScript[3] officially.[4]
Since you mentioned Clojure, have you looked at ClojureScript?[5] That may be a good entry to JS authors & articles you'd enjoy.
> I have the impression that NodeJS is a bit more magical than the JVM [...] Is that correct? Where are good resources on this subject?
As other replies have mentioned, you're really talking about V8[6] for the "JSVM" executing that code. A thing I've seen throw some people for a loop is how minimalist the specification actually is.[7] The magic in NodeJS is certainly from V8 and the rate of optimizations there but also libuv,[8] what actually powers the infamous event loop.
Hope that helps!
[0]:…
throwaway189262 · 2020-09-21
V8 still uses STW for mark sweep. The benchmark image on this https://v8.dev/blog/concurrent-marking shows 50+ms pause time, quite bad compared to ~5ms or less in new Java collectors. This might be due to STW move phase though? They don't really explain, but the long pause times show that there's definitely still long STW pauses in V8.
For Go, I'm going to be a bad HN user and not read the whole article. Sorry, it's just too long for this time of night. It does appear that my understanding of Go GC is out of date. There's been many improvements in the last couple years. Some strange behavior due to not enough knobs to configure GC, but it appears to have a near constant GC pause? https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to…
I'm annoyed that Google doesn't offer much benchmarking results for V8. Huge articles about improvements made with a single benchmark image. And they didn't use standard benchmarks for either so it's unclear what they're even benchmarking. The Go slides you linked include benchmarks from some guys production server he tweeted images of, a bunch of standard benchmarks but they only show % throughout improvement, and no pause times.