Blog
Notes & writing
12 posts on backend architecture, production systems, and applied AI.
The lock contention that wasn't in the query plan
Up to a thousand concurrent Go workers, each upserting its own user's rows in MySQL — and InnoDB kept detecting deadlocks between them. The gap-lock mechanics, the fix menu ranked, and the deliberately boring choice.
ReadThe push pipeline that didn't get blocked
Notification campaigns as scheduled batch jobs: eligibility and dedup pushed into the audience query, a send log that doubles as the resume checkpoint, throttling against platform quotas — and the two gates I'd add today.
ReadDesign your logs like an API
Business questions answered from CloudWatch Logs Insights: log-line contracts, why enriching an existing line beats adding a new one, JSON-escaping gotchas, and the retention trap.
ReadBuilding a product where the UI is a chat thread
LIFF token verification, Flex Message carousels, rich menus, and chatbot flows as routing — chat-platform engineering as a backend discipline.
ReadServing ML recommendations inside a LINE mini-app
The architecture behind a property-search platform delivered entirely through LINE — Go backend, LIFF mini-apps, an XGBoost inference service, and the batch pipelines that keep recommendations fresh.
ReadMulti-region DR you actually rehearse
Tokyo primary, Osaka standby, one Terraform module set: what to replicate, what to rehearse, and why an untested failover plan is a diagram, not a capability.
ReadHexagonal architecture inside Lambda, with code
How fifty-plus TypeScript Lambda functions stayed testable and consistent: ten-line handlers, ports and adapters, and one use case serving API, queue, and batch entrypoints.
ReadServerless in production: lessons from an enterprise AWS platform
Fifty-plus Lambda functions, hexagonal architecture, SQS-driven batch pipelines, and multi-region DR on AWS — the structure, queue design, and operational decisions behind an enterprise serverless platform.
ReadWhen a goroutine is the wrong tool
A production postmortem on Go context cancellation: a fire-and-forget cache write inherited the request's context and died with it — the diagnosis, the reverted first fix, and the boring final one.
ReadService-to-service auth without a service mesh
A sidecar proxy pattern on Cloud Run: ingress authentication, egress through a central internal API hub, and an internal load balancer doing the routing — mesh benefits without mesh weight.
ReadOne interface, four ways to pay
Card with 3DS, wallet, convenience store, and direct debit behind a single internal service — how a payment gateway abstraction keeps a provider's quirks out of your order flow.
ReadEvent-driven microservices without losing events: the transactional outbox in practice
How we kept orders, payments, and downstream services consistent on Cloud Run and Spanner using the transactional outbox pattern and task-queue relay workers — and what we'd do differently.
Read