SQLite만으로 내구성 있는 워크플로를 구현할 수 있음
(obeli.sk)- 내구 실행의 핵심은 인프라 자체가 아니라 워크플로 상태 보존이며, 진행 상태가 남아 있으면 재실행과 복구가 가능함
- Obelisk는 워크플로 진행을 실행 로그에 저장하고 지속된 이력에서 재생하며, 활동 재시도에 맞춘 구조를 가짐
- SQLite는 별도 데이터베이스 서비스, 네트워크 홉, 추가 제어 평면 없이 로컬 파일로 트랜잭션 기반 내구 상태를 제공함
- Litestream은 SQLite 변경 사항을 S3 호환 객체 스토리지로 비동기 스트리밍하지만, 복사 전 볼륨이 사라지면 최신 쓰기를 잃을 수 있음
- Obelisk는 Postgres도 지원하며, 더 높은 가용성·공유 확장성·네트워크 데이터베이스 특성이 필요할 때 더 적합함
SQLite와 Litestream 운영 모델
- Litestream은 SQLite 변경 사항을 S3 호환 객체 스토리지로 비동기 스트리밍할 수 있음
- 실행 환경 가까이에 작업 상태를 두면서도, 백업·마이그레이션·검사용으로 데이터베이스를 외부에 복사할 수 있음
- 비동기 복제 특성상 SQLite 볼륨이 복사 전에 사라지면 복원 시 최신 로컬 쓰기를 잃을 수 있음
- Obelisk 서버를 SQLite 데이터베이스와 함께 실행하고 Litestream으로 백업하며, 필요할 때 관찰자가 필요한 데이터베이스를 가져오는 구조임
- 같은 SQLite 파일은 로컬 재생, 디버깅, 에이전트가 실제로 수행한 작업 이해에 사용할 수 있음
적합한 사용 범위와 Postgres 선택 기준
- AI 에이전트와 AI 생성 워크플로는 버스트성이 있고 실험적인 경우가 많아, 에이전트나 테넌트마다 작은 자체 상태 단위를 갖는 구성이 이해하기 쉬움
- 마이크로 VM이나 컨테이너 안의 작은 서버 여러 개가 각각 SQLite 데이터베이스와 객체 스토리지 백업을 갖는 방식은, 하나의 큰 상시 실행 공유 시스템보다 단순하고 저렴하며 장애 격리가 좋을 수 있음
- 객체 스토리지로의 비동기 복제가 원하는 내구성 모델이 아니거나, 더 높은 가용성·더 넓은 공유 확장성·네트워크 데이터베이스 특성이 필요하면 Postgres가 더 적합함
- 많은 워크플로 시스템은 첫날부터 그런 수준의 인프라가 필요하지 않으며, 상태 요구보다 더 큰 인프라로 시작할 필요가 없음
- 로컬 SQLite 데이터베이스, S3로의 Litestream 백업, 저렴한 워커 조합만으로도 적은 인프라의 내구 시스템을 만들 수 있으며, AI 에이전트 영역에서는 합리적인 기본값이 될 수 있음
댓글과 토론
Hacker News 의견들
-
Temporal로 워크플로를 구성하기 시작했는데, 로컬 앱으로는 꽤 가볍게 배포되고 격리된 로컬 설치에서는 SQLite를 사용함
API 재시도 처리, 워크플로와 작업 정리가 정말 단순해져서 한번 써보길 권함. 철학적으로는 이 글이 제안하는 것과 정확히 같은 방향인데, 에이전트가 다루기 좋은 매우 풍부하고 유연한 인터페이스를 더해줌. 웹 UI로 워크플로를 살펴보고 에이전트 실행을 검토하기도 쉬움
Temporal은 시스템에 훨씬 높은 신뢰성을 거의 공짜처럼 넣어줌. 분산·신뢰성 있는 시스템은 어렵기 때문에 바퀴를 다시 발명하지 않는 편이 낫다고 봄
SQLite 데이터베이스를 쉽게 들여다보고, 워크플로에서 무슨 일이 일어나는지 파악하고, 개별 작업을 조합하고, 워크플로를 간단히 호출 가능하게 만들고 싶다면 Temporal을 볼 만함
이와 함께 에이전트용 파일 사용은 거의 줄였음. Markdown과 JSON도 좋지만 작은 로컬 앱을 만들 때는 함정처럼 느껴짐. LLM은 SQLite를 잘 다루고, 거기서 Markdown이나 JSON 등 원하는 형태로 렌더링할 수 있음. 에이전트가 jq를 띄우거나 Markdown을 grep하는 대신 특정 행만 질의할 수 있으면 토큰도 많이 절약됨. 파일 여러 개보다 데이터 구조를 더 규율 있게 만들게 하는, 이식성 좋은 자체 포함 데이터 관리 시스템을 얻게 됨. 작은 로컬 프로젝트가 커지거나 더 공식화되면 MySQL/Postgres로도 이어질 수 있고, 이미 스키마와 데이터 규율을 갖춘 상태가 됨- 주로 단일 머신에서 돌리는 것처럼 들림
Temporal은 규모가 커지면 훨씬 복잡해짐. Cassandra 운영은 즐겁지 않고, Ringpop과 TChannel은 문제가 생겼을 때 디버깅하기 어려움. SQL 백엔드 지원은 일관성 요구 때문에 수평 확장 복제본을 지원하지 않고 단일 인스턴스만 가능함
코드 작성 방식에 따라 워크플로에 박힌 코드를 수정하는 것도 복잡해짐. 히스토리 이벤트 순서를 바꾸는 변경은 이미 배포된 워커의 결정성을 깨뜨림
우리는 Temporal을 많이 쓰는데, 단순 스크립팅이나 자동화로 시작한 사람들은 다 좋아하고, 그 위에 실제 운영 시스템을 만든 사람들은 다 싫어함. 운영 미숙일 수도 있지만, 여기 댓글들에서 보이는 장밋빛 그림과 내 경험은 맞지 않았음 - HN에서 들리는 바로는 Temporal의 관리형 솔루션에 예상보다 많은 돈을 내거나, 결국 매우 무거운 시스템을 직접 운영하면서 상당한 운영 부담을 떠안게 된다고 함
직접 해본 건 아니지만, 실제 경험을 더 듣고 싶음 - Markdown을 jq나 grep하는 대신 SQLite를 쓰는 구체적인 예를 들어줄 수 있나?
- Temporal 광고처럼 읽힘 :)
- 파일과 데이터베이스 접근법 얘기가 흥미로움. 나도 왔다 갔다 하다가 결국 데이터베이스로 정착했음
- 주로 단일 머신에서 돌리는 것처럼 들림
-
실제 운영 앱에 SQLite를 쓰자는 집착이 이해되지 않음. SQLite는 임베디드 데이터베이스라 동시성 관리에는 전혀 맞지 않음
이런 일을 하라고 Postgres, MySQL 같은 데이터베이스 서버가 있는 것임. 이들의 전체 역할은 여러 프로세스가 서로 다른 머신에서 동시에 데이터를 수정할 수 있게 하는 것임
이건 컴퓨터 과학의 기본 원칙인데, “모든 것에 SQLite”를 외치는 쪽은 경험이 좀 부족해 보임- 어떤 종류의 동시성이 있고 그 요구를 어떻게 충족해야 하는지에 대한 이해가 꽤 제한적인 듯함. 서버인지 아닌지는 이 논의에서 그리 중요하지 않음
SQLite는 많은 실제 워크로드에서 훌륭한 운영 데이터베이스이고, 이는 널리 문서화되어 있음. Postgres와는 매우 다르기 때문에 완전히 다른 기술을 배워야 함
한 가지 관점은 시스템 안에서 자연스럽게 강한 파티셔닝이 되는 부분에는 SQLite가 잘 맞을 수 있다는 것임 - SQLite와 동시성 프런트엔드, 예를 들어 Go의 net/http 서버 조합만으로도 어떤 서비스가 상상할 수 있는 부하를 전부 처리할 수 있는 경우가 많음. 시간이 지나며 하드웨어를 키울 수 있다면 더 그렇고, SQLite는 수십만 TPS까지도 간단히 확장 가능함
실제로 포기하는 건 고가용성/장애 조치와 재해 복구 정도인데, 이것도 해결책은 있음. 단일 서버 시스템은 대체로 놀라울 만큼 견고함. 복잡한 제어 평면이 없으면 시스템이 늘어날수록 가동률이 내려가는 경우가 많기 때문임 - SQLite는 여러 용도에 좋지만, 아마 네트워크 데이터베이스와 샤딩이 필요한 대규모 웹앱에 주로 시간을 쓰고 있는 듯함. 그것도 흥미로운 영역이지만 다른 영역도 많음
기술 변화에 비춰 기존 “모범 사례”를 다시 평가하는 걸 좋아함. 특히 단순성을 높이는 방향이라면 더 그렇다. 가족용 소셜 미디어 사이트를 VPS 하나의 SQLite DB로 돌리는 건 훌륭함. 사용자 약 15명이고 유지보수는 거의 없음. FreshRSS 인스턴스와 “now” 페이지도 SQLite로 돌림
직장에서도 지난 수십 년 동안 SQLite를 온갖 용도에 썼음. 임시 작업 큐, 로컬에서 많은 로그를 빠르게 적재·질의하는 방식, 그리고 simonw의 훌륭한 https://github.com/simonw/datasette로 실시간 표시·필터링하는 데 썼음
“모든 것에 SQLite”라기보다는 “생각보다 훨씬 많은 곳에 SQLite”에 가깝다고 봄
kentonv/Cloudflare의 엣지 SQLite 작업이 이런 생각을 좀 더 대중화했을 수 있지만, 원래부터 있던 흐름임. https://blog.cloudflare.com/sqlite-in-durable-objects/
이런 작고 유용한 사례들을 알고 활용하고 싶어 하는 건 경험 부족이 아니라 오히려 경험의 지표일 수 있음 - 그래서 수십억 개의 SQLite 데이터베이스가 있는 것 아닌가?
SQLite는 다른 모든 데이터베이스 엔진을 합친 것보다 더 많이 쓰일 가능성이 큼. 야생에는 수십억 개의 SQLite 복사본이 존재함. Android 기기, iPhone과 iOS 기기, Mac, Windows 10/11 설치본, Firefox/Chrome/Safari, Skype, iTunes, Dropbox 클라이언트, TurboTax와 QuickBooks, PHP와 Python, 대부분의 TV와 셋톱박스, 대부분의 차량 멀티미디어 시스템, 셀 수 없이 많은 애플리케이션에 들어 있음
https://sqlite.org/mostdeployed.html - 데이터가 자연스럽게 샤딩되고, 쓰기가 단일 샤드 안에서 일어난다면 병렬성은 쉬워짐. 요청은 사용자의 데이터가 있는 샤드로 라우팅되고, 로컬에서 읽기/쓰기를 함
이렇게 하면 확장성을 훨씬 이해하기 쉬움. 잘라 붙이고, 또 잘라 붙이면 됨. 사용자 N명마다 샤드 하나를 더 두는 식임
대신 교차 샤드 질의, 예를 들어 분석, 그리고 사용자가 이탈하거나 노후화될 때 부하를 어떻게 평준화할지 같은 다른 문제를 얻게 됨
하지만 대규모 사용자 수에서 삽입/갱신으로 생기는 공유 인덱스 확장 문제 전체는 피할 수 있음
관계형 데이터베이스라기보다 계층형 데이터베이스가 됨
- 어떤 종류의 동시성이 있고 그 요구를 어떻게 충족해야 하는지에 대한 이해가 꽤 제한적인 듯함. 서버인지 아닌지는 이 논의에서 그리 중요하지 않음
-
다음 것들을 전부 Go + SQLite로 대체했음: Intercom, Zendesk, 이메일 마케팅, Kanban, Todo, 결제 스택, 이슈 트래커, 포럼, 가동 시간 모니터, PagerDuty 클론
판매하는 제품이 수십 개라서, 전부 직접 만들면 어떨까 생각했음
모두 같은 서버에서 돌아가고 메모리를 아주 적게 씀. 쓰던 SaaS 도구들을 전부 이것들로 대체함
전용 서버로 옮기면서 관리형 클라우드 솔루션에 내던 비용의 약 1/10로 줄였고, 같은 고가용성을 유지하면서 지연 시간도 더 낮아졌음. VPS의 noisy neighbor 때문에 꼬리 지연 시간이 늘던 것도 일부 이유였음
예전에는 이런 것들에 큰돈을 썼지만, 이제 운영 4개월째이고 사소한 업데이트만 필요했음
배포는 정말 단순함. Docker도 Kubernetes도 없이 systemd 서비스와 개발 머신에서 빌드해 배포한 바이너리뿐임
MaxMind나 IPData 같은 서비스에도 돈을 냈었는데, 직접 IP 지리 위치 서비스를 만들었고 테스트에서는 기존 대부분의 솔루션보다 성능이 좋았음
시작은 Uptime Robot 대체였고, 그다음 자신감이 붙어 PagerDuty를 대체했음. 이후 Intercom을 대체함
마지막으로 “결제 스택은 직접 만들지 말라”는 말을 늘 들었지만, YOLO라 생각하고 그 실수를 직접 해보기로 했음. 기존 결제 솔루션을 공부해 직접 개발하고 배포했으며, 지금까지 문제는 전혀 없었음
앞단에는 Caddy를 둠
대부분의 SaaS 제품이 제공하는 기능 중 실제로는 1~5%만 쓰고 있었고, 정작 필요한 기능은 이런 “엔터프라이즈급” 플랫폼 안에서 점점 더 깊이 묻혀 워크플로를 어렵게 만든다는 걸 알게 됨
상용 제품은 파트너와 고객들이 내가 얼마나 싼지 아는 걸 좋아하지 않을 테니 보여주지 않겠지만, 나는 이걸 수완 좋다고 부름
무료 앱은 보여줄 수 있음. 최근 출시했고 사용자 2만 명 이상임: https://macrocodex.app/
이 앱은 Zendesk 클론만 사용함. 이메일은 Cloudflare 라우팅으로 처리해서 운영 비용이 거의 들지 않음- 가동 시간 모니터를 직접 만들었는데, 지역 분산이나 주거용 회선 테스트는 어떻게 다르게 처리하나?
-
파일에서 다중 파티션 데이터베이스까지는 간극이 큼. 실제 운영이 걸린 상황에서 데이터베이스를 컨테이너로 돌리는 건 내 취향이 아님
개인적으로 많은 ETL은 엔터프라이즈 데이터베이스를 끌어들이지 않고 로컬에서 처리할 수 있음. 그런 경우 DuckDB는 SQLite보다 5~10배 낫고, 전용 Postgres 데이터베이스를 띄우는 것보다 훨씬 단순하고 빠름
일반 스크립팅에서는 20줄짜리 awk 스크립트와 DuckDB 기반의 훨씬 깔끔하고 견고하며 유지보수 가능한 동등 SQL 스크립트는 비교가 안 됨
MotherDuck이 IPO를 위해 펌프 앤 덤프를 해야 하는 상황이 아니길 바람. 흔한 기업 탐욕 때문에 이 도구를 잃으면 슬플 것임- DuckDB 개발자 관계 담당자임. 먼저 좋은 말 고마움 :)
20줄짜리 awk 스크립트 얘기가 재미있음. 어제 Ubuntu Summit에서 거의 같은 주장을 했음. 어느 시점부터는 GNU coreutils로 셸 스크립트를 쓰는 게 비현실적이 되고, DuckDB SQL 스크립트가 복잡도와 유지보수성, 그리고 종종 성능 면에서도 더 잘 확장됨. 슬라이드는 여기 있음: https://blobs.duckdb.org/slides/duckdb-ubuntu-summit-2026.pd... 페이지 32~36
또 MotherDuck은 DuckDB 위에서 비공개 소스 DBaaS를 개발함. DuckDB 위에 만들고, DuckDB로 MotherDuck에 연결하지만, 시애틀에 본사를 둔 별도의 VC 투자 회사임
DuckDB는 암스테르담의 부트스트랩, 즉 매출 기반 회사인 DuckLabs가 개발함. 프로젝트의 지식재산은 세 번째 조직인 네덜란드 비영리 단체 DuckDB Foundation에 있음. 자세한 내용은 https://duckdb.org/faq#how-are-duckdb-the-duckdb-foundation-...를 보면 됨
- DuckDB 개발자 관계 담당자임. 먼저 좋은 말 고마움 :)
-
S3에 있는 SQLite DB를 안전하게 동시 업데이트할 수 있게 해주는 라이브러리를 만들었음[0]
잘 알려지지 않은 SQLite sessions 확장과 작은 메타데이터 파일에 대한 S3 compare-and-swap을 사용해 꽤 효율적이고 안전하게 동작하게 함. Lambda 함수에 상태 저장용 DB가 필요하지만 전체 데이터베이스 인스턴스 비용은 내고 싶지 않은 여러 작은 프로젝트에서 즐겁게 쓰는 중임
[0]: https://github.com/psanford/s3db -
SQLite는 단일 노드 애플리케이션에서 Postgres와 비교해도 놀라울 정도로 성능이 좋음
Postgres는 메모리를 훨씬 많이 쓰고, 입출력이 프로세스 간 통신을 거쳐야 함. 반면 SQLite는 공유 연결 풀을 통해 모든 것을 프로세스 안에 둘 수 있음
에이전트 하네스용으로 여러 저장 엔진을 테스트 중인데, SQLite로는 단일 vCPU에서 동시 세션 7.5천 개까지 가능했지만 Postgres는 크래시하거나 연결이 바닥남
[0] https://github.com/impalasys/talon/pull/23#issuecomment-4577...- 제대로 쓰면 SQLite는 사실상 프로세스 내부 메서드 호출임. 남는 장애물이 런타임, 커널, 파일 시스템, 로컬 NVMe 저장장치뿐이라면 호스팅 대안보다 압도적으로 빠를 수 있음
현재 스레드를 벗어나는 순간 지연 시간 측면에서 지는 게임이 됨. 스레드 간 통신을 강제하지 않으면 SQLite는 마이크로초 단위 시간에서 동작할 수 있음 - SQLite가 매우 훌륭한 소프트웨어라는 전제라면, 단일 노드 애플리케이션에서 Postgres와 비교해도 성능이 좋다는 건 예상해야 하는 것 아닌가?
단일 노드 맥락에서 Postgres는 과함. SQLite와 경쟁할 것으로 기대하면 안 됨
거의 메모리 내 HashMap과 Redis를 벤치마크하고, 이상적인 조건에서 HashMap이 잘 나온다고 놀라는 것과 비슷함
- 제대로 쓰면 SQLite는 사실상 프로세스 내부 메서드 호출임. 남는 장애물이 런타임, 커널, 파일 시스템, 로컬 NVMe 저장장치뿐이라면 호스팅 대안보다 압도적으로 빠를 수 있음
-
여러 해 동안 SQLite 얘기를 읽다가 집 프로젝트에 써봤는데, Postgres를 쓰다 오니 타입 시스템이 너무 빈약해서 충격받았음
정말 열등한데 왜 그렇게 칭찬받는지 모르겠음
https://sqlite.org/datatype3.html
https://www.postgresql.org/docs/current/datatype.html
날짜/시간을 다루는 느낌은 30년 된 데이터베이스를 쓰는 것 같고, 삽입 시 아무것도 강제되지 않음. 왜 이렇게 많은 사람들이 좋아하는지 누가 설명해줘야 함- STRICT 테이블을 쓸 수 있음: https://sqlite.org/stricttables.html
- 맞음, SQLite에서 사실상 유일하게 불만인 부분임. 엄격한 타입 시스템이 있는 SQLite라면 훌륭할 것임
- 이건 하위 호환성의 잘못이자 대가임. 대부분의 SQLite 사용자는 각 연결마다 몇 가지 pragma를 실행해야 함
PRAGMA journal_mode = WAL
PRAGMA foreign_keys = ONSomething non-null
PRAGMA busy_timeout = 1000This is fine for most applications, but see the manual
PRAGMA synchronous = NORMALIf you use it as a file format
PRAGMA trusted_schema = OFF
바인딩에 따라 추가 옵션이 필요할 수 있음. 예를 들어 Python 애플리케이션은 sqlite3 모듈의 기본값을 쓰면 안 됨. 그 기본값은 그냥 잘못되어 있음. 3.12 전에는 표준 라이브러리 밖 바인딩을 쓰는 것 말고 대안도 없었음: https://docs.python.org/3/library/sqlite3.html#transaction-c...
strict table도 써야 함. https://www.sqlite.org/stricttables.html
사용성은 나쁘지만 CHECK 제약도 쓸 수 있음. 예를 들어 SQLite 내장 날짜 지원으로 가능은 하지만 어색함:
CHECK (
date(my_date_col) IS NOT NULL
AND my_date_col = date(my_date_col)
)
IS NOT NULL이 필요한 이유는 date가 잘못된 날짜에 NULL을 반환하기 때문임. 다른 검사는 율리우스일도 받아들이기 때문인데, date('2026')은 기원전 4707년 어느 시점이 됨 - 단일 파일이니까
- 타입 시스템이 아닌 다른 것들 때문에 칭찬받음
특히 strict table 이전에는 실망스럽다는 데 동의함
DuckDB를 봐야 함. 제대로 된 타입을 가진 SQLite에 가까움. 다만 OLTP, 즉 구조체 배열이 아니라 OLAP, 즉 배열 구조체라서 일반적인 SQLite 부하에서는 성능이 더 나쁠 수 있음. 실제로 둘 중 하나를 고려하는 애플리케이션이라면 큰 차이는 없을 것 같음
-
여러 대형 Postgres 클러스터를 쓰다가 SQLite로 옮겼고, 월간 활성 사용자가 7자리인 서비스가 전부 SQLite durable objects로 받쳐지고 있음
접근 패턴은 다르게 생각해야 하지만, 이점은 충분히 가치 있었음 -
좋은 프레이밍임. 주요 문제가 워크플로 상태를 내구성 있게 저장하고, 들여다볼 수 있고, 쉽게 복구할 수 있게 만드는 것이라면 SQLite로 충분한 경우가 많음
-
이 아이디어의 다음 반복으로 “내구성 있는 워크플로에는 로그만 있으면 된다”가 나오는 걸 빨리 보고 싶음
- 더 기다릴 필요 없음. 이미 일어나고 있음
“로그만 있으면 된다”식 솔루션이 실패할 수 있는 한 가지 이유는 신뢰할 수 없는 로그가 주입 공격이 되는 경우임[1]
SBOM을 확인하고, CI/CD 파이프라인도 포함하는 걸 잊지 말아야 함[2]
[1] https://news.ycombinator.com/item?id=48315440
[2] https://github.com/jqwik-team/jqwik/issues/708#issuecomment-... - 진지하게 말하면, “내구성 있는 워크플로에는 S3만 있으면 된다”는 건 받아들여서 S3에서 S3로 데이터를 옮기는 데이터 처리 애플리케이션에 쓸 것 같음
- 로그만으로 내구성 있는 워크플로가 충분한가? 헷갈림. 로그 위에서 중첩되거나 관련된 데이터를 어떻게 영속화하고 질의하나? 여기서 로그라면 Elasticsearch나 Meilisearch 같은 걸 말하는 건가?
- 곧이어 “내구성 있는 워크플로에는 소켓만 있으면 된다”가 나오고, 마지막에는 “내구성 있는 워크플로에는 커널 기본 요소만 있으면 된다”가 나올 것임
진지하게 말하면, 전문가라는 건 일에 맞는 도구를 쓰는 것임
- 더 기다릴 필요 없음. 이미 일어나고 있음