sewon.dev
givemethatsewon profile
@givemethatsewon
프로젝트를 만들고 운영하면서 배운 개발, 제품, 디버깅 기록을 남깁니다.

벡터 검색을 앞두고 SQLite에서 PostgreSQL + pgvector로 옮긴 이유

July 15, 2026

일기 서비스에 “비슷한 기록 보여주기”를 넣으려 했다. 같은 단어가 있는 글이 아니라 문맥과 감정이 닮은 과거 일기를 찾는 기능이다. 텍스트를 임베딩으로 바꾸고, 벡터를 저장한 뒤 가까운 기록을 찾는 흐름이 필요했다. 처음에는 SQLite는 그대로 두고 벡터 데이터베이스만 따로 붙이는 방법을 검토했다. 그런데 원문은 한 저장소, 임베딩은 다른 저장소에 두…


Localization 502를 Top-Down으로 좁힌 기록

July 07, 2026

Place2Page에서 localization을 생성하다가 버튼이 오래 돌고 실패하는 문제가 있었다. 처음에는 번역 모델이 실패했거나 backend에서 예외가 난 것처럼 보였다. 그런데 에러 파일을 열어보니 앱이 만든 JSON 에러가 아니었다. Cloudflare가 내려준 HTML 페이지였다. 가볍게 풀어 쓰면 이렇다. 브라우저에서 Cloudflare까…


DB가 느린 게 아니라 HTML blob을 너무 많이 읽고 있었다

July 07, 2026

Place2Page 공개 랜딩 몇 개가 갑자기 느려졌다. 로그만 보면 데이터베이스가 전반적으로 무거워진 것처럼 보였다. 같은 시각에 하나가 24-27초씩 걸렸고 slow query warning은 0.8-2.1초 단위로 여러 번 찍혔다. 처음에는 인덱스부터 봤다. 그런데 로그를 다시 보니 row를 찾는 과정만으로는 설명이 부족했다. locale 목록만…


운영 트래픽을 제품 지표에서 빼는 analytics wrapper

June 30, 2026

제품 지표를 보기 시작하면 가장 먼저 부딪히는 문제가 있다. 숫자는 찍히는데, 그 숫자가 고객 행동인지 테스트 행동인지 헷갈린다. Place2Page의 분석 환경을 정리하면서 GA4, Mixpanel, Search Console도 같이 정리했다. 이때 제품 분석에 넣을 트래픽과 제외할 트래픽을 먼저 나눠야 했다. 특히 초기 제품에서는 트래픽 모수가 작아…


소개팅 앱의 추천 점수를 궁합 점수 하나로 두지 않은 이유

June 24, 2026

이번 구현에서 가장 먼저 분리한 것은 사용자에게 보여주는 궁합 점수와 실제 추천 순서를 정하는 내부 랭킹 점수였다. 소개팅 앱의 라운지에서는 궁합 점수가 높다고 무조건 먼저 보여주면 안 된다. 사용자가 그 사람을 마음에 들어 할 가능성도 중요하지만, 상대가 다시 반응할 가능성도 함께 봐야 하기 때문이다. 예를 들어 거리가 멀면 추천 순서는 낮출 수 있다.…


Validation Error를 장애로 만들지 않기

June 14, 2026

Sentry에는 저장 화면에서 발생한 unresolved issue가 남아 있었다. 저장 중 가 global unhandled rejection으로 잡힌 케이스였다. 처음에는 단순히 "저장 API가 실패했다"처럼 보였다. 하지만 문제의 핵심은 API validation 자체가 아니었다. 사용자가 복구할 수 있는 저장 실패가 UI에서 toast로 처리된 뒤…


프로젝트 목록 DB 조회를 47배 빠르게 만든 projection

June 08, 2026

Place2Page의 프로젝트 대시보드는 로그인한 사용자가 자주 지나가는 기본 경로다. 이 화면은 를 호출해서 프로젝트 목록을 가져온다. Sentry에서 이 경로를 보다가 이상한 신호를 봤다. 최근 24시간 기준으로는 DB span p95가 한 자릿수 ms였고 장애라고 부를 정도는 아니었다. 하지만 기간을 30일로 넓히자 과거 조회에서 row 전체를 …


서버 앱에 Google Analytics MCP를 붙이며 OAuth와 서비스 계정 구분하기

June 07, 2026

서버 애플리케이션에 Google Analytics MCP를 붙이려다 생각보다 오래 헤맸다. MCP 서버 설치 자체는 어렵지 않았다. 문제는 그 다음이었다. 서버 런타임이 어떤 credential을 봐야 하는지, 왜 브라우저에서 OAuth 앱이 막히는지, service account를 GA4 사용자로 넣으면 왜 안 되는지 계속 섞였다. 최종적으로 "내가 볼…


Growth OS의 GA fetch를 cron에서 self-healing cache로 바꾼 이유

June 04, 2026

Growth 관련 정보를 한곳에서 보려고 내부 지표 화면을 만들기 시작했다. 일반적인 서버처럼 DB 정보를 쿼리하는 작업이 아니라 Google Analytics, Mixpanel, Google Search Console 같은 외부 source에서 정보를 가져와 합치는 일이어서 생각보다 많이 헤맸다. 그 과정을 기록해둔다. 기획은 노션에 있고, 실제 고객 …


Cloudflare Tunnel 장애에서 배운 계층화 디버깅

June 03, 2026

백엔드 개발자는 보통 7계층에서 산다. API path, status code, request header, CORS를 본다. 나도 Cloudflare로 stage API를 붙였을 때 브라우저의 를 보고 곧바로 redirect와 CORS를 의심했다. 그런데 Cloudflare Tunnel이 끼면 한 계층에서 바로 이름 붙일 수 없다. TLS 문제처럼 보일…