DevInsight

A developer's field notes

DevInsight Archive

전체 글

최근 발행한 분석과 실무 기술 글을 시간순으로 모았습니다.

Frontend

One 'use client' Line Splits Server and Client, and Shakes Everything From Bundle Size to State Management

In the Next.js App Router, a single 'use client' line that draws the server-client boundary reshapes your entire bundle size, data fetching, and state management strategy. Draw that boundary wrong and bundle bloat plus duplicate fetching blow up all at once, late in the game. This memo lays out the judgment principles for redrawing the boundary based on per-layer responsibilities and data ownership, plus the priority order for refactoring boundaries that were already drawn wrong.

#React#Next.js#Server Components#Client Components
Backend

Don't Trust Webhooks, Verify with Signatures

Webhook receivers must be designed with distrust of external requests. Since requests can be unstable — with retries, processing delays, and even forgery attempts — signature verification, idempotent processing, retry ID tracking, and queuing for delays are all essential for stable ingestion. Particularly, retries arriving without idempotency keys lead to duplicate processing; when delays grow too long, immediately switch to queue locking.

#webhook#signature-verification#idempotency#retry-handling
DevOps

Cache hit rate is 98%, so why does the release keep shipping an old version?

Dependency caches, build caches, and matrix strategies cut CI runtime in half, but when invalidation criteria are set wrong, stale packages sail through builds and turn into unexpected incidents. This article walks through concrete situations where a cache actually breaks a build, and lays out principles for reading invalidation points correctly in lock files, hash inputs, and matrix key design, so you have a safe standard for using caches.

#GitHub Actions#CI/CD#캐시 전략#빌드 최적화
Data

Reading the Signs in EXPLAIN: When Queries Ignore Your Indexes

Even with an index in place, seeing a full scan in EXPLAIN is common. Four patterns sever the link between a query and its index: function-wrapped columns, type mismatches, leading wildcards in LIKE, and low selectivity. This post is a decision memo that walks through each pattern with real examples of how it distorts the execution plan, and lays out a procedure for narrowing down and fixing the cause, from reading EXPLAIN to confirming the root cause.

#PostgreSQL#EXPLAIN#인덱스#풀스캔
Frontend

The Page Is Already Shifting Before the Font Even Shows

Korean web fonts carry large per-glyph payloads that delay loading, and the later a font arrives, the worse the CLS metric swings. This article walks through subsetting glyphs, nailing down preload timing, and choosing a font-display strategy with real numbers. It separates what Next.js's next/font handles from what it doesn't, and shows how to design a font pipeline that keeps text rendering stable without blowing the performance budget.

#웹 폰트#CLS#Core Web Vitals#Next.js
Tools

The Struggle of One Project's Upgrade from `any` Hell to `strict`

Suddenly enabling `strict` in a loosely-typed TypeScript project makes hundreds of errors pour out overnight. This article is a real migration log about enabling strict-family options one by one amid new feature development and bug fixes, weighing the difficulty and effect of each option to work out an optimal ordering. It covers everything from the `any` cleanup order to `strictNullChecks` and `noImplicitAny`, along with the real-world outages and regressions encountered along the way.

#TypeScript#strict#strictNullChecks#noImplicitAny
DevOps

200 OK doesn't protect your zero-downtime deployment

Zero-downtime deployments don't fail the moment a server goes down—they fail the moment a health check returns a perfunctory 200. Traffic rushes to an unprepared new version, and the outage only explodes after the deployment is finished. This covers how to tie readiness and liveness to the actual state of dependencies like databases, Redis, and message queues, check intervals that cut detection latency, and the criteria for deciding when to roll back.

#무중단배포#헬스체크#롤링배포#블루그린배포
AI

Why Finer Chunking Takes the Answer Further Away

Chunk size and the splitting criterion alone determine the quality of the embedding vectors. Cut wrong and similarity search returns only half-finished fragments with broken context, shattering the correct answer — but splitting larger doesn't fix it either. This article examines the mechanics behind common splitting mistakes and lays out practical evaluation metrics that look at search recall and response completeness together. It's structured so candidate chunk validation, context retrieval strategies, and per-criterion experiment methods can be applied directly to your pipeline.

#RAG#청크 분할#임베딩#벡터 검색
Tools

Only after deleting node_modules twice did I take another look at package managers

Choosing a package manager is a balancing act between three axes: install speed, disk usage, and phantom dependencies. In a standalone repo, even a careless choice rarely causes problems, but once you move to a monorepo, differences in hoisting strategies show up directly as CI time and disk blowups. This compares how npm, pnpm, and yarn each store and share dependencies, and lays out a decision flow for choosing a tool based on real conditions like team size and monorepo maturity.

#패키지매니저#pnpm#npm#yarn
AI

Why the Screen Shatters While Tokens Flow

When an LLM response streams token by token over SSE and is painted to the screen, markdown syntax breaks midway, abort requests don't propagate properly, and rendering stutters on every token. This article walks through the real failures you hit in streaming UI—markdown parsing collapse, abort handling and error recovery, and rendering performance problems—in the order they break, then lays out proven fixes like partial rendering and a backpressure approach that minimizes buffer accumulation.

#SSE#스트리밍#LLM#마크다운 파싱