WebCatalog이 APFS 클론으로 Mac 앱의 디스크 사용량을 최대 8분의 1로 줄이는 방법

이제 WebCatalog 데스크톱 앱은 macOS에서 APFS 클론을 사용해 디스크 사용량을 크게 줄입니다. 동일한 Electron 및 Photon 데이터를 한 번만 저장하므로 앱을 추가할 때 일반적으로 약 320MB가 아닌 1~2MB의 물리적 저장 공간만 더 사용합니다.

2026년 9월 23일

Nguyen Tran · Software Engineer

WebCatalog이 APFS 클론으로 Mac 앱의 디스크 사용량을 최대 8분의 1로 줄이는 방법

이전에는 macOS에서 WebCatalog 데스크톱 앱으로 만든 앱 하나당 약 320MB의 디스크 공간을 사용했습니다. Electron 기반 앱이라면 드문 일은 아니지만, WebCatalog는 여러 웹 앱을 데스크톱 앱으로 사용하는 사람들을 위해 설계되었습니다. 앱을 열 개 설치하면 내부 데이터 대부분이 정확히 같더라도 3GB가 넘는 공간을 차지할 수 있었습니다.

최근 macOS에서 WebCatalog 데스크톱 앱이 앱을 빌드하는 방식을 변경했습니다. 이제 첫 번째 앱은 로컬에 보관하는 앱 엔진의 준비된 사본까지 포함해 약 340MB의 실제 디스크 공간을 사용합니다. 그다음부터 추가하는 앱은 일반적으로 실제 디스크 사용량이 1~2MB만 늘어납니다. 테스트에서는 앱 열 개의 디스크 사용량이 3GB 이상에서 약 360MB로 줄었습니다.

이를 위해 macOS에 이미 내장된 기능인 APFS 클론을 사용했습니다. 핵심은 단순히 파일을 복제하는 것이 아니었습니다. 각 앱을 독립적으로 유지하면서도 코드 서명이 올바르고, 기존 방식으로 빌드한 앱과 기능적으로 동일하도록 복제를 구현하는 것이었습니다.

앱마다 320MB가 추가로 필요했던 이유

WebCatalog 데스크톱 앱은 웹사이트를 독립 실행형 데스크톱 앱으로 바꿉니다. 생성한 앱은 모두 Electron을 기반으로 만든 앱 엔진인 Photon에서 실행됩니다. macOS에서 각 앱은 Electron(Chromium과 Node.js), Photon, 해당 앱 전용 파일을 포함하는 일반적인 .app 번들입니다.

예를 들어 Slack과 Discord 앱을 보겠습니다. 이름, 아이콘, 번들 식별자, 설정은 다르지만 용량이 큰 Electron 프레임워크와 Photon의 대부분은 동일합니다.

지금까지는 각 앱을 완전히 별개의 사본으로 빌드했습니다.

Slack.app
  Electron
  Photon
  Slack 전용 파일

Discord.app
  Electron
  Photon
  Discord 전용 파일

두 앱의 Electron 프레임워크와 Photon이 바이트 단위까지 같더라도 macOS는 앱마다 별도의 실제 사본을 저장했습니다. 따라서 앱 열 개를 설치하면 거의 동일한 320MB짜리 앱 번들을 대략 열 개 저장하는 셈이었습니다.

이 구조에는 유지하고 싶은 장점이 있었습니다. 모든 앱이 완전히 독립적이었습니다. 한 앱을 삭제해도 다른 앱에는 영향을 주지 않았고, 설치된 앱이 계속 작동하는 데 시스템에 WebCatalog 데스크톱 앱이 남아 있을 필요도 없었습니다.

없애고 싶었던 것은 그 이면의 불필요한 데이터 중복이었습니다.

APFS에는 필요한 기능이 이미 있었습니다

최신 Mac은 Apple의 APFS 파일 시스템을 사용합니다. APFS는 두 개의 독립적인 파일이 어느 한쪽에서 변경이 발생하기 전까지 동일한 실제 데이터를 공유할 수 있게 하는 기록 중 복사(copy-on-write) 방식의 복제를 지원합니다.

300MB 파일을 복사한다고 가정해 보겠습니다. 일반 복사에서는 macOS가 디스크에 300MB를 추가로 기록하므로 두 파일이 총 약 600MB를 차지합니다.

APFS 클론을 사용하면 새 파일은 여전히 완전한 300MB 파일처럼 보이고 작동하지만, 처음에는 원본과 동일한 물리적 블록을 가리킵니다.

파일 A ─────┐
            ├── 공유되는 물리적 블록
파일 B ─────┘

나중에 파일 B의 일부가 변경되면 APFS는 변경된 데이터에 대해서만 새 블록을 기록합니다. 동일하게 유지되는 부분은 계속 원본 블록을 공유할 수 있습니다.

파일 A ───────── 공유 블록

파일 B ───────── 공유 블록
       └──────── 변경된 블록

애플리케이션 입장에서는 파일 A와 파일 B가 별개의 파일입니다. SSD 입장에서는 동일한 데이터를 한 번만 저장하면 됩니다.

이는 우리가 필요로 했던 동작과 거의 정확히 일치합니다.

공통 기반으로 앱 빌드하기

이제 WebCatalog 데스크톱 앱은 Electron과 Photon 버전의 조합마다 기반 앱을 준비합니다. Photon 기반 앱에는 Electron, Photon, 프레임워크 구조, 공통 서명 등 앱 전반에 걸쳐 동일한 부분이 들어 있습니다.

데스크톱 앱이 같은 버전을 사용하는 다른 앱을 만들 때는 더 이상 전체 사본을 처음부터 추출해 빌드하지 않습니다. 대신 Photon 기반 앱의 APFS 클론을 만들고, 달라야 하는 부분만 맞춤 설정합니다.

여기에는 앱 이름, 아이콘, 번들 식별자, 설정, 실행 파일 이름, 빌드 식별자, 그 밖의 앱별 메타데이터가 포함됩니다.

번들의 대부분은 변경되지 않으므로 APFS는 Electron과 Photon이 들어 있는 물리적 블록을 계속 공유합니다. 상대적으로 적은 양의 앱별 데이터만 새로운 공간을 차지합니다.

Electron만 공유하면 안 될까요?

더 명백해 보이는 방법은 Electron을 한 번 설치하고 모든 앱이 이를 참조하게 하는 것입니다.

이 방법도 고려했지만, 안정성 측면에서 근본적인 변화가 생깁니다. 공유 Electron 설치 파일이 사라지면 이를 사용하는 모든 앱이 작동을 멈출 수 있습니다. 캐시 정리 도구가 파일을 제거하거나 WebCatalog 데스크톱 앱을 삭제하면서 함께 제거할 수도 있고, 개별 앱을 이동하거나 복원하는 일도 더 복잡해집니다.

또한 이전 버전을 안전하게 정리하려면 설치된 앱마다 어떤 런타임 버전에 의존하는지 추적해야 합니다.

macOS 코드 서명도 또 다른 문제입니다. 엄격한 서명 검증은 앱 번들 외부를 가리키는 심볼릭 링크를 거부합니다.

APFS 클론을 사용하면 이러한 의존성을 도입하지 않고도 데이터 공유의 이점을 얻을 수 있습니다. 설치된 앱은 완전하고 독립적인 애플리케이션 번들로 남으면서 실제 디스크 블록을 공유할 수 있습니다.

Photon 기반 앱을 삭제해도 이를 복제해 만든 앱은 정상적으로 작동합니다. 설치된 앱 하나를 삭제해도 다른 앱에는 영향이 없습니다. 파일 시스템이 공유를 처리하는 동안 애플리케이션 구조는 독립적으로 유지됩니다.

코드 서명 때문에 절약 효과가 거의 사라질 뻔했습니다

앱을 복제하는 것은 문제의 일부에 불과했습니다. macOS 애플리케이션에는 코드 서명도 필요합니다.

기존 빌드 파이프라인에서는 앱을 맞춤 설정한 뒤 각 애플리케이션 번들 전체에 다시 서명했습니다. 일반 복사에서는 문제가 없지만, 기록 중 복사 저장 방식에서는 용량이 큰 바이너리를 수정하면 APFS가 이를 위해 새로운 물리적 블록을 할당할 수 있습니다.

개발 과정에서 Electron 프레임워크에 다시 서명하면 앱당 실제 저장 공간이 약 194MB 늘어나는 것을 확인했습니다. 앱을 만들 때 Electron을 복사하지 않는 데는 성공했지만, 서명 과정에서 상당 부분을 다시 복제한 셈이었습니다.

따라서 서명 과정도 바꿔야 했습니다.

이제 용량이 큰 공통 프레임워크는 Photon 기반 앱을 준비할 때 서명합니다. 데스크톱 앱이 이 기반 앱을 복제한 뒤에는 크기가 큰 공유 바이너리를 수정하지 않고, 앱마다 실제로 달라야 하는 작은 부분에만 다시 서명합니다.

앱이 완성되면 최종 번들을 대상으로 엄격한 서명 검증을 실행해 모든 서명이 유효한지 확인합니다.

이렇게 하면 macOS의 코드 서명으로 보장되는 안전성과 APFS를 통한 저장 공간 절약을 모두 유지할 수 있습니다.

Node.js에 복제를 요청했지만 실제로는 복제되지 않았습니다

또 다른 예상치 못한 문제는 복제 작업 자체였습니다.

Node.js는 COPYFILE_FICLONE과 COPYFILE_FICLONE_FORCE를 비롯해 기록 중 복사 동작을 요청하기 위한 복사 플래그를 제공합니다. 이론적으로는 우리가 필요로 하는 API처럼 보였습니다.

Node.js 24에서 같은 288MB Electron 애플리케이션을 여러 방식으로 복사하고 각 작업이 실제 디스크 공간을 얼마나 추가로 사용하는지 측정했습니다.

fs.cpSync                              +288 MB
fs.cpSync + COPYFILE_FICLONE           +288 MB
fs.cpSync + COPYFILE_FICLONE_FORCE     +288 MB
/bin/cp -c -R                          ~0 MB

테스트에서 Node.js의 두 복제 모드는 모두 전체 물리적 사본을 만들었습니다. 예상했던 복제 동작이 일어나지 않았는데도 FORCE 변형조차 오류를 보고하지 않았습니다.

macOS의 기본 제공 cp -c 명령은 예상대로 작동했으므로 WebCatalog 데스크톱 앱은 이 방식을 직접 사용합니다.

파일 시스템 최적화는 파일 시스템 자체를 측정해 검증해야 한다는 점도 다시 확인했습니다. 기록 중 복사를 요청하는 API를 호출했다고 해서 결과 파일이 실제 저장 공간을 공유한다는 보장은 없습니다.

최적화가 실패해도 설치는 성공하도록

디스크 공간 절약은 최적화입니다. 앱 설치의 성공 여부까지 걸어서는 안 됩니다.

새 파이프라인은 복제에 실패하더라도 앱 설치가 중단되지 않도록 설계했습니다. Photon 기반 앱 준비가 실패하거나, 캐시된 기반 앱이 손상되거나, 복제가 실패하거나, 서명 검증을 통과하지 못하면 데스크톱 앱은 전체 파일 추출과 전체 서명을 사용하는 기존 빌드 방식으로 돌아갑니다.

따라서 최악의 경우에도 디스크 사용량이 이전과 같아질 뿐, 설치가 실패하지는 않습니다.

동시 실행도 고려해야 했습니다. Photon 기반 앱은 먼저 임시 디렉터리에서 준비한 뒤 완성되었을 때만 최종 위치로 이동합니다. 덕분에 앱 빌드 두 건이 동시에 진행되더라도 어느 쪽도 미완성된 기반 앱을 실수로 사용하지 않습니다.

오래된 기반 앱도 안전하게 제거할 수 있습니다. 설치된 APFS 클론은 원본 기반 앱이 계속 존재해야 작동하는 것이 아닙니다. 기반 앱을 삭제해도 클론이 계속 사용하는 물리적 블록은 유지됩니다.

이 방식은 모든 최신 Mac의 기본 파일 시스템인 APFS에서 작동합니다. 앱이 외장 HFS+ 또는 exFAT 드라이브처럼 복제를 지원하지 않는 디스크에 있으면 WebCatalog 데스크톱 앱은 일반 복사 방식으로 전환합니다. 이 경우 앱은 이전처럼 작동하지만 공간 절약 효과는 없습니다. Windows와 Linux는 현재 변경 사항이 없습니다.

논리적 크기와 실제 크기는 다릅니다

다소 혼란스러울 수 있는 점은 Finder에서 여전히 앱마다 크기가 약 320MB로 표시될 수 있다는 것입니다.

이 숫자는 앱의 논리적 크기입니다. 앱에는 실제로 약 320MB에 해당하는 파일이 들어 있으며, 복제 기능 없이 이 파일들을 다른 곳에 복사한다면 대략 그만큼의 데이터를 기록해야 합니다.

달라진 것은 실제 크기, 즉 파일이 디스크에서 차지하는 고유한 블록의 양입니다.

두 앱에 동일한 300MB 프레임워크가 들어 있고 APFS가 기본 블록을 공유하도록 허용한다면, 각 앱에는 논리적으로 300MB가 들어 있더라도 두 번째 앱으로 인해 추가되는 실제 데이터는 거의 없습니다.

Finder의 정보 가져오기 화면이나 du 같은 도구에서는 이러한 공유가 반드시 드러나지는 않습니다. 절약 효과는 실제 디스크의 남은 여유 공간에서 가장 분명하게 확인할 수 있습니다.

Discord, Facebook, Instagram, Messenger, TikTok, 그리고 맞춤형 앱 두 개를 포함한 실제 앱 일곱 개로 이를 검증했습니다. 이 방식으로 빌드했을 때 기존 빌드 방식에 비해 디스크 공간을 약 1.9GB 절약했습니다.

또한 디스크의 기본 물리적 오프셋을 확인해 앱들이 공통 Electron 및 Photon 데이터를 블록 수준에서 공유한다는 사실을 확인했습니다. 기존 빌드 방식으로 만든 앱은 해당 블록을 전혀 공유하지 않아 유용한 비교 대상이 되었습니다.

결과

WebCatalog 데스크톱 앱으로 앱을 하나만 만드는 사용자에게는 차이가 작습니다. 첫 번째 앱은 이후 클론을 만드는 데 사용할 Photon 기반 앱도 데스크톱 앱이 보관하므로, 오히려 이전보다 디스크 공간을 조금 더 사용합니다.

하지만 그다음부터는 이점이 빠르게 커집니다.

이전

앱 1개       약 320MB
앱 10개      3GB 초과

APFS 복제를 사용하면 다음과 같습니다.

이후

앱 1개       약 340MB
앱 10개      약 360MB

처음 기반 앱을 만들고 나면 앱을 추가할 때마다 일반적으로 실제 디스크 사용량이 1~2MB만 늘어납니다.

중요한 점은 공유 런타임에 대한 의존성을 도입하지 않고도 이를 달성했다는 것입니다. 각 앱은 일반적인 독립형 macOS 애플리케이션으로 유지되고, APFS는 동일한 Electron과 Photon 데이터를 한 번만 저장합니다. 앱을 열 개가량 설치했다면 실제 디스크 사용량을 8분의 1 이하로 줄일 수 있습니다.

이 기능은 macOS용 WebCatalog 데스크톱 앱 최신 버전에서 사용할 수 있습니다. 따로 활성화할 필요는 없습니다. 새 앱에는 자동으로 적용되고, 이미 설치한 앱은 다음 업데이트 때 차지하는 공간이 줄어듭니다.