Day job (Software Tech Lead, Oizom) / 2025

1 million+ sensor readings in Node.js on a 2 GB server

The backend ran out of memory on large sensor queries. I replaced millions of JSON objects with one typed-array table behind a small class, so the rest of the code never sees the buffers.

Diagram: a million JSON objects replaced by one Float64Array table of times by gases plus a string dictionary, read through one class.
Diagram: a million JSON objects replaced by one Float64Array table of times by gases plus a string dictionary, read through one class.

Result

  • Out-of-memory crashes on a 2 GB droplet stopped; memory graph stayed flat
  • Loading a million points became faster than JSON.parse on the same data
  • Roughly 400% gain on the load-and-serve path vs the JSON version, same box

Stack

Node.jsTypeScriptFloat64Array / Int32ArrayArrayBuffer

Built at my day job, where I lead the software team behind the Envizom platform. The code belongs to the company; this write-up comes from my public blog post.

The problem

Every sensor reading was a plain object with a map of gas values. Reports asked for millions of them at once, and the backend, on a DigitalOcean droplet with 2 GB of RAM, kept dying with out-of-memory errors on exactly those queries. A million small objects in V8 means a million allocations, pointer chasing on every property read and a garbage collector that never catches up.

What I built

  • Treat the data as an image. One Float64Array for all decimal values (rows are times, columns are gases) and one Int32Array holding indexes into a dictionary of unique strings, so a repeated label is stored once. One allocation for the whole table.
  • One class on top. A report asks for a row and gets [gas, value] pairs; nothing else in the codebase touches the buffers.
  • Version two. The first version was correct and 8x slower than JSON, because it kept rows in order on every insert. Tracking free rows instead fixed it.
  • No JSON on the wire. Database rows go straight into the table, the buffer goes to the browser as is, and the frontend rebuilds the same class.

Result

The memory graph stayed flat where the JSON version fell over, loading a million points became faster than JSON.parse on the equivalent array, and the load-and-serve path measured roughly a 400% gain against the JSON version on the same box.

Read more




You have requested the PDF version of this page!
This page was not designed or optimized for your request.


You have a redirct option for your expected request:



  1. Checkout the PDF version: https://firebasestorage.googleapis.com/v0/b/panth-personal.firebasestorage.app/o/portfolio%2FPanth-Patel-Resume.pdf?alt=media



  2. Back to website: https://panth.vardayinitech.in/