Dev blog by Jaeyong Choi (jaeyonging), a frontend and full-stack developer. I write about web development with React, TypeScript and Node.js, the sites I built myself, and my project notes.
100 days of a monitoring server I built myself: what I did well and what needs fixing
I went back through the records of 270,000 checks. Checking the public domain was a good call. Self-monitoring, sequential checks, endless history and tokens in logs need fixing.
My health check recorded for 3 months and never told anyone
31 failures piled up with 0 alerts. Alerting on every failure meant 58 emails, 2 in a row meant 4. I counted from the records first, then added alerts on state change.
I deleted the guest login and built a status page
I kept adding guest permission branches to show people my dashboard, then saw the only thing worth showing was "is it alive" and built a separate public status page.
PM2 revived my apps so well that I couldn't see the outages
The health check kept returning 200 while the restart count sat at 96. Why crash loops should be judged by the increase within a window, not the cumulative total.
I almost added Redis, measured first, and didn't. The real culprit was a cache header
A server with a 6ms TTFB didn't need a cache layer. I just hadn't known that FilesMatch doesn't apply to proxied responses.
I built it in a glass style and mobile dropped to 20fps
My glass-style portfolio fell to 20fps on mobile. I throttled the CPU, measured frame intervals, found background blur, hidden badges and card backdrop-filter, and got 60fps back.
One bundle was 700KB. The criteria I set while splitting it with Vite manualChunks
How I decided what goes into which chunk when splitting a 700KB bundle with Vite manualChunks, and when I use lazy and when I don't.
One of my projects uses Zustand and another uses Redux. Why did the same person pick differently?
How I chose between Redux Toolkit, Zustand and React Query differently depending on the kind of project.
Two exchange WebSockets at once killed my screen. Batching dispatch with requestAnimationFrame
How I batched prices arriving at hundreds of messages per second using a Map queue and rAF, and the alternatives I didn't pick.
My straight-line trip itinerary was off from real roads by 2 hours 28 minutes
An itinerary built on straight-line distance was 148 minutes off real road times. I switched to Kakao directions with a coordinate cache, estimate fallback and days split by area.