노트

로컬 퍼스트 아키텍처

Local-First Software

설계#architecture · 연결된 개념 5개

쉽게 말하면

로컬 퍼스트는 할 일을 내 휴대폰 수첩에 먼저 적고, 인터넷이 잡히면 그때 서버에 옮겨 적는 방식이에요. 그래서 지하철에서 신호가 끊겨도 앱이 바로 반응해요.

비유가 깨지는 곳 혼자 쓰는 수첩과 달리 여러 기기와 사람이 같은 데이터를 고쳐요. 그래서 충돌을 합치는 CRDT 같은 장치가 필요하고, 재고 차감처럼 자동 병합이 어려운 규칙에는 맞지 않아요.

클라이언트 기기의 로컬 데이터를 진실의 원천(Source of Truth)으로 삼고, 서버는 동기화와 백업을 맡는 설계 방식. 전통적인 "서버가 원천, 클라이언트는 요청해서 그린다" 구조를 뒤집어 로컬 DB → UI 렌더링 → 백그라운드 동기화 순서로 흐른다.

핵심

  • 읽기·쓰기가 로컬 저장소에서 먼저 일어나 네트워크를 기다리지 않는다. UI가 즉시 반응한다
  • 네트워크가 끊겨도 앱이 동작하고, 다시 연결되면 변경을 동기화한다
  • 여러 기기·사용자가 같은 데이터를 고치므로 충돌 해결이 필수다. 주로 CRDT를 쓴다. 서버가 순서를 중재해야 하는 OT는 오프라인 시나리오에 약하다

기술 요소 (2026 기준)

  • 로컬 저장소: IndexedDB, OPFS(Origin Private File System), WASM(WebAssembly)으로 돌리는 SQLite
  • CRDT 라이브러리: Yjs, Automerge
  • 동기화 엔진: Replicache, ElectricSQL, PowerSync 등

주의할 점

  • 재고 차감처럼 자동 병합이 어려운 업무 규칙이 있다. 실시간 정합성이 절대적인 금융 거래 같은 곳에는 서버 권위 모델이 맞다
  • 브라우저 저장 용량 한계, 첫 접속 때 대량 동기화 비용
  • 민감한 데이터가 기기에 남는 보안 위험

노트 앱, 협업 편집기, 할 일 관리처럼 반응성과 오프라인이 중요한 앱에 잘 맞는다. 결국 각 사본이 언젠가 같은 상태로 수렴한다는 최종 일관성(Eventual Consistency) 모델이다. 서버 상태를 캐시하는 기존 방식(TanStack Query)과 비교해 보면 차이가 분명하다.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 저장소 역할 분담 (DB·캐시·큐·검색)

    서버 애플리케이션 옆에는 거의 늘 관계형 DB, 인메모리 캐시, 메시지 브로커(message broker), 검색 엔진이 붙는다. 하나로 다 하지 않는 이유는 데이터의 성격(영구성·속도·전달·검색)마다 잘하는 도구가 다르기 때문이다.

  • 데이터베이스 다중화

    같은 데이터를 여러 DB 서버에 복제해 두는 것. 가장 흔한 형태는 원본을 가진 주(Primary) 서버가 쓰기를 받고, 사본을 받는 부(Replica) 서버들이 읽기를 나눠 맡는 구조다.

  • 역색인과 검색 엔진

    역색인(inverted index)은 "각 문서에 어떤 단어가 있나" 대신 거꾸로 "이 단어가 어느 문서들에 있나"를 미리 만들어 둔 자료구조다. 책 뒤의 찾아보기와 같다. OpenSearch·Elasticsearch 같은 검색 엔진은 이 구조로 전문 검색(full-text search)을 빠르게 한다.

  • React 서버 컴포넌트(RSC)

    React 서버 컴포넌트(React Server Components, RSC)는 서버에서만 실행되고, 컴포넌트 코드가 아니라 실행 결과(직렬화된 엘리먼트 트리)만 클라이언트로 보내는 컴포넌트다. Next.js App Router에서는 'use client'를 붙이지 않은 컴포넌트가 기본으로 서버 컴포넌트다.

  • DB 인덱스와 트레이드오프

    DB 인덱스는 특정 컬럼 값으로 행을 빨리 찾도록 테이블 옆에 따로 유지하는 보조 자료구조(auxiliary data structure)다. 관계형 DB의 기본 인덱스는 정렬된 균형 트리(B-tree 계열)라서, 전체를 훑지 않고 트리를 따라 내려가 원하는 행에 닿는다.

보기 옵션