Skip to content

Performance

Valet streams with no file-size ceiling: volume, rules, compression and storage set speed; record limits, global-rule cardinality and the budget decide fit.

Note

max_record_bytes: 1MiB allows a multi-gigabyte CSV if each row is at most 1 MiB.

Measured 5 GB Parquet workload

SetupValue
Date, machine2026-10-19; Intel Core Ultra X7 358H, 16 logical CPUs, Linux amd64, Go 1.27.2
StorageDisk-backed local (not RAM-backed /tmp)
RunsSingle timed runs, not medians or cold-cache
Input5,003,192,038 bytes, 10,215,424 rows; 512-byte string ID, int64 amount, string status; Snappy
PipelineExplicit schema; not_blank, positive range, allowed status; 512 MiB budget, 8 MiB batches, 1 MiB record limit; all rows pass
BuildConfigured workersFull CLI elapsedPeak process RSS
Before optimizations165.91 s58.7 MiB
Optimized124.61 s89.4 MiB
Optimized417.57 s147.5 MiB
Optimized817.19 s224.9 MiB
  • Timed end to end: startup, decoding, every check, output writes, manifest. Fixture generation excluded.
  • Output: 5,400,820,356 bytes in 41 parts (before: ~5.15 GB in 156); faster Snappy trades size for CPU. Outputs were verified value-for-value against input.
  • The sub-10-second target was not reached; past four workers gains are small (evaluation and output stay ordered single-owner stages) and memory rises.

Comparison with GX Core

Measured 2026-10-26, same workstation, with benchmarks/competitors:

  • 10,000,000 rows: id int64 with nulls, amount decimal(18,2), quantity int64, status string.
  • Checks: id not null, amount 0–10000, quantity 1–1000, status in a fixed set; ~1% of rows fail each.
  • Median of three fresh processes, warm cache; both tools reported the expected failure counts.
InputToolWall timePeak RSS
CSV, 251 MiBValet, 1 worker5.37 s53 MiB
CSVValet, 4 workers3.60 s74 MiB
CSVGX Core 1.24.1 + pandas 3.1.02.71 s1,467 MiB
Parquet, 93 MiBValet, 1 worker3.04 s112 MiB
ParquetValet, 4 workers2.53 s280 MiB
ParquetGX Core + pandas17.22 s2,654 MiB
GX CoreValet
MemoryWhole file in a pandas DataFrameStreams within the managed budget
NotesParquet decimals become Python Decimal (slow); CSV amount compared as float64No rules, 1 worker: 3.8 s CSV, 1.4 s Parquet (CSV reading ≈ 70%)
abc in decimal columnRange expectation errors instead of countingRow fails, cell counted as INGEST_TYPE, run continues
Wrong CSV field countpandas.read_csv raisesExits 2

Schema-only Parquet inspection

valet schema -p pipeline.yml -i input.parquet

Took 0.040 s on the same file, startup included. It reads only the footer: scope: schema, metadata_only: true, validation: not_evaluated, zero checked rows, unverified row count.

Parquet execution costs

  • Full local validation keeps a baseline digest and a final replay digest; page verification is fused into row-group decoding, giving three source passes on the measured plan.
  • S3 identity pinning adds no extra digest scan.
  • MB/s depends on row width and compression; don’t extrapolate from small fixtures. No service-level guarantees.

What changes throughput

FactorEffect
Schema inferenceExtra pass; explicit CSV schema avoids it
Uniqueness, global checksReplay plus cardinality-dependent memory
Wide strings, decimals, timestamps, regexes, conversion failuresHigher per-row cost
Output format, compression, part sizeSink cost
Cold storage, S3 latency, TLS, range requestsCan dominate compute
GzipLower input MB/s
Small filesDominated by startup and publication

Capacity planning

Benchmark the exact pipeline in the target pod and storage with representative data. Keep memory_budget below the pod limit and GOMEMLIMIT with headroom (operations).

Opt-in scale suite:

go test -tags=scale ./benchmarks \
  -run '^TestScale100GiB$' \
  -timeout 0 \
  -v