Data Engineering Field Notes

Supporting resource

Custom Live Pools and High Concurrency: benchmark details and replication

Selected-run results, notebook timing, cluster allocation, CU accounting, and the protocol behind the v0001 benchmark.

This resource supports v0001: Faster or cheaper?. The original benchmark documents the three selected runs per scenario used in that article: 18 pipelines, 54 notebook activities, 1,530 query executions, and 36 distinct billed notebook sessions. Those measurements were captured on 7 October 2026. A separate 14 October follow-up tests explicit shutdown after the final HC notebook; it does not replace the original results.

The same physical runs determine both latency and CU. Selection was based on pipeline latency, not on choosing the least expensive CU samples. This is a selected comparison, not a statistical guarantee of typical performance. Run labels preserve the original repetition number: SP-R2, for example, is the selected second repetition of SP.

The page contains results and replication instructions, not downloadable notebooks, templates, or raw logs. Workspace-specific identifiers are omitted. The recommendations remain in the article; this page explains what was measured and what can be inferred from it.

Reading guide

Setup and workload

The workspace used an F32 capacity in West Central US and managed private endpoints. SP and SP-HC selected the Starter Pool configuration, but private connectivity required on-demand fallback, not the usual prewarmed Starter Pool startup within seconds. The experiment evaluates CLP where that fast Starter path is unavailable.

ScenarioSelected compute pathPipeline HCNotebook applications per runMaximum hydrated clusters
SPStarter Pool, on-demand fallback; no environmentOff3N/A
ODOn-demand custom pool, published environmentOff3N/A
CLPCustom Live Pool, published environmentOff33
SP-HCStarter Pool, on-demand fallback; no environmentOn1N/A
OD-HCOn-demand custom pool, published environmentOn1N/A
CLP-HCCustom Live Pool, published environmentOn11

Each pipeline ran Bronze, then Silver, then Gold, with no parallel notebook activities. These are stage labels for different TPC-DS query selections, not a claim that the queries reproduce every transformation in a production medallion pipeline.

The workload used LakeBench 1.2.0 and TPC-DS SF100. The same source snapshot and query order were used throughout. Every successful run completed 29 Bronze queries, 28 Silver queries, and 28 Gold queries.

Exact query order

These are the LakeBench query identifiers, including the a/b variants. Do not substitute another query list or sort the identifiers.

{
  "Bronze": ["q13", "q16", "q27", "q28", "q29", "q30", "q37", "q38", "q39b", "q40", "q42", "q43", "q44", "q51", "q53", "q55", "q57", "q58", "q61", "q62", "q63", "q65", "q68", "q69", "q81", "q85", "q88", "q90", "q95"],
  "Silver": ["q8", "q9", "q21", "q24b", "q26", "q32", "q39a", "q46", "q48", "q49", "q54", "q56", "q59", "q60", "q66", "q73", "q76", "q77", "q78", "q79", "q84", "q87", "q89", "q92", "q94", "q96", "q97", "q99"],
  "Gold": ["q12", "q15", "q17", "q18", "q19", "q20", "q22", "q24a", "q25", "q31", "q33", "q34", "q35", "q36", "q41", "q45", "q47", "q50", "q52", "q70", "q71", "q80", "q82", "q83", "q86", "q91", "q93", "q98"]
}

Queries used already prepared tables; data generation was not part of pipeline latency or notebook query execution. Validation confirmed that all 24 queried tables retained the recorded Delta versions and row counts. The source inventory contained 95 Parquet files totaling 31,453,187,652 bytes. The inventory also included its own manifest: its aggregate byte count was not used as a stable fingerprint because it did not reconcile. Actual table versions, counts, and file inventory were the controls.

Each notebook finished when its real work finished. There was no target execution time, padding, fixed-rate CU replacement, or normalization.

Compute and dependency settings

These are configured limits, not the active cluster size at every instant.

SettingRecorded value
Published environment runtime2.0
Starter and custom pool node family / sizeMemoryOptimized / Medium
Pool node autoscaleEnabled, minimum 1 / maximum 10
Configured driver8 vCores, 56g memory
Configured executor8 vCores, 56g memory
Dynamic executor allocationEnabled, minimum 1 / maximum 9
Notebook session keep-alive setting0
Notebook Spark session timeoutspark.synapse.nbs.session.timeout=1200000
CLP and CLP-HC cluster idle timeoutPT50M
CLP and CLP-HC Live Pool lifespanPT2H

CLP and CLP-HC used separate published environments so their maximum hydrated-cluster counts could be three and one respectively. OD and OD-HC used an environment with Custom Live Pool support disabled.

Acceleration and efficient scaledown

The published environments used the following properties. NEE and RSM were also required and verified in the Starter notebook configuration; selecting a pool alone was not considered proof that acceleration was active.

Spark propertyValue
spark.native.enabledtrue
spark.remote.shuffle.enabledtrue
spark.sql.rsm.decisionlayer.enabled.levelstage
spark.sql.adaptive.enabledtrue
spark.sql.adaptive.shuffleWrite.enabledtrue
spark.storage.decommission.shuffleBlocks.enabledtrue
spark.storage.decommission.shuffleBlocks.cleanuptrue
spark.storage.decommission.shuffleBlocks.migrateToFallbackStoragetrue
spark.storage.decommission.fallbackStorage.cleanUptrue
spark.dynamicAllocation.preventShutdownExecutorWithCachefalse
spark.dynamicAllocation.excludeDeltaSnapshotCachetrue

Each stage checked its effective properties and ran a small native-execution probe before the timed query batch. Environment publication and compute readback were verified before submission.

Libraries and initialization

Environment-backed notebooks used published lakebench==1.2.0. Starter notebooks carried pinned wheels, unpacked them locally into a temporary site directory, and used a completion marker to avoid repeated extraction. That bootstrap did not download and resolve packages through a fresh network installation or restart Python.

There were no dedicated bootstrap start/end timers. The CU before the first preflight marker includes initialization, imports, dependency preparation, and bookkeeping; it is not an independently measured library-installation cost. These results cannot establish a universal Starter library surcharge or predict the cost of a fresh network package installation.

Selected results

All CU values below are observed consumption, not proof of complete lifecycle coverage. All times are seconds. Aggregate rows are means of the selected three complete pipeline runs, not per-notebook averages.

Scenario means

ScenarioPipeline latency sSelected latency range sNotebook CU-sEnvironment CU-sObserved notebook + environment CU-s
SP1165.9721128.695-1186.4547542.060N/A7542.060
OD1256.8991214.330-1280.6998085.359Unresolved8085.359
CLP844.230821.485-878.5768669.276678.9489348.224
SP-HC744.350711.255-783.9387528.742N/A7528.742
OD-HC731.734723.054-736.2337819.711Unresolved7819.711
CLP-HC571.869554.411-591.2077221.952227.1957449.148

The article presents these same measurements at lower precision. Figures here are rounded to three decimal places from the original values, so adding displayed components may differ slightly from the displayed subtotal.

Individual selected runs

RunPipeline latency sNotebook CU-sEnvironment CU-sObserved notebook + environment CU-sSeparate pipeline CU-s
SP-R21186.4547869.912N/A7869.91260.480
SP-R31128.6957216.796N/A7216.79660.480
SP-R41182.7667539.472N/A7539.47260.480
OD-R21280.6998209.630Unresolved8209.63060.480
OD-R31275.6698187.454Unresolved8187.45460.480
OD-R41214.3307858.992Unresolved7858.99260.480
CLP-R2832.6288289.559635.0788924.63760.480
CLP-R3878.5768998.016639.5529637.56860.480
CLP-R4821.4858720.254762.2159482.46860.480
SP-HC-R2711.2557282.508N/A7282.50860.480
SP-HC-R3737.8567628.186N/A7628.18660.480
SP-HC-R4783.9387675.533N/A7675.53360.480
OD-HC-R2723.0547805.518Unresolved7805.51860.480
OD-HC-R3736.2337829.048Unresolved7829.04860.480
OD-HC-R4735.9137824.567Unresolved7824.56760.480
CLP-HC-R1554.4117272.879215.0927487.97060.480
CLP-HC-R3569.9887191.092175.4017366.49360.480
CLP-HC-R4591.2077201.886291.0947492.97960.480

Pipeline orchestration CU is separate from the notebook-plus-environment subtotal. An HC notebook session is counted once, even though three activities use it.

N/A means no attached environment. Unresolved means an environment was attached but no separate environment billing events were observed; it does not mean zero environment consumption. For CLP paths, the subtotal includes reported activation consumption, but Ready reporting does not prove that every waiting or idle interval is covered.

Notebook timing and charging

Different clocks answer different questions:

ClockSource and meaning
Pipeline start/endService job timestamps; used for end-to-end pipeline latency
Notebook execution start/endActivity output result.metadata.runStartTime / runEndTime
Query batch start/endWorkload markers around the ordered LakeBench query batch
Spark session start/endLivy startDateTime / endDateTime
Observed first charge interval startBilling operationStartTime
Charge interval endpointNotebook billing consumptionStartTime, checked against duration and preceding endpoint
Event arrivalEventProcessedUtcTime; ingestion time, not execution or charging start

The name consumptionStartTime is misleading for the observed notebook slices: it behaves as an interval endpoint, not the beginning of the charge. Do not use the first received event or its ingestion timestamp as the time charging began.

Selected session timing ranges

Each range is across selected notebook sessions: nine sessions for each isolated scenario, or three shared sessions for each HC scenario. For a shared session, notebook start is the first attached workload’s start and notebook end is the last workload’s end.

ScenarioCharging begins after notebook start sCharging begins after Spark session start sCharging ends after last notebook end sCharge endpoint minus Spark session end s
SP103.172-123.15033.870-35.6303.016-7.4130.151-0.952
OD118.032-142.97253.830-60.0492.781-8.8900.060-0.979
CLP5.092-7.345212.351-857.0691.905-8.9530.030-0.804
SP-HC104.158-173.98434.325-58.29480.965-119.8820.303-0.847
OD-HC122.947-137.19054.894-60.803118.559-123.0420.026-0.708
CLP-HC5.412-7.110252.994-285.21175.119-115.1040.535-0.855

CLP sessions existed before pipeline submission, so their Spark session start is not the notebook execution start. The delay from that earlier session start includes precreated capacity waiting for acquisition; notebook and environment accounting must remain separate.

Charging ended within one second of the recorded Spark session end in all 36 selected sessions. It did not necessarily end when the last query or notebook finished. In shared sessions, CU can also be consumed between notebook activities.

Representative selected sessions

All times below are UTC on 7 October 2026, displayed to millisecond precision with finer digits omitted. For isolated scenarios, these examples show only the Bronze session, not the complete pipeline. For HC scenarios, they show the one application serving all three activities.

Run / stagesFirst notebook startSpark session startCharging beginsLast query batch endsLast notebook endsCharging ends
SP-R4 / Bronze21:55:44.50921:56:54.00021:57:28.85822:01:30.53822:01:37.56422:01:42.150
OD-R4 / Bronze21:33:03.83021:34:12.00021:35:11.55621:39:29.08121:39:34.31521:39:39.354
CLP-R4 / Bronze21:17:01.97221:13:15.00021:17:07.85621:21:04.35421:21:10.47121:21:12.487
SP-HC-R4 / Bronze, Silver, Gold20:19:01.31020:20:57.00020:21:55.29420:31:24.75920:31:29.33720:32:50.303
OD-HC-R4 / Bronze, Silver, Gold20:54:18.61320:55:35.00020:56:35.80321:06:05.99721:06:09.46721:08:08.025
CLP-HC-R4 / Bronze, Silver, Gold20:42:04.20620:37:26.00020:42:11.21120:51:20.00520:51:23.43020:52:38.548

Cluster allocation and notebook CU

CU measures allocated compute over time, not simply CPU utilization or pipeline wall-clock duration.

ScenarioMean summed billed secondsWeighted billed-equivalent vCoresPeak billed-equivalent vCoresMean query batch secondsMean CU-s after notebook completion, approximate
SP787.32919.15924657.553175.735
OD798.64420.24824644.727210.728
CLP789.82021.95332677.255188.031
SP-HC668.64722.51924440.9551170.589
OD-HC694.50422.51924441.4371441.608
CLP-HC632.69322.82924424.9651167.108

For SP/OD/CLP, billed duration and query time sum three distinct sessions; they are not pipeline elapsed time. The last column sums consumption after each stage’s notebook completes. For HC, it represents consumption after the final Gold notebook completes. It is already part of notebook CU, not an extra amount to add to the total.

Approximate CU after notebook completion represented about 15.5-18.4% of observed notebook CU for HC, compared with about 2.2-2.6% for isolated sessions. Phase allocations assume a uniform average rate within each validated billing slice; they are not independently metered phases.

What “cluster size” means here

The driver and first executor shared a physical host in all 36 selected sessions. Their configured 8 vCores must not be added as if they were two separate hosts. Executor registration history was grouped by host to avoid double counting.

Most observed billing intervals were near 4 CU per second, equivalent to 8 billed vCores, or 12 CU per second, equivalent to 24 billed vCores. The selected sessions each reached three registered physical hosts. A driver-host executor being removed does not prove the host was released: the driver can remain there. Likewise, registered executor cores can fall while a larger physical or billed footprint remains allocated.

The weighted billed-equivalent footprint is:

weighted billed-equivalent vCores
  = 2 * total notebook CU-seconds / summed reported billed seconds

This is inferred from metering using 1 CU = 2 Spark vCores; it is not a complete VM history or a measurement of CPU utilization. For a scenario, the ratio uses totals across its selected runs rather than averaging per-run ratios.

Autoscaling, reuse, and dependencies

Within SP/OD/CLP and within SP-HC/OD-HC/CLP-HC, scale-up happened at different times. The resulting differences in time spent at larger allocations are consistent with expected autoscaling variation, not a fixed surcharge for a named pool type.

HC reused an expanded cluster between activities instead of starting every stage with a new, initially smaller application. For SP versus SP-HC, mean summed billed time fell from 787.329 to 668.647 seconds, while weighted billed-equivalent vCores rose from 19.159 to 22.519. Those effects nearly cancel: mean notebook CU changed by about -0.177%, despite the much shorter pipeline latency.

Cold acquisition and context preparation largely preceded the observed notebook charging start. Removing those waits can therefore shorten a pipeline without removing an equal amount of notebook CU. CLP environment consumption still needs to be considered separately.

A fixed-size cluster could reduce scale-up timing variation and make notebook CU more comparable. This test deliberately retained autoscaling to resemble real-world operation; fixed size would still not eliminate differences in query duration, dependencies, or session lifetime.

Accounting and limitations

For portal setup and reusable KQL, see Measure Fabric CU usage with Capacity Operation Events. The rules below explain how those measurements were applied to this benchmark.

Operation ownership and summation

Notebook charges were matched using the workspace, capacity, notebook item, and exact Livy session operation ID. A notebook activity ID is not substituted for the session ID. HC’s shared session was counted once, not once per attached notebook.

Environment charges were matched to the owned SparkPool activation job ID. The billing payload’s activationId is a different identity and was not used as a substitute. CLP’s three warm clusters were represented by distinct events under their activation; the activation sum was not multiplied by three again.

Pipeline activity charges were matched to recorded activity run IDs. The three activities consumed 60.480 CU-s per selected pipeline run, reported separately.

CloudEvent deliveries were deduplicated by root event id, keeping the latest processed copy and rejecting conflicting payloads. Incremental nonzero slices were summed, including both progress and terminal records. Keeping only the final record would discard earlier usage.

CU-seconds = sum(deduplicated, exactly attributed capacityUnitMs) / 1,000
CU-hours   = sum(deduplicated, exactly attributed capacityUnitMs) / 3,600,000

Decimal arithmetic preserved fractional CU-ms. Rounding was applied only for presentation. Events were followed through session closure rather than clipped at pipeline end. Terminal evidence and spaced extraction snapshots were checked for late nonzero increments.

Missing coverage is not zero

ComponentInterpretation
SP/SP-HC environmentNo attachment; not applicable
OD/OD-HC environmentNo separate events observed; unresolved, not verified zero
CLP/CLP-HC environmentReported Startup/Ready events included; Ready durations do not establish the full observed waiting period
Notebook totalsExactly summed reported CU with terminal evidence; not proof that every wall-clock interval was metered
PipelineSeparately observed orchestration CU, excluded from notebook/environment subtotal

The three-minute wait after observed readiness was a submission control, not an assumed charge calculated as three minutes times a fixed CU rate. Missing or unexplained coverage was not filled with estimated usage.

Selected timing and allocation discrepancies

SP-HC-R3: one notebook slice reports 60.188 seconds of duration, but consecutive endpoints differ by 85.276954 seconds: a 25.088954-second mismatch. Its 722.264 CU-s remains in notebook totals, but is not allocated to workload, initialization, or after-notebook phases. Do not invent a charge for the apparent gap. The mean unallocated phase consumption across SP-HC’s selected runs is 240.755 CU-s.

CLP-R4: a 61.646-second slice is near 16 CU per second, equivalent to 32 billed vCores, while captured registration history shows at most three hosts. This is an unresolved allocation/monitoring discrepancy. Allocated-but-not-registered resources or metering semantics are possible explanations, not verified additional physical nodes.

Initialization: mean CU before the first preflight marker was 240.271 for SP, 330.863 for OD, 259.941 for CLP, 161.857 for SP-HC, 130.549 for OD-HC, and 105.986 for CLP-HC. These approximate envelopes include more than library preparation; do not relabel them as library-only charges.

The session collectors waited for natural completion and did not cancel or explicitly stop the measured sessions. CU after notebooks finish is therefore not an artifact of a collector-driven shutdown.

Follow-up: stopping the final HC session

On 14 October 2026, three matched CLP-HC control/stop pairs tested whether notebookutils.session.stop(detach=False) reduces CU consumption after the final notebook. These were six additional runs, not a new selection from the original benchmark.

The test used the same workspace’s active F32 capacity in West Central US, existing published CLP-HC environment, Runtime 2.0, LakeBench 1.2.0, prepared SF100 tables, and exact Bronze/Silver/Gold query order above. Driver/executor sizing, autoscaling, acceleration, and one hydrated cluster were retained. Each pipeline was submitted after the original readiness control: 180 seconds after observing a ready cluster. Owned activation details and preexisting Spark application timestamps confirmed warm acquisition.

Isolated notebook/pipeline copies used a unique session tag per trial. The order was fixed before measurement: control/stop, stop/control, control/stop. Runs were serial, with no other workspace Spark sessions active. Each trial used one shared application for its three activities, distinct from the other five trials. Table IDs, Delta versions, file counts, and byte sizes were checked before each stage and remained unchanged across all six runs. Snapshot checks and durable evidence writes were outside the timed query batches and present in both arms; this instrumentation is another reason not to merge these totals into the original comparison.

Control sessions closed naturally. In the stop arm, Gold first completed and validated its queries, saved results and a UTC shutdown-request marker, then executed this as its final action:

notebookutils.session.stop(detach=False)

The runtime exposed the signature (detach=True). Its help distinguished the default HC behavior, detaching the current notebook, from detach=False, stopping the session. That description was not treated as proof: the experiment followed the actual shared session and its billing operation to closure, without an external cancellation or another stop API.

Observed results

All six pipelines completed, all 18 notebook activities succeeded, and all 510 queries passed the runner’s result checks. All six shared sessions reached Succeeded. The table follows actual execution order; no successful run was excluded.

Pair / armSession ends after Gold sCharging ends after Gold sApproximate CU-s after GoldTotal notebook CU-sEnvironment CU-s
1 / control130.681130.9781,571.74010,068.255291.482
1 / stop18.49519.162229.9448,586.977215.183
2 / stop11.76312.516150.1918,269.000214.346
2 / control77.57678.420941.0378,885.005214.477
3 / control119.280119.7891,437.46710,359.399215.359
3 / stop10.26510.901130.8158,789.137215.215

Here, Gold completion is the final notebook’s service-reported runEndTime, not pipeline end or event arrival. Cross-checking the marker written before the stop call, treatment sessions ended 11.421-19.708 seconds after the shutdown request, and charging ended 12.057-20.375 seconds after it. Billing endpoints were within one second of session end in all six runs.

Mean approximate post-notebook consumption fell from 1,316.748 CU-s for controls to 170.317 CU-s with explicit stop, an 87.1% reduction in this sample. Each matched pair showed a reduction. Shutdown still consumed CU: the call did not immediately deallocate all resources or eliminate the tail. Mean total notebook consumption was 9,770.886 versus 8,548.371 CU-s, but differences in query duration and autoscaling also affect that total; do not attribute every CU of that difference solely to shutdown.

Pipeline orchestration was separately observed at 60.480 CU-s per run. Environment consumption above was attributed to each owned CLP activation; it was not folded into notebook CU, and its variation is not evidence that stopping Gold makes hydration cheaper.

Accounting, scope, and safe use

The Capacity Operation Events method was applied with exact workspace, capacity, item, and operation identities. HC session CU was counted once. Deliveries were deduplicated by CloudEvent ID, checked for conflicting payloads and invalid CU, and incremental progress plus terminal Stopped notebook records were summed. Later extractions checked delayed delivery; the final two snapshots, separated by more than two minutes, had unchanged attributed CU totals for every trial.

Post-Gold CU is a phase estimate, using a uniform average rate within each billing slice, not a separately metered operation. consumptionStartTime again behaved as the notebook slice endpoint. Reported durations reconciled with consecutive endpoints, so no nonzero notebook slice needed to be excluded from phase allocation. Total notebook CU is the direct sum of the attributed events; the phase estimate is already part of it.

One initial setup submission was rejected before a notebook started because its session tag contained hyphens. The tag was corrected to letters, numbers, and underscores, and its unused owned activation was cancelled. That failed setup attempt is not one of the six measured workload runs; its preparation consumption is not included in their totals. A billing-query quoting error and an expired monitoring token were recovered without resubmitting completed or running workloads.

The result confirms this mitigation for the tested CLP-HC pipeline configuration, not a guaranteed saving for every pool, runtime, or workload. Only stop when Gold is known to be the last consumer of the whole shared session, including concurrent branches and future attachments or planned retries. Being the last notebook in one branch is insufficient. Complete required output writes and cleanup before calling it; a subsequent cell must not be needed. If another notebook still needs the session, leave it running rather than destroy its shared application.

Explicit shutdown reduces the final session-retention tail; it does not reverse earlier execution CU, remove gaps between stages, or eliminate CLP preparation and orchestration consumption. The original natural-closure measurements and recommendations above remain intact. After this follow-up, the workspace’s original HC setting was restored, the published environment was unchanged, all experiment-owned activation schedules were disabled, and all owned jobs and sessions were terminal. Inert test copies were retained for snapshot inspection.

How to repeat the benchmark

These instructions reproduce the protocol, not a one-click release of the private runner or a guarantee of identical numbers. Use your own workspace and item identifiers. Fabric runtime, workload data, scaling decisions, capacity competition, and service behavior can change the results.

1. Establish the same scope

Use an isolated, paid F32 workspace with comparable private-connectivity requirements. Without managed private endpoints or other settings that require dedicated provisioning, Starter Pool sessions may use the seconds-fast prewarmed path; that is a different experiment. HC can still be useful there, but CLP no longer removes the same cold-start delay.

Confirm workspace Admin access for configuration changes, the assigned capacity, and the absence of competing workloads. Record the initial Spark settings so they can be restored. Avoid running two trials in parallel when they require different workspace-wide pipeline HC settings.

2. Prepare and freeze SF100 data

Follow the LakeBench TPC-DS workflow to prepare SF100 data and query tables in a lakehouse. Use the same snapshot for all trials, recording each queried table’s Delta version and row count, plus the source-file inventory. Validate them again after the tests.

Regenerating SF100 data alone does not prove it matches the source used here. Keep the generator/version/seed and physical table preparation consistent within your own experiment; report any differences rather than claiming byte-identical replication from the scale factor.

Data generation, dependency downloads, and environment publication must finish before timed pipeline submission.

3. Prepare the compute paths

Configure the Starter selection and a MemoryOptimized Medium custom pool with the recorded autoscale bounds. Create the published on-demand environment and separate CLP/CLP-HC environments; use the library pin and compute properties above.

Use v0002’s REST API workflow for pool/environment configuration, publication, activation scheduling, and readiness monitoring. Read back published settings instead of relying on staged values or an unchanged display name. Record publication versions.

For the Starter selections, do not attach the custom environment. The observed bootstrap uses locally embedded pinned wheels and a completion-marker cache; replacing that with a network install changes the experiment. Verify the effective notebook Spark settings, including the acceleration properties.

4. Build the three-activity pipeline

Use three dependent notebook activities in Bronze/Silver/Gold order, all under the same identity, workspace, and default lakehouse. Parameterize the stage and use its exact ordered query list above. Keep table locations, query selections, and result validation identical across scenarios.

Configure LakeBench’s TPC-DS benchmark for query execution against the prepared source, with scale factor 100, the stage query list, and a unique benchmark run ID. Run the query batch once per activity; do not include data generation or add a sleep to reach a target duration.

The measured runner disabled LakeBench’s modeled dollar-price lookup and cost estimates; CU came from Capacity Operation Events, not a retail-price model. It also adapted optional history-link metadata when a session’s Spark UI URL lacked the GUID shape expected by LakeBench 1.2.0, restoring the original property after construction. These were compatibility adjustments, not query or timing normalization. If your pinned version needs such adjustments, document them; do not report constructor pricing placeholders as observed costs.

Record before/after query-batch UTC timestamps and a monotonic elapsed timer. Persist the ordered query list or its checksum, result count, failures, duplicates, effective settings, application identity, notebook identity, and environment identity. Verify native execution with a small preflight probe outside the timed query batch.

5. Control sharing and warm readiness

Turn pipeline HC off for SP/OD/CLP, and on for SP-HC/OD-HC/CLP-HC. Use one unique session tag per HC trial, shared by that trial’s three activities; never reuse it to accidentally attach to an earlier run. Confirm one application for HC and three distinct applications for isolated sessions.

For CLP paths, monitor the owned activation with job type SparkPool. Record the first UTC observation with at least one ready cluster, then submit the pipeline 180 seconds after that observation. This uses observed readiness, not a claim to know the exact instant a cluster became ready.

Verify the warm handoffs: CLP must acquire three intended precreated applications, while CLP-HC must use one shared application. Record the owned activation, readiness samples, actual submission time, acquisition state, and preexisting Spark application start. A missing warm handoff is not silently accepted as a CLP result.

6. Execute and validate

Run trials serially, waiting for each trial’s pipeline and session lifecycle to finish before changing shared workspace settings or starting the next trial. Pipeline activities and all 85 queries must succeed. Check query order/count, missing or duplicate results, environment/pool routing, acceleration, and expected application sharing.

Prespecify the repetitions and any selection policy before examining comparative results. Use the same selected physical runs for latency and CU. Do not independently choose cheaper CU samples.

7. Collect lifecycle and CU evidence

Record pipeline, activity, notebook, environment publication, Livy session, Spark application, and owned activation identities privately. Capture notebook metadata, workload markers, session details, executor add/remove history, resource allocation samples, and available driver logs. Explicitly record unavailable monitoring data instead of treating it as absence of work.

Wait for natural session closure; do not stop a session simply because Gold completed. Match billing operations using the exact identities described above, sum deduplicated incremental events, and require terminal evidence. Take at least two extraction snapshots separated by two minutes and investigate new nonzero increments before finalizing totals.

Keep environment and orchestration consumption separate from notebook consumption. Do not clip charges at pipeline end, substitute fixed CU rates, or turn unresolved component coverage into zero. Configuration and querying of Capacity Operation Events are a separate monitoring topic; this page records the accounting rules used for the comparison.

8. Restore and interpret

Disable activation schedules owned by the experiment, confirm no sessions or pending pipeline jobs remain, and restore the original default pool and HC setting without overwriting unrelated changes.

Compare latency alongside the time-integrated allocation and CU used after notebooks finish. Report the selected-run sample size and coverage limits. Use the observations to evaluate your own service-level objective and capacity headroom, not to promise that one pool configuration is universally cheapest.

References