JSON::Stringify and node16/v8 string length limits

1,836 views
Skip to first unread message

philip....@airtable.com

unread,
Jan 4, 2022, 6:11:19 PM1/4/22
to v8-users
In transitioning from Node12 to Node16 we found that v8's string left limit went down to 512MB. We have a few places in our existing code base where we JSON.stringify() objects that serialize to hundreds of megabytes, and we're looking at alternatives.

Have folks in this forum worked through similar issues? In our use case, the next thing to happen will be gzip compression, so it's tempting to duplicate https://github.com/v8/v8/blob/main/src/json/json-stringifier.cc and the IncrementalStringBuilder therein to compress as it goes.

Thanks!

Jace Mogill

unread,
Jan 6, 2022, 9:48:17 AM1/6/22
to v8-users
Hi Phillip,

When faced with a similar situation we were concerned with startup/restore efficiency of parsing all that JSON every time the program was run, we concluded a lazy evaluation strategy worked best for us and we decomposed the object for serialization & storage, later it was reconstituted when referenced.  Your additional step of compression would complicate this, but the basic idea holds.

If you really need a monolithic snapshot, your plan of implementing your own based on existing deep-copy and stringify code is probably your least surprise-free permanent solution.  If you publish it you may discover you're not the only one reading and writing large JSON objects.

However, if it is possible to leverage your knowledge of the data to decompose it for serialization, a small amount of JS to paper over the decomposition may be all you need.

            -J

philip....@airtable.com

unread,
Jan 23, 2022, 1:10:31 AM1/23/22
to v8-users
Thanks for the suggestions!

I tried duplicating json-stringifier.cc but ran quickly into the fact that it uses v8::internal stuff which isn't exposed in the v8 public API, and therefore not exposed in Node's plugin APIs either. So, I implemented on top of v8::Object::GetPropertyNames() instead. Thus far, my implementation is 3x slower than the built-in one: together v8::Object::GetPropertyNames() and v8::Object::Get() eat up two thirds of the time. The internal implementation is able to use IterateOwnDescriptors(), which seems much faster (and doesn't allocate an array of keys).

-- Philip
Reply all
Reply to author
Forward
0 new messages