인터넷이 끊기면 먹통이 되는 앱, 저장 버튼을 누르지 않으면 불안한 앱. 우리가 익숙해진 이 불편이 사실은 당연한 게 아니라는 문제 제기가 로컬 퍼스트(Local-first) 소프트웨어다. 그리고 이걸 현실로 만드는 기술적 심장이 CRDT라는 자료구조와 동기화 엔진이다.
로컬 퍼스트는 데이터를 서버가 아니라 사용자 기기에 먼저 두고, 서버는 여러 기기 사이를 잇는 동기화 통로로만 쓰는 설계 철학이다. 네트워크가 없어도 앱은 온전히 동작하고, 연결이 돌아오면 그동안의 변경이 조용히 합쳐진다. 저장이라는 개념 자체가 사라진다.
데이터의 주인을 서버에서 사용자 기기로 되돌리는 설계.
CRDT는 충돌 없는 병합을 수학적으로 보장한다.
오프라인에서도 멈추지 않고, 여러 기기의 변경이 서버의 심판 없이도 자동으로 하나가 되는 협업 앱의 토대다.
오프라인 연결 없이도 완전 동작 |
즉시반응 서버 왕복 없는 즉각 UI |
자동병합 충돌 없이 수렴 보장 |
소유권 데이터가 내 기기에 |
왜 이 이야기가 나왔나
지금 대부분의 앱은 서버 중심이다. 내가 문서에 한 글자를 쳐도 그 변경은 서버로 올라갔다 내려와야 화면에 확정된다. 네트워크가 느리면 반응이 굼뜨고, 끊기면 아무것도 못 한다. 서버가 데이터의 진짜 주인이고, 내 기기는 그저 창구다. 실시간 협업 앱들이 이 방식으로 훌륭한 경험을 만들어 냈지만, 그 이면엔 항상 연결에 대한 의존이 있었다.
로컬 퍼스트는 이 관계를 뒤집자고 제안한다. 데이터의 원본은 내 기기에 있다. 그래서 앱은 네트워크 상태와 무관하게 언제나 즉각 반응한다. 서버는 사라진 게 아니라 역할이 바뀌었다. 진실의 원천이 아니라, 여러 기기의 사본을 오가며 변경을 실어 나르는 우체국이 된다. 나는 이 관점 전환이 성능 최적화 이상의 의미를 갖는다고 본다. 소프트웨어에 대한 통제권이 사용자에게 돌아오기 때문이다.
CRDT: 충돌 없는 병합의 원리
여기서 어려운 질문이 생긴다. 두 사람이 동시에, 각자 오프라인 상태에서 같은 문서를 고쳤다면? 나중에 연결됐을 때 이 둘을 어떻게 합치나. 전통적 방식은 서버가 심판이 되어 "누가 이겼는지"를 정하거나, 사용자에게 충돌을 떠넘겨 수동으로 해결하게 했다.
CRDT(Conflict-free Replicated Data Type)는 다른 길을 간다. 자료구조 자체를 어떤 순서로 병합해도 결국 같은 결과에 도달하도록 수학적으로 설계한다. 각 변경에 고유한 정체성과 시간 정보를 심어, 서로 다른 기기에서 제멋대로 일어난 변경들을 규칙에 따라 자동으로 하나로 수렴시킨다. 중앙의 심판이 필요 없다. 어느 기기든 같은 변경 집합을 받으면 반드시 같은 최종 상태가 된다.
기기A: [문서] + "안녕" 삽입
기기B: [문서] + "!" 삽입 (동시, 오프라인)
연결 후 → 두 변경이 규칙대로 병합, 양쪽 동일 결과
이 성질 덕분에 병합에 서버의 개입이 필요 없고, 심지어 기기끼리 직접 변경을 주고받아도 일관성이 유지된다. 협업 편집기가 여러 커서를 매끄럽게 다루는 마법의 상당 부분이 이 원리 위에 서 있다.
동기화 엔진의 부상
최근의 변화는 이 어려운 CRDT를 개발자가 직접 구현하지 않아도 되게 해 주는 동기화 엔진들이 늘고 있다는 점이다. 이들은 로컬 저장, 변경 추적, 병합, 서버 동기화를 한 묶음으로 제공한다. 개발자는 마치 로컬 데이터를 다루듯 코드를 짜고, 나머지 동기화는 엔진이 알아서 처리한다. 로컬 퍼스트의 진입 장벽이 이 도구들 덕에 눈에 띄게 낮아졌다.
| 항목 | 로컬 퍼스트 | 서버 중심 |
|---|---|---|
| 데이터 원본 | 사용자 기기 | 서버 |
| 오프라인 | 완전 동작 | 기능 제한/중단 |
| UI 반응 | 즉각(로컬) | 서버 왕복 대기 |
| 충돌 처리 | 자동 수렴 | 서버 판정/수동 |
모든 앱을 위한 건 아니다
냉정히 보면 로컬 퍼스트가 모든 문제에 맞는 답은 아니다. CRDT는 병합 이력을 담느라 데이터가 커지는 경향이 있고, 강한 일관성이나 중앙의 권한 통제가 꼭 필요한 도메인, 예컨대 금융 거래나 재고 차감 같은 곳엔 오히려 서버 중심 모델이 맞는다. 접근 권한 관리도 데이터가 기기마다 흩어지면 더 까다로워진다.
그럼에도 방향은 흥미롭다. 노트, 문서, 할 일, 디자인 도구처럼 개인의 창작물을 다루는 앱에서 로컬 퍼스트는 즉각적인 반응성, 오프라인 자립, 진짜 협업을 한꺼번에 준다. 나는 앞으로 "이 앱은 인터넷이 없으면 왜 안 되지?"라는 질문을 던지는 사용자가 늘어날 거라 본다. 그 질문에 답하려는 시도가 로컬 퍼스트다.
자주 묻는 질문
로컬 퍼스트 앱에는 서버가 아예 없나요?
있다. 다만 역할이 다르다. 데이터의 진실을 쥔 주인이 아니라, 여러 기기 사이에서 변경을 실어 나르고 백업을 맡는 동기화 통로 역할을 한다.
CRDT가 충돌을 없애 준다는 게 정말인가요?
병합 결과가 항상 하나로 수렴하도록 자료구조를 설계한다는 뜻이다. 데이터 구조 수준의 충돌은 자동 해소되지만, 서로 상반된 의도를 담은 편집처럼 의미적 판단이 필요한 부분까지 대신 결정해 주지는 않는다.
동기화 엔진을 쓰면 CRDT를 몰라도 되나요?
대체로 그렇다. 동기화 엔진이 병합과 저장, 서버 통신을 감춰 주므로 개발자는 로컬 데이터를 다루듯 작업할 수 있다. 다만 데이터 크기나 병합 특성을 이해하면 설계에 도움이 된다.
어떤 앱에 특히 잘 맞나요?
노트, 문서, 할 일 관리, 디자인 도구처럼 개인 창작물을 다루고 협업이 중요한 앱에 잘 맞는다. 반대로 강한 일관성과 중앙 통제가 필수인 금융, 재고 관리 같은 도메인에는 서버 중심 모델이 더 적합하다.

댓글 0