01
Building an OG Scraping Server in Node.js (2): How SSRF Gets Through
#nodejs#security#ssrf
A feature where the server opens a URL the user handed it has the textbook conditions for SSRF written into its spec. Six ways a whitelist gets bypassed first, then five defensive principles that block them, all actually run on Node. Strip IPv4-mapped by hand and it gets through in hex notation, undici lookup hook is never called when the host is an IP literal, and URL.hostname keeps the brackets on an IPv6 literal. The final post of a two-part design note on OG scraping servers.
2026-08-2225 min Β· read
02
Building an OG Scraping Server in Node.js (1): From Runtime Choice to Error Rate and Latency
#nodejs#web#scraping
The "10% error rate" of a link preview server is a single number that five different kinds of failure got mashed into. This post works out why this workload is I/O bound at that TPS, where runtime choice actually diverges across four points, and then moves on to lowering the error rate with User-Agent and encoding. Node built-in TextDecoder turns CP949 extension characters into different characters without raising an error, and a scraped og:title is not an API response but user input. It also covers cache stampedes, negative caching, and a two-million-run simulation that verifies "P95 under one second" by working backwards from the cache hit rate. The first post of a two-part design note on OG scraping servers.
2026-08-2233 min Β· read
03
Next.js Turbopack Turned One Singleton into Two: A Scope Hoisting Bug and a Circular Import
#turbopack#nextjs#bundler
In a Next.js 16 Turbopack production build, a module-scope singleton became two live instances at runtime. Inside the same synchronous block, one condition contradicted the other, and responses that arrived in 30ms still timed out. This is the record of tracing the cause through the bundle output: a partial scope hoisting merge, a circular import, an upstream bug that had already been fixed, and the single-variable experiment I ran too late.
2026-08-1916 min Β· read
04
Killing Frame Drops in a framer-motion Banner: Two Wrong Turns and One Easing Function
#framer-motion#performance#animation
A banner built with framer-motion made the entire home screen stutter for the 0.6 seconds it took to open. The record of guessing the cause from the code, having that guess overturned twice by measurement, and finally removing the reflow with a single easing function. Plus what the work left behind: the gap between declaration and execution, the principle that properties decide performance, preserving mechanisms, suspecting your instruments first, and proving sameness with a curve.
2026-08-1530 min Β· read
05
Porting number-flow to Old Browsers: Five Decisions and Two Reversals
#javascript#animation#web-animations-api
The minimum versions where number-flow turns animations on are Chrome 125 and Safari 17.2. A record of the decisions made while building a fork that lowers this floor to Chrome 66 and WebKit 16.4, the two judgment calls I ended up reversing, and the Safari bug investigation that made me give up on automatic downgrading.
2026-08-1125 min Β· read
06
Autoscaling Is Automatic but Not Instant: HPA's Timeline, Measured Segment by Segment
#kubernetes#autoscaling#nextjs
Raise traffic 12x and it takes 31.5 seconds for a new pod to receive its first request. I pulled an itemized bill for those 31.5 seconds with a stopwatch: the structure dominated by the detection window, the conditions under which the autoscaler goes blind in the five minutes right after a deploy, the scale-down staircase, why memory-based HPA misfires on Node, and KEDA's preemptive scaling. Part 5 of the Kubernetes for frontend developers series.
2026-08-1025 min Β· read
07
How Do Pods Terminate? Measuring the Causes and Fixes of Deploy-Time Errors
#kubernetes#nextjs#nodejs
Even a deploy that changes not a single line of code leaks errors. This is a measured record of tagging every failure that leaks during rolling deploys by type and timestamp, performing an autopsy on four causes, and stacking prescriptions one layer at a time until the count reaches zero. Includes the actual Next.js shutdown code, hostage draining, and the real CrashLoopBackOff timetable. Part 4 of the Kubernetes for frontend developers series.
2026-08-0820 min Β· read
08
How Does Traffic Reach My Pod? From ClusterIP to port-forward
#kubernetes#networking#nextjs
A Service's ClusterIP is an IP attached to no machine, yet curl reaches it. iptables rules and conntrack, EndpointSlice, cluster DNS and ndots, Gateway, and port-forward: a record of opening up the entire path a request takes to a pod, directly in a kind cluster. Part 3 of the Kubernetes for frontend developers series.
2026-08-0627 min Β· read