
로컬 퍼스트 아키텍처, 연구에서 프로덕션으로 — 동기화 엔진 4종 비교
데이터를 사용자 기기에 먼저 저장하고 백그라운드로 동기화하는 로컬 퍼스트 아키텍처가 연구 단계를 지나 프로덕션에 들어왔다. 오프라인에서도 즉시 동작하는 앱을 만드는 PowerSync·ElectricSQL·Zero·Triplit의 출발점 차이와, 국내 팀이 이 구조를 고를 때 따져야 할 트레이드오프를 짚었다.
비행기 모드로 노션을 켜본 적 있다면 안다. 글은 그대로 써지고, 착륙해서 와이파이가 잡히면 알아서 합쳐진다.
이게 마법이 아니라 아키텍처라는 것, 그리고 그 아키텍처를 이제 npm install 한 줄로 시작할 수 있다는 것. 뒤쪽 이야기를 아는 개발자는 아직 많지 않다.

로컬 퍼스트(Local-first)는 2019년 Ink & Switch 연구소가 발표한 에세이에서 출발했다. 그동안은 "이론적으로는 아름다운데 직접 만들기엔 부담스러운" 쪽에 가까웠다. 그 평가가 최근 1~2년 사이에 뒤집혔다.
서버가 아니라 내 기기가 원본이다
구조는 한 문장으로 끝난다. 데이터를 서버가 아니라 사용자 기기의 로컬 저장소에 먼저 쓴다. 클라이언트 SQLite, 브라우저라면 IndexedDB 같은 곳이다. 서버와의 동기화는 그다음에, 백그라운드에서 조용히 일어난다.
순서 하나 바꿨을 뿐인데 결과가 셋이나 딸려 온다.
- 네트워크가 끊겨도 앱이 그대로 동작한다.
- UI가 서버 왕복을 기다리지 않는다. 누르면 그 자리에서 반응한다.
- 여러 명이 동시에 편집하는 상황이 예외 처리가 아니라 기본값이 된다.
세 번째가 진짜다. 협업 기능을 나중에 얹으려다 아키텍처를 갈아엎어 본 팀이라면 무슨 말인지 안다.
연구 프로젝트에서 npm install 로
지난 몇 년 사이 세 가지가 동시에 자리를 잡았다.
CRDT(Conflict-free Replicated Data Type, 충돌 없이 병합되는 자료구조)가 성숙했다. Automerge는 3.0에 도달했고, Yjs는 이미 여러 협업 에디터의 밑바닥을 떠받치고 있다. 두 사람이 같은 문장을 동시에 고쳤을 때 "누가 이겼는지" 묻지 않고 합쳐지는 그 부분 — 이제 직접 구현하지 않아도 된다.
여기에 SQLite를 로컬 저장소로 삼는 동기화 엔진이 등장했고, 그걸 앱 개발자가 쓸 수 있게 감싼 전용 프레임워크가 나왔다.
문서와 추상화가 갖춰졌다는 게 핵심이다. 로컬 퍼스트 앱을 만드는 데 드는 노력이 전통적인 클라이언트-서버 앱을 만드는 것과 비슷한 수준까지 내려왔다는 뜻이니까.
동기화 엔진 4종, 출발점이 다르다

이름만 나열하면 다 비슷해 보이지만, 각자 상정하는 팀이 다르다.
| 엔진 | 어떤 팀에 맞나 | 성격 |
|---|---|---|
| PowerSync | 이미 Postgres·MongoDB·MySQL을 쓰는 팀 | 서버 데이터의 일부(subset) 만 클라이언트 로컬 SQLite로 내려보낸다. 넷 중 가장 프로덕션 레디로 꼽힌다. |
| ElectricSQL | Postgres를 쓰는 팀 | Postgres 전용. Postgres ↔ 클라이언트 SQLite 액티브-액티브 동기화. |
| Zero | 협업 앱을 처음부터 새로 만드는 팀 | 기존 DB에 얹기보다 새 제품에 맞춰 설계됐다. |
| Triplit | 협업 앱을 처음부터 새로 만드는 팀 | Zero와 같은 결. 신규 프로젝트 전제. |
TanStack DB 같은 이름도 같은 범주에서 언급된다.
갈림길은 단순하다. 이미 굴러가는 백엔드가 있느냐다. 운영 중인 Postgres에 로컬 퍼스트를 얹고 싶다면 PowerSync·ElectricSQL 쪽이고, 백지에서 협업 앱을 그리는 중이라면 Zero·Triplit이 상정하는 세계에 가깝다.
정답은 하나가 아니다
최선의 아키텍처는 데이터 형태, 협업이 실제로 필요한지, 일관성을 얼마나 강하게 요구하는지, 타깃 플랫폼이 무엇인지에 따라 갈린다. 이건 여전히 그대로다.
달라진 건 다른 지점이다. 이 접근들이 전부 프로덕션에 올릴 만큼 성숙했다는 것. "어느 쪽이 승자냐"가 아니라 "이제 골라 쓸 수 있다"가 지금의 변화다.
곁가지로 하나. SQLite는 로컬 저장소로만 뜨는 중이 아니다. 서버와 엣지 쪽에서도 존재감이 커졌다 — Turso/libSQL, Cloudflare D1, Fly.io LiteFS가 대표적이다. 엣지에 데이터를 두면 중앙 DB를 왕복할 때보다 지연이 크게 준다는 보고가 있다. 읽기 기준 30~80ms 하던 것이 10ms 미만으로 내려가고, 로컬 리플리카를 쓰면 더 짧아진다. 방향은 로컬 퍼스트와 같다. 데이터를 쓰는 쪽 가까이로 내리는 것.
그래서, 우리 팀은?
왜 하필 지금이냐는 질문에는 사용자 기대치로 답하는 게 정확하다. 노션에서 글자를 치면 바로 뜨고, 피그마에서 남이 옮긴 도형이 실시간으로 따라 움직이고, 리니어에서 이슈 상태를 바꿔도 로딩 스피너를 볼 일이 없다. 이런 경험이 '잘 만든 앱'이 아니라 '기본'이 됐다. 문제는 그걸 전통적인 요청-응답 구조로 흉내 내려면 낙관적 업데이트와 롤백, 재시도, 캐시 무효화를 앱마다 손으로 다시 짜야 한다는 것이다. 로컬 퍼스트는 그 부담을 우회하는 대신 정면에서 아키텍처로 가져간다.
물론 공짜는 아니다. 충돌 해결 규칙을 CRDT 위에서 설계해야 하고, 서버 데이터 중 무엇을 어디까지 내려보낼지 부분 동기화 규칙을 직접 정해야 한다. 동기화 계층 자체가 새로 생기는 복잡도이고, 보안 모델도 달라진다. 데이터가 화면에 '보이는' 정도가 아니라 사용자 기기에 실제로 존재하기 때문이다. 결제나 재고처럼 중앙 권위와 강한 일관성이 필요한 도메인이라면 이 구조는 애초에 답이 아니다. 잔고를 클라이언트에서 낙관적으로 더하는 앱을 상상해 보면 이유는 설명이 필요 없다.
국내 팀 기준으로 선을 긋자면 이렇게 된다. 실시간 협업이나 오프라인 동작이 제품의 핵심 가치라면 — 에디터류, 현장·필드 업무 앱, 모바일 비중이 큰 서비스 — 지금 검토할 값어치가 충분하다. 반대로 대부분의 CRUD 대시보드나 사내 관리도구라면 전통적인 아키텍처가 여전히 더 단순하고 더 옳다. 유행한다고 전부 갈아탈 이유는 없고, 로컬 퍼스트 진영도 그렇게 주장한 적 없다.
2019년의 에세이가 손에 잡히는 프레임워크가 되기까지 7년쯤 걸렸다. 질문은 이제 "가능한가"에서 "우리 제품에 필요한가"로 넘어왔다.
지금 만들고 있는 앱에서 오프라인 동작과 실시간 협업은 '있으면 좋은 것'인가, '없으면 안 되는 것'인가. 그 한 줄이 이 아키텍처를 검토할지 말지를 가른다. 어느 쪽인지 댓글로 듣고 싶다.
📎 출처: 원문 보기
- inkandswitch.comhttps://www.inkandswitch.com/local-first/
댓글 0
댓글을 불러오는 중…






