From f0287d69e598bd9f3113cef7bdc1867b8740ef38 Mon Sep 17 00:00:00 2001 From: Oleksiy Syvokon Date: Mon, 9 Feb 2026 18:02:56 +0200 Subject: [PATCH] ep: Compress EP requests (#48793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Benchmark results on 3,000 captured requests: | Scenario | Mean | Savings | p95 | Savings | |:------------------|-------:|--------:|-------:|--------:| | Uncompressed | 12,275 | — | 35,896 | — | | zstd (no dict) | 2,784 | 77.3% | 7,193 | 80.0% | | zstd + global dict| 2,544 | 79.3% | 6,862 | 80.9% | | brotli (no dict) | 2,650 | 78.4% | 6,857 | 80.9% | A trained zstd dictionary adds only 2% over plain zstd, which is not worth added complexity. Brotli compresses comparably but is 4 times slower. Release Notes: - N/A --- Cargo.lock | 1 + crates/edit_prediction/Cargo.toml | 1 + crates/edit_prediction/src/edit_prediction.rs | 6 +++++- crates/edit_prediction/src/edit_prediction_tests.rs | 3 ++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95aa65c06ceeb74ef03443b62912b3ee60fceb46..6c4addac4e47161b1a06b5126747c93a50ae7785 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5353,6 +5353,7 @@ dependencies = [ "zed_actions", "zeta_prompt", "zlog", + "zstd", ] [[package]] diff --git a/crates/edit_prediction/Cargo.toml b/crates/edit_prediction/Cargo.toml index 767fd49a9f7f3fe5d481f93583ef14e17a87e9f3..f1d0d30815273413922e60927059fe3481113577 100644 --- a/crates/edit_prediction/Cargo.toml +++ b/crates/edit_prediction/Cargo.toml @@ -65,6 +65,7 @@ workspace.workspace = true worktree.workspace = true zed_actions.workspace = true zeta_prompt.workspace = true +zstd.workspace = true [dev-dependencies] clock = { workspace = true, features = ["test-support"] } diff --git a/crates/edit_prediction/src/edit_prediction.rs b/crates/edit_prediction/src/edit_prediction.rs index 1c2d756f2797a4f68d0e1fad9ab69b367b278bc9..f24a39353e65ed5a99a527d62f1138dc6edf4f2f 100644 --- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -1944,11 +1944,15 @@ impl EditPredictionStore { let request = PredictEditsV3Request { input, trigger }; + let json_bytes = serde_json::to_vec(&request)?; + let compressed = zstd::encode_all(&json_bytes[..], 3)?; + Self::send_api_request( |builder| { let req = builder .uri(url.as_ref()) - .body(serde_json::to_string(&request)?.into()); + .header("Content-Encoding", "zstd") + .body(compressed.clone().into()); Ok(req?) }, client, diff --git a/crates/edit_prediction/src/edit_prediction_tests.rs b/crates/edit_prediction/src/edit_prediction_tests.rs index dad91c7fed96eb8f8abcdcf2ced33029e92f1861..19d2532de094b849952ca16c100cf2c8b4a598dc 100644 --- a/crates/edit_prediction/src/edit_prediction_tests.rs +++ b/crates/edit_prediction/src/edit_prediction_tests.rs @@ -1380,7 +1380,8 @@ fn init_test_with_fake_client( "/predict_edits/v3" => { let mut buf = Vec::new(); body.read_to_end(&mut buf).await.ok(); - let req = serde_json::from_slice(&buf).unwrap(); + let decompressed = zstd::decode_all(&buf[..]).unwrap(); + let req = serde_json::from_slice(&decompressed).unwrap(); let (res_tx, res_rx) = oneshot::channel(); predict_req_tx.unbounded_send((req, res_tx)).unwrap();