채널톡 팀이 기존 오픈소스를 거치지 않고 직접 로컬 DB 동기화 엔진 'hearth'를 만든 여정
네트워크 상태와 무관하게 즉각적으로 로딩되는 '오프라인 퍼스트' 구조는 뛰어난 사용자 경험을 자랑하지만 직접 구축하기는 매우 까다롭습니다. 채널톡 프론트엔드 팀은 무거운 상용 라이브러리 대신 자체 API 서버에 최적화된 Dexie 기반의 경량 동기화 엔진 'hearth'를 완성했습니다. LWW 규칙의 함정, 낙관적 업데이트 방어, 캐시 축출 버그 등을 실전에서 극복하며 다듬어 나간 엔지니어링 스토리를 공유합니다.
IndexedDB를 활용한 로컬 캐싱 고도화, 실시간 동기화 상태 관리, 또는 브라우저 캐시 정합성 설계로 머리를 싸매고 있는 시니어 프론트엔드 개발자분들에게 적극 권장합니다.
네트워크 상태와 무관하게 빠른 속도로 동작하는 오프라인 퍼스트(Local-First) 아키텍처를 도입하려 했으나, 기존의 오픈소스 동기화 엔진(WatermelonDB, RxDB 등)은 자체 백엔드 API와의 연동 시 불필요한 추상화 계층이 발생하여 비효율적이었습니다. 또한, 채널톡의 AI 비서 Drive 기능 등 여러 제품군에서 진입 시마다 스피너가 발생하고 오프라인 동작이 불가한 문제를 공통적으로 겪고 있었습니다.
사내에서 이미 검증되었던 동기화 코드를 추상화하여 Dexie(IndexedDB 래퍼) 기반의 도메인 독립적 사내 라이브러리인 'hearth'를 개발했습니다. hearth는 core 계층(LWW 비교 훅, 필수 캐시 eviction 정책, 전체 생애주기 plugin)과 sync 계층으로 논리적 구조를 분리하고, 서버 동기화는 별도의 pull/push 로직을 설계하여 해결했습니다.
Drive 기능에 도입하여 화면 진입 시 스피너를 완전히 제거하고 지연 없는 극강의 UX와 오프라인 읽기/쓰기를 성공적으로 구현했습니다. 복잡한 로컬 동기화 로직을 라이브러리 내부로 회수하여 개발자가 수동으로 동기화 로직을 다시 작성하지 않고도 여러 제품군에 공통 엔진으로 손쉽게 이식할 수 있는 환경을 마련했습니다.
Trade-off
LWW(Last-Writer-Wins) 규칙으로 인해 데이터 정합성 보장의 책임이 서버로 확장되면서 서버 측 타임스탬프 미갱신 시 변경 사항이 영구히 덮어씌워지는 버그가 발생할 수 있습니다. 또한, 과거 동기화 영수증 기록과 실제 로컬 캐시 데이터의 수명이 일치하지 않아 데이터 유실이 감지되는 설계 결함이 발생하기도 했으며, 네트워크 요청 자체를 줄이는 완전한 Delta Sync 구현은 아직 과제로 남아 있습니다.
사용자의 데이터 조작을 원격 서버가 아닌 로컬 디바이스의 데이터베이스에 우선적으로 기록하고, UI 역시 로컬 데이터를 바탕으로 즉각 변경한 뒤 서버와의 동기화는 백그라운드에서 지연 처리하는 아키텍처 패턴입니다.
분산 데이터 처리 중 동일한 항목에 여러 쓰기 요청이 겹칠 때, 가장 늦은 타임스탬프나 최종 순서 번호를 가진 데이터가 최종적으로 유효하다고 판정하는 가장 직관적이고 널리 쓰이는 충돌 해결 메커니즘입니다.
서버가 성공 응답을 주기 전에 화면에 먼저 반영하는 낙관적 업데이트 도중, 사용자 수정 이전 시점에 생성된 서버 응답이 뒤늦게 오며 사용자의 입력을 덮어써 버리는 레이스 컨디션 오류를 방지하는 장치입니다.