Get CV
Back to business cases

SSR

The Node process that kept every locale

Vue SSR rendered Russian and still allocated English and German message files. The isolate grew with every page.

The vue container sat at 700 MB after a quiet morning. No leak in the app code. The SSR entry imported the full i18n JSON for en, ru, and de on every render, then picked one locale. Node kept the other two in the isolate. A long-lived process never gave that back.

The HTML payload repeated the same mistake. Serialized state shipped all three dictionaries so the client could switch language without a navigation. Nobody switched language without a navigation. The extra JSON sat in the document and in the heap.

The problem was one isolate holding every locale for a site that already has locale in the URL. Visitors paid in TTFB and in a fat first document. I needed one message table per request and a recycle when the heap grew.

One request locale. One message table. The other two files stay on disk.
One request locale. One message table. The other two files stay on disk.

What the entry loads now

The SSR server loads messages for the locale on the request, not for the whole site. The client hydrates that table only. A language change hits a new URL and a new document. That is already how the router works.

Import of locale JSON is dynamic. The Node process does not require the other two files on a Russian render. Static copy that never listens to i18n stays in the server render and is not in the hydrate payload.

  • Static regions that never listen to i18n stay server-only.
  • Formatted dates go into the serialized state. The client does not recompute them on mount.
  • The vue process recycles after a memory ceiling, same idea as pm.max_requests on PHP-FPM.

Heap on a warm worker settled near 180 MB. First HTML lost the unused dictionaries. Hydration warnings that came from locale mismatch on dates went with them.

What I took from this

SSR that imports every locale is a leak you scheduled. The isolate does not forget unused JSON.

Client-side language switch without navigation is a product I did not have. Shipping three dictionaries for it was free in the design and expensive in the document.

Recycle the Node process. Long-lived SSR is PHP-FPM without max_requests unless I add a ceiling.

Back to business cases