Skip to content

Operations

Running Valet in pods and batch jobs: memory, storage, signals, logs.

Kubernetes memory

execution.memory_budget is a managed limit, not an RSS cap; leave headroom for the Go runtime, SDK and buffers (memory budget).

Important

Limits are per decompressed row or record, not per file. A 5 GB CSV with ordinary rows fits the 1 GiB profile (slower, not 5 GB of memory).

Pod limitGOMEMLIMITManaged budgetBatch targetMax one CSV rowMax one JSON recordMax one Parquet row/page
512 MiB384 MiB256 MiB4 MiB512 KiB2 MiB4 MiB
1 GiB768 MiB512 MiB8 MiB1 MiB4 MiB8 MiB
2 GiB1.5 GiB1 GiB8–16 MiB2 MiB8 MiB8–16 MiB
resources:
  requests:
    memory: 768Mi
  limits:
    memory: 1Gi
env:
  - name: GOMEMLIMIT
    value: 768MiB
WhatMemory behaviour
max_record_bytesA large ceiling does not by itself mean a large allocation; CSV reservations grow with actual record bytes.
WorkersShare the same managed budget.
Row-local checksStay bounded as file size grows.
Exact uniqueness, reference indexesGrow with distinct keys; can exhaust the budget and fail explicitly (no spilling or approximation).
Parquet row groupsKeep uncompressed ≤ 32 MiB for the 1 GiB profile; large groups can exhaust the guard.
  • Profiles are starting points: measure RSS with your real compression, schemas, output, cardinality and storage before setting production limits.
  • Small-fixture MB/s does not predict runtime; see Performance.

Internals (decoder buffers, queues, reorder state): Engineering spec.

S3

Uses the standard AWS SDK credential chain; never put static credentials in pipeline documents.

TopicBehaviour
SettingsEndpoint, region, path-style addressing and profile, set separately for source and output.
PublicationUnique run prefixes; writes never overwrite.
MultipartAmbiguous uploads are aborted; constrained budgets upload serially.
ReadsAdjacent range reads are coalesced; schema-only inspection reads just the footer.
DigestsPublication and artifact references share one completed digest.

Configure an abort-incomplete-multipart lifecycle rule as a backstop. Write reconciliation and part sizing: Engineering spec.

Local publication

Files are published without replacement and fsynced; manifest.json is written last and marks the commit (Engineering spec).

Metadata trust is not data integrity

  • Schema-only inspection checks metadata, not payload; Parquet statistics can be false in a valid footer.
  • Version pinning and ETags do not prove the statistics match the values.
  • Valet reads values by default. --parquet-stats trusted accepts eligible producer claims with reduced coverage, disclosed in the result and evidence ledger. Read trust and tampering and output modes first.
  • Keep trusted digests, signatures and producer permissions outside the data’s write boundary; an attacker who can replace both file and checksum can fake the evidence.

Signals and cancellation

SignalEffectExit code
SIGINTCancel, close readers/writers, abort known multipart uploads, no terminal manifest130
SIGTERMSame143

Logging

Logs go to stderr; stdout carries only requested output.

valet validate ... --log-format json --log-level info
valet validate ... --log-level debug
ItemDetail
All run recordsrun_id; URIs redacted; row values and credentials never logged.
JSON recordslog_version, event, run-local seq, command identity.
run.phaseWork/queue-wait timings; phases overlap, so not additive CPU.
decode phaseCSV/JSON/NDJSON parsing and batch conversion, once per batch.
run.finishedExit/commit outcome, byte counters, managed peak, coverage.
parquet.stats_decisionPer row group, debug level; raw cells and min/max never logged.
Logging failureDoes not abort validation; exit 3 still reports the committed manifest.

Event schema: validation modes spec.

Why a run failed

With text logs, a failed run (exit 2) ends with an error and, where known, a hint:

valet: error: malformed CSV in data/orders.csv at line 3: found 4 fields; the header has 3
valet: hint: quote any field that contains ",", and check this line for a missing or extra ","; set input.on_malformed: reject to reject such rows and check the rest of the file

With --log-format json, the same information is in the command failed record:

  • error_class: input_format, resource, not_found, access_denied, canceled, deadline or operation.
  • Pipeline load/validation errors show the full message (e.g. unknown field config.rules[0].chekcs (line 5)); other errors show class and typed fields only, to avoid leaking row values.

Malformed input (error_class: input_format) is reported by position and reason, never record contents:

FieldMeaning
input_formatcsv, json or ndjson
input_sourceThe file or object, without credentials or query string
input_line, input_columnWhere the record starts, when known
input_offsetByte offset, when known
framing_reasonfield_count, quote, bare_quote, csv_syntax, blank_line, missing_header, invalid_utf8, record_too_large, json_syntax, truncated, not_array, not_object, trailing_data, multiple_records, multiline_record, duplicate_key or too_deep
expected_fields, found_fieldsHeader and record field counts, for field_count
hintHow to fix the input

Malformed records stop the run; input.on_malformed: reject rejects only wrong-field-count CSV rows (malformed CSV rows).

Health checks for batch jobs

See exit codes for definitions.

ExitTreat asRead
0Completed, warnings allowedstdout JSON or manifest
1Completed, checks failedstdout JSON or manifest
2Failed, no committed manifeststderr
3Manifest committed, stdout failedmanifest
130, 143Interrupted by signal—