How I found a 32x performance bug hiding in a UTF-8 decoder
Last week I was profiling a Node.js service that processes large JSON-RPC responses. Three concurrent 18.7 MB responses crashed the process with an out-of-memory error — on a machine with 1 GB of heap. The culprit wasn't the JSON parser. It was the UTF-8 decoder that ran before JSON.parse ever saw the data. The setup The service fetches binary response bodies as Uint8Array and converts them to…
A developer discovered a performance bug in a UTF-8 decoder used by a Node.js service processing large JSON-RPC responses. The custom decoder, which converted binary response bodies to strings before parsing, created intermediate arrays of code points and then converted those to strings, leading to significant memory usage and processing slowdown.
The native TextDecoder API, which handles UTF-8 decoding directly, was identified as a more efficient alternative. By swapping the custom decoder for the native TextDecoder, the developer reduced processing time from 928ms to 31ms and memory usage from 794MB to 62MB, even when processing three concurrent 18.7MB responses. The issue underscores the importance of considering the allocation patterns and performance implications of custom implementations versus native APIs, especially for large-scale applications.
The developer submitted a pull request implementing the fix, which passed all existing tests and eliminated OOM crashes while maintaining the same error behavior.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — it may contain errors, so check the original before relying on it.