
Cloudflare Computer 읽고 실행하기: Durable Object 내부의 가상 파일 시스템
요약
Cloudflare가 AI 에이전트의 지속적인 작업을 위해 Durable Object 내부에 가상 파일 시스템을 구축하는 'Cloudflare Computer'를 공개했습니다. 컨테이너가 정지되어도 데이터가 소실되지 않도록 SQLite를 정본(Source of Truth)으로 활용하는 구조를 다룹니다.
핵심 포인트
- Durable Object 내부에 가상 파일 시스템 구축
- SQLite를 정본으로 사용하여 컨테이너 정지 시 데이터 유실 방지
- AI 에이전트의 장기 작업 및 상태 유지에 최적화된 설계
- 현재 Preview 단계로 운영 환경 적용 시 주의 필요
Cloudflare가 cloudflare/computer라는 리포지토리를 공개했다.
AI 에이전트에게 작업용 파일 시스템을 제공하기 위한 메커니즘이며, 라이선스는 MIT이다.
README의 첫 줄이 이 제품을 요약하고 있다.
Cloudflare Computer is a virtual filesystem that lives inside a Durable Object.
Durable Object 내부에 거주하는 가상 파일 시스템이라는 설명이다.
이 기사에서는 그 내부가 어떻게 구성되어 있는지 테이블 정의까지 내려가며 확인한다.
그 후 실제로 실행하여, 공개된 수치가 어떤 조건에서 성립하는지 측정한다.
참고로, 이 패키지는 본격적인 운영(Production)을 상정하지 않는다.
README에 PREVIEW ONLY라고 명시되어 있으며, API도 변경될 예정이다.
그럼에도 읽을 가치가 있다고 생각하는 이유는 말미에 서술한다.
전제: Worker와 Durable Object
Cloudflare Workers는 요청이 온 시점에 기동하고, 응답을 반환하면 사라지는 실행 환경이다.
대기하는 시간이 없기 때문에 그만큼의 과금이 발생하지 않는다.
그 대신, 실행되는 동안에만 존재하므로 상태를 가질 수 없다.
변수에 넣은 값은 응답을 반환하는 시점에 소실된다.
이 제약에 대한 해답이 Durable Object(이하 DO)이다.
이름으로 지정할 수 있으며, 전용 SQLite를 가진 특수한 Worker라고 생각하면 된다.
DO에는 세 가지 성질이 있다.
idFromName("session-42")와 같이 이름으로 지정하면, 어디서 호출하든 동일한 인스턴스에 도달한다. 또한 특정 이름의 DO는 동시에 하나만 동작하며, 단일 스레드이다.
- 부속된 SQLite는 DO가 동작하는 머신의 로컬 디스크에 있다.
세 번째에 대해 Cloudflare 자체의 설명을 인용한다.
your storage lives in the same thread as the application, requiring not even a context switch to access
애플리케이션과 동일한 스레드에 스토리지가 있어, 컨텍스트 스위칭(Context Switch)조차 필요하지 않다.
용량 상한은 유료 플랜에서 1 DO당 10GB이다.
왜 SQLite를 경유하는가
Cloudflare Computer는 이 SQLite 내부에 파일 시스템을 구축한다.
순수하게 생각하면 컨테이너 내부의 일반적인 파일 시스템에 쓰면 될 것 같다.
그렇게 하지 않는 이유는, 그곳에 써도 사라지기 때문이다.
컨테이너는 유휴 상태가 지속되면 자동으로 정지한다.
sleepAfter = "10m"와 같이 유예 시간을 설정하며, 이를 지나면 정지한다.
다시 기동했을 때 컨테이너 내부는 초기 상태로 돌아가 있다.
이 성질 자체는 설계상의 선택이며, 정지 중에 과금되지 않는 이유이기도 하다.
하지만 AI 에이전트에게 긴 작업을 시키는 문맥에서는 곤란하다.
에이전트의 작업은 한 번의 왕복으로 끝나지 않는다.
쓰고, 테스트하고, 실패를 보고 수정한다.
그 도중에 인간의 판단을 기다리는 경우도 있다.
기다리는 동안 컨테이너가 정지되면 그때까지의 작업이 사라진다.
게다가 이러한 고장은 알아차리기 어렵다.
개발 중에는 컨테이너를 10분 동안 방치하지 않기 때문에 증상이 나타나지 않는다.
운영 환경에서 밤사이에 한 번 정지되었을 때 비로소 나타난다.
여기서 **정본(Source of Truth)**의 위치를 바꾼다.
동일한 데이터의 복사본이 여러 개 있을 때, "이것이 진짜이다"라고 결정한 쪽을 정본이라고 부른다.
Cloudflare Computer는 정본을 DO의 SQLite에 둔다.
컨테이너 측에도 파일 시스템은 있지만, 그것은 미러링(Mirroring)된 이미지이며, 사라져도 DO로부터 다시 만들어진다.
설계 문서에는 컨테이너 측의 위치를 명시하고 있다.
today's
computerd
runs against a process-lifetime DB, so a container restart loses local state and the next push from the DO re-baselines it
오늘날의 computerd는 프로세스 생명주기 DB를 대상으로 실행되므로, 컨테이너 재시작 시 로컬 상태를 잃게 되며, DO로부터의 다음 푸시가 이를 다시 베이스라인(Re-baseline)한다.
여섯 개의 테이블
그렇다면 SQLite 내부는 어떻게 되어 있는가.
정의는 packages/dofs/src/schema/core.ts에 있다.
vfs_meta: 스키마 버전과 변경 일련번호
vfs_nodes: 파일 및 디렉터리의 속성
vfs_dirents: 어떤 디렉터리 아래에 어떤 이름으로 위치하는지
...
역할은 세 가지로 나뉜다.
속성(vfs_nodes), 위치(vfs_dirents), 내용(나머지 세 개)이다.
속성과 위치를 분리하기
vfs_nodes의 기본 키(Primary Key)는 inode라는 정수로, 이름이 아닌 번호로 실체를 가리킨다.
vfs_dirents는 "부모의 inode 번호와 이름"으로부터 "자식의 inode 번호"를 찾는 표로 되어 있다.
경로(Path)의 해결은 루트부터 순차적으로 이 표를 조회하는 작업의 반복이 된다.
이 이중 구조로부터 두 가지 성질이 도출된다.
설계 문서의 기술을 인용한다.
Paths are resolved through an inode-style indirection (vfs_dirents → vfs_nodes), so the local namespace move in a rename is O(1) and hardlinks fall out for free.
이름 변경은 vfs_dirents의 한 행을 수정하는 것만으로 끝난다.
파일이 1GB라 하더라도 소요되는 작업량은 변하지 않는다.
그리고 하드 링크(Hardlink)가 자연스럽게 성립한다.
서로 다른 이름을 가진 행이 동일한 자식 inode를 가리키기만 하면 된다.
단, 이 동일성은 컨테이너 간의 동기화를 거치면 상실된다.
Hardlink identity is not preserved across the wire — each name becomes an independent file with the same content, not a shared inode.
내용은 지문(Fingerprint)으로 관리된다
내용과 관련된 세 개의 테이블이 이 설계의 중심에 있다.
CREATE TABLE vfs_blobs (
hash BLOB PRIMARY KEY,
size INTEGER NOT NULL,
...
)
기본 키가 hash로 되어 있다는 점이 핵심이다.
내용 그 자체가 주소가 된다, 즉 Git과 동일한 내용 주소 지정(Content-addressable) 방식이다.
동일한 내용을 두 번 저장하려고 해도 해시가 같으므로 동일한 행에 해당한다.
실체는 단 한 번만 저장된다.
vfs_chunks는 "이 파일의 0번째 조각은 이 해시"라는 목록을 기록한다.
조각의 크기는 상수로 결정되어 있다.
export const CHUNK_SIZE = 512 * 1024;
512KiB 단위로 나누어 해시를 생성하기 때문에, 큰 파일의 끝부분만 수정했을 경우 앞부분의 청크(Chunk)는 해시가 변하지 않는다.
변경된 부분만 새롭게 저장된다.
중복 제거(Deduplication)와 차분 동기화(Differential Synchronization)가 동일한 구조에서 비롯된다.
행 번호를 갖지 않기
여섯 개의 테이블에는 공통된 지정이 있다.
) WITHOUT ROWID
여섯 개 모두에 적용되어 있다.
SQLite는 통상적으로 각 행에 내부적인 일련번호를 부여한다.
WITHOUT ROWID는 이를 부여하지 않겠다는 지정으로, 검색 경로가 한 단계 짧아질 뿐만 아니라 삽입당 쓰기 작업이 줄어든다.
후자가 효과적인 이유는 과금 체계에 있다.
DO의 SQLite는 쓰기 행 수로 과금되며, 그 단가가 읽기보다 1,000배 높다.
- 행 읽기: 100만 행당 0.001 달러 (월 250억 행까지 무료)
- 행 쓰기: 100만 행당 1.00 달러 (월 5,000만 행까지 무료)
즉, 이 지정은 성능만을 위한 선택이 아니다.
자사의 과금 체계를 고려한 최적화이기도 하다.
직접 실행하며 측정하기
여기서부터는 실제로 실행해 본다.
검증 환경은 Ubuntu 24.04 (x86_64), Node.js v22.22.2, 커밋 63d3636이다.
다행히도 Cloudflare 네트워크가 없어도 동작할 수 있다.
파일 시스템 구현은 @cloudflare/dofs라는 독립된 패키지에 있으며, DO의 스토리지에 해당하는 부분을 교체할 수 있다.
교체용 구현은 리포지토리에 동봉되어 있다.
packages/dofs/src/testing.ts의 SQLiteTestStorage가 Node.js 내장 모듈인 node:sqlite를 메모리 상의 데이터베이스로 사용한다.
그 서두에 방침을 서술한 주석이 있다.
Workers' DO SQL surface는 이것의 하위 집합이므로, 여기서 작동하는 모든 것은 실제 플랫폼에서도 작동한다.
준비 과정에서의 한 가지 걸림돌
클론(Clone) 직후에 테스트를 실행하면 실패한다.
Error: Cannot find package '@cloudflare/dofs/testing' imported from
/home/claude/computer/packages/dofs/src/schema/index.test.ts
자체 패키지의 서브 패스(Sub-path)를 해결하지 못하고 있다.
먼저 빌드(Build)가 필요하다.
npm run build --workspace @cloudflare/dofs
npm run build --workspace @cloudflare/computer-rpc
순서는 dofs
→ rpc
→ computerd
이다.
빌드 후에는 436개의 테스트가 통과한다.
파일 1개는 몇 줄이 되는가
조작 전후로 각 테이블의 행(Row) 수를 센다.
function countRows(storage) {
const counts = {};
for (const table of VFS_TABLES) {
...
13바이트의 파일을 하나 작성한다.
await fs.writeFile("/workspace/notes/todo.md", "- [ ] ship it");
vfs_nodes: 1, vfs_dirents: 1, vfs_blobs: 1, vfs_blob_bytes: 1, vfs_chunks: 1
합계 5행
새로운 파일 1개에 5행.
속성, 위치, 지문(Fingerprint), 바이트 열(Byte sequence), 조각(Chunk)의 나열이 각각 1행씩이다.
같은 경로에 다른 내용을 작성하면 다음과 같이 된다.
vfs_blobs: 1, vfs_blob_bytes: 1
합계 2행
덮어쓰기는 2행.
속성과 위치는 이미 존재하기 때문에, 늘어나는 것은 내용만큼이다.
새로 생성하는 것이 덮어쓰기보다 2.5배 더 많다는 비대칭성은 에이전트(Agent)의 작업에 유리하게 작용한다. 한 번 작성한 파일을 수정하는 횟수가 새로 만드는 횟수보다 많기 때문이다.
중복 제거(Deduplication)는 정말 효과가 있는가
동일한 1MB의 내용을 이름을 바꿔가며 세 번 작성한다.
1회차: nodes:1 dirents:1 blobs:1 blob_bytes:1 chunks:2 합계6
2회차: nodes:1 dirents:1 chunks:2 합계4
3회차: nodes:1 dirents:1 chunks:2 합계4
2회차부터는 실체의 행이 늘어나지 않는다.
내용 주소 방식(Content-addressable)이 예상대로 작동하고 있다.
청크(Chunk)의 경계도 측정했다.
100KB → chunks: 1
512KB → chunks: 1
513KB → chunks: 2
...
512KiB에서 정확히 나뉜다.
CHUNK_SIZE의 정의와 일치한다.
차분 쓰기(Differential write)도 확인한다.
2MB가 채 되지 않는 파일의 마지막 1행만 10번 바꿔 썼다.
증가 행수: 35행
합계 20MB를 작성한 계산이 되지만, 늘어난 것은 35행이다. 매번 통째로 저장하는 구현이었다면 400행 전후가 되었을 텐데, 1할 미만으로 억제되었다.
FUSE로 마운트하기
여기까지는 API를 호출했을 뿐이다.
이 메커니즘의 가치는 "기존 도구가 그대로 작동한다"는 점에 있으므로, 실제로 마운트한다.
FUSE는 파일 시스템 구현을 일반적인 프로그램으로 작성할 수 있게 해주는 메커니즘이다. 커널이 범용 창구를 갖고, 실제 응답을 유저 공간(User space)의 프로그램에 위임한다. 그 역할을 담당하는 것이 computerd이다.
PORT=45999 MOUNT_POINT=/tmp/mnt-test FUSE_MOUNT=fuse \
node packages/computerd/dist/cli/computerd.js
처음에는 실패했다.
libfuse.so.2: cannot open shared object file: No such file or directory
/dev/fuse
커널의 대응과 권한은 모두 갖춰져 있었으나, 제2세대 FUSE 라이브러리가 부족했다.
examples/container/Dockerfile에 필요한 패키지가 나열되어 있다.
RUN apt-get install -y --no-install-recommends fuse3 libfuse2t64 ca-certificates
설치하면 실행된다.
computerd listening on 0.0.0.0:45999 mount=/tmp/mnt-test backend=fuse
$ mount | grep mnt-test
/dev/fuse on /tmp/mnt-test type fuse (rw,nosuid,nodev,relatime,max_read=524288)
max_read=524288은 512KiB이다.
한 번에 운반하는 최대량이 내부의 청크 (Chunk) 경계에 맞춰져 있다.
참고로, 이 절차가 필요했던 이유는 빌드 후의 JavaScript를 직접 실행했기 때문이다.
정식 배포판은 단일 실행 파일이며, libfuse를 내장하고 있다.
일반적인 명령어를 통과시키기
echo "こんにちは、Durable Object" > /tmp/mnt-test/hello.txt
sed -i 's/42/1337/' /tmp/mnt-test/src/lib/index.ts
grep -rn "1337" /tmp/mnt-test/
...
모두 통과되었다.
sed -i는 임시 파일을 만들어 이름을 바꾸는 동작을 하기 때문에 단순한 읽기/쓰기보다 더 많은 것을 요구하지만, 이 또한 성립한다.
데몬을 중지하기
컨테이너가 정지했을 때 무엇이 보이는지 확인한다.
kill -9 $CDPID
ls -la /tmp/clean2/
ls: cannot access '/tmp/clean2/': Transport endpoint is not connected
No such file or directory가 아니다.
사라진 것은 파일이 아니라 응답자(Responder)이다.
마운트 등록은 커널에 남아 있지만, 응답할 프로그램이 더 이상 없다.
이 차이는 장애 조사에서 의미를 갖는다.
"파일이 사라졌다"고 생각하여 저장 처리를 의심하면 원인에 도달할 수 없다.
공개 벤치마크는 무엇과 비교한 수치인가
docs/19_performance.md에 측정 결과가 실려 있다.
computerd / 비교 대상의 비율로, 1.0 미만이라면 computerd가 더 빠르다.
| 항목 | computerd | ext4 | 비율 |
|---|---|---|---|
| 속성 취득 (1000건) | 1971.9 ms | 2659.3 ms | 0.91 |
| ... |
문서는 다음과 같이 요약하고 있다.
The in-memory inode store beats real disk on metadata-heavy work
메타데이터 중심의 작업에서는 실제 디스크를 능가한다고 말이다.
동일한 항목을 직접 다시 측정해 보았다.
FUSE (DO-backed) : 61 ms
실제 디스크 (ext4): 25 ms
tmpfs (메모리) : 19 ms
결과가 반대로 나왔다.
공개된 수치에서 0.72였던 항목이, 실측에서는 2.4배 느리다.
원인을 분리해 보자.
공개된 수치의 측정 환경은 문서에 명시되어 있다.
examples/container를 Cloudflare Containers standard-2 instance (1 vCPU, 6 GiB memory, 12 GB disk)에서 실행 중.
반면, 검증 환경의 /var/tmp는 초당 594MB를 낸다.
즉, 비교 대상의 속도가 다르다.
더 세밀한 단위로 측정하면 이 가설이 뒷받침된다.
FUSE create500: 19ms stat500: 8ms rm500: 4ms
ext4 create500: 9ms stat500: 8ms rm500: 4ms
tmpfs create500: 7ms stat500: 8ms rm500: 3ms
속성 취득과 삭제는 막상막하다.
트리 순회(Tree traversal)도 4ms 대 4ms로 비슷했다.
차이가 난 것은 생성(Create)뿐이었으며, FUSE가 약 2배 더 걸리고 있었다.
따라서 공개된 수치의 요약은 다음과 같이 제한적으로 읽어야 한다.
메타데이터 중심의 작업에서는
Cloudflare Containers에 할당된 디스크를 상회한다.
고속 디스크를 상대할 경우 막상막하이거나 열세에 놓이게 된다.
직접 실행해 보며 "공개된 수치만큼 빠르지 않다"고 느껴지더라도, 그것이 반드시 결함인 것은 아니다.
한편, computerd
자신의 절대값은 잘 재현되었다.
64MiB 복사는 공개 수치 1037.2 ms에 대해 실측 1164 ms로, 차이는 12% 이내이다.
느린 이유는 512KiB 단위의 해시 계산에 있다.
즉, 중복 제거(Deduplication)와 차분 동기화(Differential Synchronization)의 대가로 지불되는 것이다.
세 가지 실행 백엔드 (Execution Backends)
실행 환경은 세 종류가 있다.
| ID | 입력 | 용도 |
|---|---|---|
container-shell | 셸 명령 (Shell command) | Linux 전체, 네이티브 바이너리, 패키지 도입 |
worker-shell | just-bash 명령 | 컨테이너 없는 텍스트 처리 및 git |
worker-javascript | ECMAScript 모듈 | 구조화된 입출력을 동반한 격리 실행 |
진입점은 workspace.runtime.exec(source, { backend }) 하나뿐이다.
그리고 source의 해석은 백엔드에 따라 달라진다.
Backend IDs are part of the execution contract: changing the backend may change the source language. (백엔드 ID는 실행 계약의 일부이다: 백엔드를 변경하면 소스 언어가 변경될 수 있다.)
worker-shell이 사용하는 just-bash는 bash를 TypeScript로 다시 작성한 구현체이다.
Vercel Labs의 오픈 소스이며, Cloudflare의 제품은 아니다.
여기서 주의해야 할 점이 있다.
백엔드마다 할 수 있는 일이 다르므로, ID를 자유롭게 선택하게 하는 것은 권한을 자유롭게 선택하게 하는 것과 같다.
설계 문서(Design document)는 명확하게 경고하고 있다.
Routing is not authorization: trusted gateways must choose from a host-owned allowlist rather than accepting an arbitrary model-supplied backend ID. (라우팅은 권한 부여가 아니다: 신뢰할 수 있는 게이트웨이는 모델이 제공하는 임의의 백엔드 ID를 수락하기보다 호스트가 소유한 허용 목록(allowlist)에서 선택해야 한다.)
그리고 권한을 동적으로 제한하는 메커니즘은 의도적으로 마련되어 있지 않다.
There is no general workspace.scope() abstraction. Backend construction fixes maximum authority and module availability. (일반적인 workspace.scope() 추상화는 존재하지 않는다. 백엔드 구성은 최대 권한과 모듈 가용성을 고정한다.)
권한이 필요하다면, 그 권한을 가진 진입점을 별도로 구축한다.
backends: [
new WorkerJavaScriptBackend({ id: "implementer", access: "read-write", loader: env.LOADER }),
new WorkerJavaScriptBackend({ id: "reviewer", access: "read",
...
불편해 보일 수 있지만, 이는 제한 설정을 누락하는 것이 실패로 나타나지 않는 상황에 대한 대처라고 읽을 수 있다.
동적으로 제한하는 메커니즘에서는 제한을 누락하더라도 동작은 성공해 버리기 때문이다.
전신 리포지토리가 존재함
docs/18_runtime_migration.md에 이전 API와의 대응표가 있다.
workspace.shell.exec가 workspace.runtime.exec가 되었다는 내용이다.
방금 공개된 리포지토리에 마이그레이션 문서가 있는 것은 부자연스럽다.
아직 아무도 사용하지 않는 API에는 마이그레이션이 발생하지 않기 때문이다.
조사해 보니 cloudflare/workspace라는 별도의 리포지토리가 존재했다.
| 구(Old) | 신(New) |
|---|---|
cloudflare/workspace | cloudflare/computer |
@cloudflare/workspace-rpc | @cloudflare/computer-rpc |
wsd | computerd |
| 백엔드 ID ` |
커밋은 393개, star는 15개, fork는 2개였다.
상당한 개발이 이루어졌음에도 불구하고, 거의 주목받지 못했던 것으로 보인다.
그리고 이전 README에는 현재는 삭제된 단락이 있었다.
"wsd 쓰기 경로(write path)는 매 릴리스마다 각 CHUNK_SIZE (512 KiB) 청크를 내용 주소 지정 방식(content-addressed)의 블롭 스토어(blob store)로 해싱합니다. 이를 통해 Durable Object는 변경된 청크만 동기화하고 동일한 콘텐츠를 중복 제거(deduplicate)할 수 있습니다. 그 비용은 원시 dd 스타일의 처리량(throughput) 수치에는 나타나지만, 실제 개발자 워크로드에서는 거의 나타나지 않습니다."
512KiB의 청크, 내용 주소 지정 방식, 중복 제거, 차분 동기화(differential sync), 그리고 그 대가가 처리량 측정에 나타난다는 점.
이 기사에서 측정하여 도출한 내용이 그대로 적혀 있다.
현재의 README에는 이 단락이 없다.
성능에 관한 부분은 남아 있지만, 느린 이유에 대한 설명은 삭제되었다.
현재의 리포지토리만 읽어서는 이 설명에 도달할 수 없다.
직접 측정하여 추론하거나, 이전 버전을 찾아내야만 한다.
얻을 수 있는 교훈
프로덕션(본番)에서 바로 사용하기에는 무리가 있을 수 있다.
그럼에도 불구하고, 다른 곳에 적용할 수 있는 세 가지 설계 결정(design decision)이 있다.
권한을 실행 시점에 제한하지 않는다.
workspace.scope()를 준비하는 대신, 권한별로 입구를 분리한다.
제한하는 것을 잊어버리는 실수가 "성공"으로 나타나지 않도록 하기 위한 구조이다.
종료하기 전에 수락된 처리가 완료되기를 기다린다.
Normal completion은 동일한 drain 규칙을 사용하므로, await하지 않은 capability 호출은 exit 0 이후에 workspace를 변경할 수 없다.
기다리지 않은 비동기 처리가 종료 후에 파일을 다시 쓰는 일은 없다.
"종료란, 수락한 작업이 모두 정리된 상태이다"라고 정의되어 있다.
상한을 초과하면 거부한다.
동시 실행이 기본값인 24개를 초과하면 EEXEC_BUSY를 반환한다.
자동으로 늘리는 방식이라면 폭주를 막을 수 없지만, 거부하는 방식이라면 피해를 유한하게 유지할 수 있다.
세 가지의 공통점은, 편의성을 낮추는 대신 예상치 못한 일이 발생하지 않는 구조를 선택했다는 점이다.
제한하는 것을 잊어버리는 것은 동작상 성공으로 나타난다.
기다리지 않는 구현은 타이밍에 따라 성공한다.
자동으로 늘리는 구현은 계속 늘어나는 동안 계속 성공한다.
성공으로 나타나는 실패는 테스트에서 발견되지 않는다.
따라서 구조로 이를 봉쇄한다는 판단으로 읽힌다.
이러한 사고방식은 프로덕션에서 사용할 수 있는지 여부와는 별개이다.
요약
Cloudflare Computer는 DO의 SQLite 내부에 구축된 가상 파일 시스템이다.
구현은 6개의 테이블로 구성되며, 속성(attribute)과 위치(location)와 내용(content)이 분리되어 있고, 내용은 내용 주소 지정 방식으로 512KiB마다 관리된다.
측정한 범위 내에서 중복 제거와 차분 쓰기(differential write) 모두 선언된 대로 동작하고 있었다.
공개된 벤치마크는 재현할 수 있었으나, 그 결론은 비교 대상의 속도에 의존한다.
computerd 측의 절대값은 12% 이내로 일치한 반면, "실제 디스크보다 빠르다"라는 요약은 Cloudflare Containers의 디스크를 대상으로 했을 때의 이야기이다.
현 시점에서는 실험 및 프로토타입의 대상이다.
읽을 가치는 실행할 수 있는지 여부가 아니라, 그곳에 적힌 판단(decision)에 있다.
참고로, 이 기사에서 결론만 제시한 검증에 대해서는 재현 절차와 관측용 스크립트 전문을 『Durable Object 내부의 파일 시스템: Cloudflare Computer 읽고 실행하기』라는 서적에 정리해 두었다.
참고
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기