ScanTwin: Simulating Performance Regressions
Without Access to Tenant Data


Abstract

In cloud data platforms, developers often encounter performance regressions that occur in specific tenant datasets. However, due to confidentiality constraints, they cannot access the original data, which makes it difficult to reproduce these regressions locally. Current methods for synthetic data usually focus on statistical properties, such as matching data distributions or improving query accuracy. However, they overlook the physical properties that control how the engine behaves during scans, including row-group pruning.

We propose ScanTwin, a lightweight framework that extracts a per-row-group sketch from the Parquet footer, including boundary values and compressed sizes, and releases them under \(\varepsilon\)-differential privacy using a boundary parameterization. On TPC-H and SSB (6M rows), ScanTwin achieves 0% pruning error and less than 1% byte error at \(\varepsilon{=}\infty\). Under \(\varepsilon{=}5\), high-selectivity queries (\(>\)​30%) incur below 8.5% pruning error on both datasets, and per-query scan timing on DuckDB closely tracks the original.

1 Introduction↩︎

Cloud data platforms often experience performance regressions that affect only specific tenant datasets. Diagnosing such regressions requires reproducing the original execution behavior, but privacy rules prevent the development team from accessing the original data. Therefore, they need synthetic data that triggers the same engine behavior as the original.

The main reason current synthetic data fails to reproduce performance is that it ignores the physical layout of files. Most existing methods [1][3] focus only on statistical fidelity, like matching data distributions or query counts. But in columnar engines like DuckDB, the scan operator reads per-row-group (RG) statistics from the Parquet footer and skips any RG whose value range does not match the query predicate. If the synthetic file does not have the same physical arrangement of values, the engine will scan every RG even if the authentic data would have pruned them. The key problem is not just the values themselves, but where they are partitioned across RGs.

In this paper, we focus on scan-level behavior because the scan operator determines which RGs are read from storage, bounding the I/O cost of all downstream operators. Since joins and aggregations require additional state that cannot be recovered from a Parquet footer, we defer them to future work.

To solve this, we develop ScanTwin, a lightweight framework that uses the Parquet footer. ScanTwin extracts a per-RG sketch of the file, including min/max boundaries and compressed sizes, and we protect this information with \(\varepsilon\)-differential privacy (DP) [4]. Boundary parameterization is a key idea that reduces \(2K\) min/max values to \(K-1\) interior values, maintaining the accuracy of the synthetic file while minimizing DP noise. Our contributions are:

  • We formalize engine reaction equivalence using RGs scanned and bytes read as proxies for scan-level performance, enabling developers to reproduce and diagnose regressions without accessing the original data (§2).

  • We design a boundary parameterization for the DP sketch that fixes the outer limits and only noises the \(K{-}1\) interior points, with \(\varepsilon\)-DP guaranteed via the bounded Laplace mechanism (§3.2).

  • On TPC-H and SSB, ScanTwin closely reproduces per-query scan timing on DuckDB. At \(\varepsilon{=}5\), pruning error for high-selectivity queries stays below 8.5% for both datasets (§4).

2 Problem↩︎

Setting. Given a confidential Parquet dataset \(D\), a scan-heavy workload \(W\), and a privacy budget \(\varepsilon\), we extract a compact execution-relevant sketch \(\mathcal{S} = \mathrm{\small Sketch}(D)\) inside the trusted environment. The sketch is then released with \(\varepsilon\)-DP noise and used to generate \(D'\) on an untrusted machine.

Goal (Engine Reaction Equivalence). For each query \(q \in W\), the physical execution profile on \(D'\) should approximate that on \(D\): \(\mathrm{\small Profile}(q, D) \approx \mathrm{\small Profile}(q, D')\). Here, \(\mathrm{\small Profile}\) captures scan-level signals such as the number of RGs scanned and the bytes read. By reproducing these signals, ScanTwin ensures that the engine makes the same pruning decisions and incurs similar I/O volume as on the original data. In practice, high-selectivity queries dominate the workload’s cost: a query scanning 40-60 RGs incurs substantially more I/O than one scanning 1-2 RGs. ScanTwin therefore focuses on these high-cost queries, where regressions have a large impact.

3 Synthesis↩︎

The ScanTwin framework follows a three-stage process: (1) sketch extraction from the Parquet footer, (2) DP noise application, and (3) synthetic Parquet generation.

3.1 Sketch Extraction↩︎

Given a Parquet file sorted on the filter column \(c\), we read only the file footer, not the data pages, and record three values per RG \(i\):

  • \(\mathsf{min}_i, \mathsf{max}_i\): the minimum and maximum of column \(c\) in RG \(i\), read from the Parquet footer statistics.

  • \(\mathsf{size}_i\): the total compressed size (bytes) of RG \(i\).

Figure 1 illustrates this layout. Only the filter column’s per-RG metadata is extracted; other columns are ignored at sketch time. The sketch \(\mathcal{S}\) is composed of the row count \(N\), the number of RGs \(K\), and the column count. Since Parquet stores statistics in the footer, we extract the sketch without reading data pages. Sorting by the filter column is standard practice (e.g., Snowflake clustering keys [5], Databricks Z-order [6]), and is necessary for effective zone-map pruning, the target behavior ScanTwin reproduces.

We treat the compressed storage size \(\mathsf{size}_i\) as the sensitive information that requires protection through DP. For the Parquet writer, we use a fixed row count for each RG (\(RG\_size = n\)), following DuckDB’s recommendation [7] of 100K–1M rows. While \(n\) is public (derived from \(N\) and \(K\)), the compressed size \(\mathsf{size}_i\) is sensitive as it depends on the entropy of the tenant data.

3.2 Differentially Private Sketch↩︎

Public metadata and trust model. Sketch extraction and noise injection occur within a trusted boundary managed by the tenant. Once the noise is added, the sketch can be safely shared with anyone. This is because it contains only per-RG aggregate statistics, not individual records, and the synthetic file is a deterministic function of the noisy sketch, revealing no additional information beyond what the DP release already protects.

We assume the following as public: (1) The domain of the filter column \([d_L, d_U]\). (2) The query workload \(W\). (3) The maximum multiplicity \(m\) (the highest number of times any single value appears). If \(m\) is unknown, we can safely use the row count per RG (\(m = n\)). Only the actual data \(D\) is confidential. Our method provides pure \(\varepsilon\)-DP, secure against a computationally unbounded adversary.

Table 1: Sketch contents.
Level Feature Role
File-level \(N\) (total rows) Scan volume
\(K\) (number of RGs), RG size Pruning granularity
Column count, codec I/O width, decode cost
Per-RG \(\mathsf{min}_i, \mathsf{max}_i\) (filter col) Pruning decisions
\(\mathsf{size}_i\) (compressed bytes) Per-RG I/O cost

Neighboring relation. Neighboring datasets are defined as those that differ by the value of a single row within a fixed positional RG assignment. Rows are assigned to RGs by position (rows \(1 \ldots n\) to RG 1, rows \(n{+}1 \ldots 2n\) to RG 2, and so forth), and a neighboring dataset replaces the value of one row while preserving its RG assignment. Because RGs are disjoint, modifying a single row affects only the min, max, and size of that specific RG.

Figure 1: ScanTwin’s sketch over a Parquet file.

Boundary parameterization. In a sorted file, boundaries of neighboring RGs are usually similar, with \(\mathsf{max}_{i-1} \approx \mathsf{min}_{i}\). Instead of noising \(\mathsf{min}\) and \(\mathsf{max}\) separately for every RG and then repairing inconsistencies, we use a single boundary-based representation. We fix the outermost points to the public domain limits, namely \(\beta_0 = d_L\) and \(\beta_K = d_U\), and treat only the \(K-1\) internal boundaries as parameters, with each \(\beta_i\) corresponding to \(\mathsf{max}_i\). In this notation, \(i\)th RG is \(\mathrm{RG}_i=[\beta_{i-1},\,\beta_i]\). Since the endpoints are already public, they do not need to be perturbed, so noise is applied only to the internal boundaries. This lowers the number of noisy values from \(2K\) to \(K-1\). It also enables an even split of the privacy budget across all RGs.

Privacy budget. Since the \(K\) RGs are disjoint subsets, parallel composition [8] lets every RG use the full privacy budget \(\varepsilon\). Within each RG, we release two statistics (\(\beta_i\) and \(\mathsf{size}_i\)) and split the budget evenly via sequential composition [4], allocating \(\varepsilon/2\) to each.

Sensitivity. The sensitivity of an interior boundary \(\beta_i\) represents the maximum possible shift caused by changing a single row. If the data has duplicates, changing one row can move the boundary by at most the number of times that specific value appears (\(m\)). Since boundaries are constrained to the public domain, we cap sensitivity at the domain width: \(\Delta_\beta = \min(m,\, d_U - d_L)\). In practice, \(m\) is conservative for skewed distributions; tighter bounds via DP histograms [9] are deferred to future work. For the compressed size, changing one row affects the RG’s size by at most the size of one uncompressed row: \(\Delta_s = \frac{\sum_{c \in \mathrm{Cols}} \mathsf{UncompressedSize}(c)}{n}\).

Figure 2: DP Sketch Release

Noise mechanism (Algorithm 2). We release each interior boundary using the bounded Laplace mechanism of Holohan et al. [10], which samples from a Laplace distribution conditioned on the public domain \([d_L, d_U]\) via inverse CDF transform. The mechanism’s noise scale \(b^*\) is computed via the fixed-point iteration of [10], which yields the smallest \(b\) guaranteeing pure \(\varepsilon\)-DP. When \(\Delta_\beta = d_U - d_L\), this reduces to the standard Laplace scale \(b^* = b_0 = \Delta_\beta / \varepsilon_\beta\) exactly [10] Lemma 4.2. Otherwise, \(b^*\) is modestly larger. In our experiments, the noise inflation \(b^*/b_0\) is exactly \(1.0\) on TPC-H (where the cap binds at \(\Delta_\beta = d_U - d_L\)) and remains below \(1.009\) on SSB across all \(\varepsilon \geq 0.01\). Compressed sizes are released analogously on \([0, \infty)\), where the inflation is negligible since size values are far from the lower bound.

After noising, we sort \((\tilde{\beta}_1, \ldots, \tilde{\beta}_{K-1})\) in ascending order to restore monotonicity. Sorting is a deterministic function of the noisy boundaries and incurs no extra privacy cost. The outer boundaries \(\beta_0 = d_L\) and \(\beta_K = d_U\) are public constants and require no repair.

3.3 Synthetic Parquet Generation↩︎

Using the noisy sketch, we build a replacement Parquet file. This new file is designed to trigger the same pruning results and I/O workload as the original data.

Step 1: Filter column. For each RG \(i\), we pick \(n\) values uniformly from the estimated domain \([\tilde{\beta}_{i-1},\, \tilde{\beta}_i]\) and sort within the group. This ensures the Parquet writer populates the footer with min/max statistics, so the engine’s zone-map pruning yields skip-or-scan decisions that closely match those in the original.

Step 2: Padding columns. We add \(C{-}1\) padding columns of random bytes to match each RG’s target compressed size. Because ZSTD overhead varies with payload, we use a two-pass calibration: write an initial estimate (with compressed size \(\mathit{base}_i\) from the filter column alone), measure the output, then adjust the padding to reach the noisy target \(\tilde{\mathsf{size}}_i\). This uses only the noisy sketch and codec behavior, consuming no additional privacy budget: \(\mathit{pad}_i = \max\bigl(0,\;\tilde{\mathsf{size}}_i - \mathit{base}_i\bigr)\).

Step 3: Write. The synthetic file uses the same RG size and ZSTD codec as the original. The synthetic data is semantically neutral. Dummy values are random, and filter column values only need to fall within the estimated range. Our main goal is to ensure the query engine maintains identical pruning decisions and I/O volumes.

Table 2: Full comparison at \(\varepsilon{=}\infty\) (no privacy).
Dataset Method MAPE-RG MAPE-Bytes
TPC-H Random 3,631% 5,274%
Marginal 3,616% 5,274%
Sorted-Global 28.5% 88.4%
ScanTwin-MinMax 0.0% 7.9%
ScanTwin-Full 0.0% 0.2%
SSB Random 1,421% 1,760%
Marginal 1,431% 1,818%
Sorted-Global 0.0% 35.1%
ScanTwin-MinMax 0.0% 10.4%
ScanTwin-Full 0.0% 0.2%

4 Experimental Results↩︎

We evaluate ScanTwin on: (1) pruning and I/O fidelity compared to layout-unaware baselines, (2) the privacy–utility tradeoff, (3) engine-level validation, and (4) sensitivity to the multiplicity bound \(m\).

4.1 Setup↩︎

We assess ScanTwin using two standard analytical benchmarks: TPC-H lineitem (6M rows, filter on l_shipdate[11] and SSB lineorder (6M rows, filter on lo_orderdate[12]. Both are sorted by the filter column and written as Parquet with 100K rows per RG (61 RGs each) and ZSTD compression. All experiments use WHERE col\(\leq\)cutoff queries at selectivities log-spaced from 0.1% to 95%. For privacy analysis, we report mean \(\pm\) std over five seeds (42, 7, 2025, 777, 867). Engine validation runs on DuckDB (v1.4.4), single-thread, 4 GB RAM, and reports median of five runs per query.

Metrics. MAPE-RG: mean absolute percentage error in RGs scanned (pruning fidelity). MAPE-Bytes: error in compressed bytes read (I/O fidelity). For engine validation, we report per-query scan times and total workload time ratio (synthetic/original).

Methods. We compare against Random (unsorted uniform), Marginal (global histogram), Sorted-Global (globally sorted, no per-RG metadata), ScanTwin-MinMax (per-RG bounds, uniform padding), and ScanTwin-Full (per-RG bounds, two-pass calibrated padding). All methods share the same schema, row count, codec, and RG size.

4.2 Layout-Aware vs.Layout-Agnostic Synthesis↩︎

Table 2 isolates layout reproduction from DP noise (\(\varepsilon{=}\infty\)). Random and Marginal scan all 61 RGs (MAPE-RG \(>\)​1,400%). Both ScanTwin variants achieve 0% MAPE-RG. Sorted-Global reaches 28.5% on TPC-H; its 0% on SSB is coincidental, as the near-uniform date distribution matches uniform sampling. ScanTwin-Full’s 0.2% MAPE-Bytes vs.Sorted-Global’s 35.1% on SSB confirms that per-RG size calibration is essential for I/O fidelity.

4.3 Privacy-Utility Tradeoff↩︎

Figures 3 and 4 use ScanTwin-Full; shaded bands show mean \(\pm\) std over five seeds. Figure 3 fixes \(m_{actual} = 2{,}707\) (TPC-H) and \(m_{actual} = 2{,}531\) (SSB) and varies \(\varepsilon\); Figure 4 fixes \(\varepsilon{=}5\) and varies \(m\).

Privacy budget impact. A single aggregate MAPE-RG can be misleading: at low selectivity, an off-by-one error (1\(\to\)​2 RGs) yields 100% APE. At \(\varepsilon{=}5\), MAPE-RG for high-selectivity queries (\(>\)​30%) is only \(6.4\%\) (TPC-H) and \(8.3\%\) (SSB), well within practical tolerance. Mid-selectivity (5–30%) reaches \(42.9\%\) and \(19.6\%\), while low-selectivity (\(<\)​5%) is highest at \(70.9\%\) and \(27.8\%\). As \(\varepsilon\) increases, all bands converge to 0% at \(\varepsilon{=}\infty\). SSB outperforms TPC-H despite similar domain widths (\(\approx\)​2,553 days) and noise scales. The gap reflects TPC-H’s more variable per-RG boundary spacing (coefficient of variation \(0.25\) vs.\(0.13\)), making tightly packed boundaries more susceptible to noise displacement at low and mid selectivities. Workload-proportional budget allocation is a natural extension that we leave to future work.

Sensitivity to \(m\) (Figure 4). When \(\varepsilon{=}5\), MAPE-RG grows as \(m\) increases. At \(m{=}10\), the error is \(4.2\%\) on TPC-H and \(1.5\%\) on SSB. At \(m{=}100\), the errors rise to \(14.5\%\) and \(14.1\%\). This happens because the noise scale grows with sensitivity \(\Delta_\beta = \min(m,\, d_U - d_L)\), so a higher multiplicity bound increases boundary perturbation until the cap binds at the domain width. If domain knowledge allows for a small \(m\), ScanTwin still provides strong utility even when \(\varepsilon\) is low.

Figure 3: MAPE-RG vs.\varepsilon broken down by selectivity.
Figure 4: MAPE-RG vs.declared m at \varepsilon{=}5.

4.4 Engine Validation↩︎

Table 3 shows median scan times per selectivity band at \(\varepsilon{=}5\). High-selectivity queries are well-reproduced by ScanTwin, consistent with their low MAPE-RG of 6.4% and 8.3%. Low-selectivity queries exhibit higher MAPE-RG values but only minor absolute timing differences (e.g., 1.4% on TPC-H), since scanning one or two RGs consistently takes only a few milliseconds. Consequently, a \(\pm\)​1 RG error has minimal impact on wall-clock time at this scale. These results confirm that ScanTwin reproduces scan timing for high-selectivity queries, the regime where I/O cost is largest and performance regressions have the greatest impact.

Table 3: DuckDB scan times at \(\varepsilon{=}5\). (ms)
TPC-H SSB
2-4(lr)5-7 Band Orig. ScanTwin Diff. Orig. ScanTwin Diff.
Low (\(<\)​5%) 3.59 3.54 \(1.4\%\) 4.63 4.22 \(8.8\%\)
Mid (5–30%) 5.34 5.12 \(4.2\%\) 5.90 5.70 \(3.3\%\)
High (\(>\)​30%) 13.37 13.44 \(0.5\%\) 12.33 12.17 \(1.4\%\)

5 Related Work↩︎

Query performance regression diagnosis. APOLLO [13] automates regression detection in DBMSs through domain-specific fuzzing and statistical debugging. Other recent work [14] has used pattern-based detection to see how structural changes in query plans affect performance after index tuning. These methods assume access to engine internals or execution traces for diagnosis. ScanTwin addresses a complementary scenario. The developer cannot access the original data at all. Instead, we show how to reproduce the physical I/O behavior using only a privacy-protected sketch.

Privacy-preserving benchmarks. PrivBench [1] uses sum-product networks to ensure the synthetic data matches the original distribution and query runtime. More broadly, methods based on marginals [2], graphical models [3], and GANs [15] target statistical utility or downstream ML accuracy. These approaches treat the data as a logical object and write it to storage in whatever layout the system chooses. ScanTwin differs fundamentally: we treat the physical storage layout as the target, reproducing per-RG zone maps and compressed sizes rather than value distributions.

6 Conclusion↩︎

We presented ScanTwin, a framework that reproduces scan-level engine behavior using a privacy-protected Parquet footer sketch. Our results on TPC-H and SSB demonstrate that capturing physical layout metadata, rather than just data distributions, is key to matching engine behavior, achieving 0% pruning error at \(\varepsilon{=}\infty\). We provide pure \(\varepsilon\)-DP guarantees via the bounded Laplace mechanism, with sensitivity capped at the public domain width. Under DP noise, utility is governed by the multiplicity bound \(m\). For datasets with low multiplicity, ScanTwin achieves strong pruning fidelity even at small \(\varepsilon\), while high-selectivity queries remain well-reproduced across both benchmarks at \(\varepsilon{=}5\). Tighter sensitivity bounds via DP histograms are a promising direction for future work, alongside extending support to multi-column predicates and downstream operators like joins.

This work was supported in part by NSF awards CNS-1846447 and CNS-2016240.

References↩︎

[1]
Y. Ge et al., “Privacy-enhanced database synthesis for benchmark publishing,” Proceedings of the VLDB Endowment, vol. 18, no. 2, pp. 413–425, 2024, doi: 10.14778/3705829.3705855.
[2]
R. McKenna, B. Sheldon, and G. Miklau, “AIM: An adaptive and iterative mechanism for differentially private synthetic data,” in Proceedings of the 39th international conference on machine learning (ICML), 2022.
[3]
J. Zhang, G. Cormode, C. M. Procopiuc, D. Srivastava, and X. Xiao, “PrivBayes: Private data release via bayesian networks,” ACM Transactions on Database Systems, vol. 42, no. 4, 2017.
[4]
C. Dwork, F. McSherry, K. Nissim, and A. Smith, “Calibrating noise to sensitivity in private data analysis,” in Theory of cryptography, 2006.
[5]
“Clustering keys & clustered tables.” https://docs.snowflake.com/en/user-guide/tables-clustering-keys, 2024.
[6]
“When to partition tables on Databricks.” https://docs.databricks.com/aws/en/tables/partitions, 2024.
[7]
“File formats — DuckDB documentation.” https://duckdb.org/docs/stable/guides/performance/file_formats, 2024.
[8]
C. Dwork and A. Roth, “The algorithmic foundations of differential privacy,” Foundations and Trends in Theoretical Computer Science, vol. 9, no. 3–4, pp. 211–407, 2014.
[9]
J. Xu, Z. Zhang, X. Xiao, Y. Yang, G. Yu, and M. Winslett, “Differentially private histogram publication,” The VLDB Journal, vol. 22, no. 6, pp. 797–822, 2013, doi: 10.1007/s00778-013-0309-y.
[10]
N. Holohan, S. Antonatos, S. Braghin, and P. Mac Aonghusa, “The bounded laplace mechanism in differential privacy,” Journal of Privacy and Confidentiality, vol. 10, no. 1, 2019, doi: 10.29012/jpc.715.
[11]
Transaction Processing Performance Council, TPC-H benchmark specification,” Published at http://www.tpc.org, 2023.
[12]
P. O’Neil, B. O’Neil, and X. Chen, “Star schema benchmark,” University of Massachusetts at Boston, Revision 3, 2009.
[13]
J. Jung, H. Hu, J. Arulraj, T. Kim, and W. Kang, “APOLLO: Automatic detection and diagnosis of performance regressions in database systems,” Proceedings of the VLDB Endowment, vol. 13, no. 1, pp. 57–70, 2020.
[14]
W. Wu, A. Dutt, G. Xu, V. Narasayya, and S. Chaudhuri, “Understanding and detecting query performance regression in practical index tuning,” Proceedings of the ACM on Management of Data (SIGMOD), vol. 3, no. 6, 2026.
[15]
L. Xie, K. Lin, S. Wang, F. Wang, and J. Zhou, “Differentially private generative adversarial network,” arXiv preprint arXiv:1802.06739, 2018.