From 4a2ec29cddb0d67f572499f461396841be120fc5 Mon Sep 17 00:00:00 2001 From: Nico Hinderling Date: Tue, 16 Jun 2026 15:26:12 -0700 Subject: [PATCH 1/2] feat(snapshots): Compress preprod snapshot manifest with zstd The preprod snapshot manifest can be large; send it as a zstd-compressed JSON body so create_preprod_snapshot transfers fewer bytes over the wire. Adds a with_zstd_json_body request builder that serializes the payload to JSON, compresses it with zstd, and sets the Content-Encoding: zstd header. --- Cargo.lock | 1 + Cargo.toml | 1 + src/api/mod.rs | 21 ++++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 3073b9181f..7fa7281372 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3702,6 +3702,7 @@ dependencies = [ "whoami", "windows-sys 0.59.0", "zip 2.4.2", + "zstd", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 87e4a8f3aa..99092a8382 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ walkdir = "2.3.2" which = "4.4.0" whoami = "1.5.2" zip = "2.4.2" +zstd = "0.13.3" data-encoding = "2.3.3" magic_string = "0.3.4" chrono-tz = "0.8.4" diff --git a/src/api/mod.rs b/src/api/mod.rs index b52d4cc4e0..e7ca1c0097 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1020,7 +1020,9 @@ impl AuthenticatedApi<'_> { PathArg(org), PathArg(project) ); - self.post(&path, body) + self.request(Method::Post, &path)? + .with_zstd_json_body(body)? + .send() } /// Fetches upload options for snapshots. @@ -1360,6 +1362,23 @@ impl ApiRequest { Ok(self) } + pub fn with_zstd_json_body(mut self, body: &S) -> ApiResult { + let mut body_bytes: Vec = vec![]; + serde_json::to_writer(&mut body_bytes, &body) + .map_err(|err| ApiError::with_source(ApiErrorKind::CannotSerializeAsJson, err))?; + let compressed = zstd::encode_all(body_bytes.as_slice(), 0) + .map_err(|err| ApiError::with_source(ApiErrorKind::CompressionFailed, err))?; + debug!( + "zstd json body: {} bytes compressed to {} bytes", + body_bytes.len(), + compressed.len() + ); + self.body = Some(compressed); + self.headers.append("Content-Type: application/json")?; + self.headers.append("Content-Encoding: zstd")?; + Ok(self) + } + pub fn with_body(mut self, body: Vec) -> Self { self.body = Some(body); self From 597d3031e65b08467568cdd7de86da69efd48aa6 Mon Sep 17 00:00:00 2001 From: Nico Hinderling Date: Tue, 16 Jun 2026 15:51:59 -0700 Subject: [PATCH 2/2] docs: Add changelog entry for zstd snapshot manifest compression --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ce4bb3765..9c4e2c3875 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- (snapshots) Compress preprod snapshot manifest with zstd ([#3336](https://github.com/getsentry/sentry-cli/pull/3336)) + ## 3.5.1 ### Internal Changes 🔧