Backend engineer building production systems at scale — film school grad turned engineer, now leading backend at Moba. This blog collects what I've learned along the way.
- Events synced
- 7M
- Essays shipped
- 167
- Polyglot services
- 6
- Bilingual writing
- EN/KR
Work
Arch Calendar
Sole-maintained backend from legacy to public launch — multi-account calendar sync, payments, and real-time updates across 7M events.
visit ↗3B System
Sanitized system map for the 3B agent harness behind this site: layers, subsystems, decisions, and blog-series progress.
system map →Project Crucio
Zero Trust security for generative AI — 6 polyglot microservices (Python + Go + Rust + TypeScript), Kafka event streaming, hash-chained audit, and full LGTM observability on hybrid GCP + NAS infrastructure.
visit ↗
Anthropic Prompt Cache TTL + Cost Mechanics
Anthropic silently dropped Claude Code's prompt-cache TTL from 1 hour to 5 minutes around early March 2026. Without explicit awareness, idle gaps ≥5 min between messages evaporate the cache and force a full cold cache-write on the next message — pricing it at 1.25× base input on the entire conversation prefix.

The pre-commit hook race that put my files in someone else's commit
Two sessions committing to one repo, a slow pre-commit hook, and `fatal: cannot lock ref HEAD`. The loud failure is the easy one — the quiet failure hands your staged files to the other session's commit under its message.

Serena MCP — Multi-Profile Setup for Claude Code (cpers/cwork)
Installing the Serena MCP server across a Claude Code dual-profile setup (cpers/cwork) plus Codex, including the four recommended hooks, the system-prompt override, and the non-obvious "installer writes to default ~/.claude.json, misses profile-specific stores" trap.

Claude Code Agent Teams
Experimental feature for orchestrating multiple Claude Code instances as a coordinated team with shared task lists and inter-agent messaging

Gemini Asymmetric Embeddings
Retrieval gets better when queries and documents are encoded differently. Gemini expressed that with a task_type parameter, and its newer model moved the same idea into the prompt.

BeautifulSoup + lxml memory overhead — why scrapers need size caps
A scraper that fetches a page with httpx and hands the body to BeautifulSoup is an OOM vector, because the parsed tree costs many times the raw HTML size. Streaming plus a two-layer size reject is what I ended up with.

FastAPI Dependency Injection Patterns
How to use Annotated types with FastAPI Depends() for reusable, type-safe dependency injection across routers.

FastAPI domain-exception handler — stopping 500s on your 404s
Domain exceptions raised in the service layer come back as 500s until FastAPI is told otherwise. What I found registering one handler for the whole hierarchy, and the four gotchas a review pass surfaced afterwards.

PostgreSQL IN Clause Parameter Limits
PostgreSQL's wire protocol caps parameterized queries at 65,535 bind parameters. Batching TypeORM's `In([...])` at 500-1,000 stays inside practical performance limits.

Stale vs Orphan Records in Calendar Sync
Google Calendar sync leaves behind two kinds of leftover rows that look identical in the database and need opposite handling.