Skip to main content

Workload Utility

CamusDB.Workload is a source-tree utility for validating and measuring a CamusDB server with a deterministic mixed workload. It creates a repeatable dataset, runs read/write traffic through the CamusDB client protocol, verifies the result, and writes artifacts that can be compared across server builds or configuration changes.

Use it when you want to:

  • check that a local or test deployment can handle concurrent reads and writes
  • compare gRPC and REST client behavior
  • measure the effect of configuration changes such as WAL or optimizer settings
  • collect a repeatable evidence bundle for performance diagnosis

The utility lives in the CamusDB source repository as CamusDB.Workload.

Dataset

The workload uses a deterministic table named workload_accounts:

CREATE TABLE workload_accounts (
id OID PRIMARY KEY,
owner INT64 NOT NULL,
balance INT64 NOT NULL,
version INT64 NOT NULL,
payload STRING NOT NULL
);

CREATE INDEX workload_accounts_owner ON workload_accounts (owner);

Rows, ids, balances, owners, and payloads are generated from the configured seed, row count, and payload size. The same inputs produce the same dataset fingerprint every time, which lets run verify that it is measuring the data shape it expects.

Setup and reconciliation happen outside the measured interval.

Initialize

Run init once to create the database, table, index, and seed data:

dotnet run -c Release --project CamusDB.Workload -- init \
--endpoint http://127.0.0.1:5096 \
--database workload \
--protocol grpc \
--rows 100000 \
--payload-bytes 256 \
--batch 500

init is idempotent. If the schema and expected rows already exist, it can be run again without changing the measured workload.

Common options:

OptionDefaultMeaning
--endpointrequiredServer endpoint. Use the gRPC port for --protocol grpc, for example http://127.0.0.1:5096.
--databaserequiredDatabase used by the workload.
--protocolgrpcClient protocol: grpc or rest.
--seed1847Deterministic seed for ids, payloads, and operation selection.
--rows100000Number of rows in workload_accounts.
--payload-bytes256Payload string size per row.

Run

The run verb validates the dataset, warms up, runs the measured interval, drains in-flight work, reconciles correctness, and writes output files.

Open-loop mode submits a target number of operations per second:

dotnet run -c Release --project CamusDB.Workload -- run \
--endpoint http://127.0.0.1:5096 \
--database workload \
--protocol grpc \
--output /tmp/camus-workload-run \
--mode open \
--target-ops 800 \
--workers 64 \
--connections 8 \
--duration 5m \
--warmup 30s \
--drain 10s

Closed-loop mode keeps a fixed number of workers busy and is useful for finding a saturation point:

dotnet run -c Release --project CamusDB.Workload -- run \
--endpoint http://127.0.0.1:5096 \
--database workload \
--protocol grpc \
--output /tmp/camus-workload-closed \
--mode closed \
--workers 64 \
--connections 8 \
--duration 5m \
--warmup 30s

Run options:

OptionDefaultMeaning
--outputrequiredOutput directory for artifacts. It must not already exist.
--modeopenopen for target-rate load, closed for worker saturation.
--target-ops800Open-loop submitted operations per second.
--workers64Concurrent workers.
--read-percent60Percent of operations that are read-only point reads.
--write-percent40Percent of operations that are write transactions. Must make the read/write total equal 100.
--writes-per-transaction1Row updates per write transaction.
--duration5mMeasured interval.
--warmup30sWarm-up before measurement.
--drain10sOpen-loop drain window after measurement.
--connections8Number of read connections and write connections opened by the client.
--max-in-flight4096Open-loop cap for pending plus in-flight operations before schedule drops are counted.
--init-if-missingfalseCreate and seed the dataset before the run if it is absent. Setup is still outside measurement.

The write side uses optimistic read/write transactions. The baseline workload shards writers so independent workers should not update the same rows. In that non-conflicting baseline, conflicts are reported as invalidating evidence rather than hidden by retries.

Output Artifacts

A successful run writes:

FileContents
manifest.jsonTool version, endpoint, protocol, workload shape, runtime, and dataset fingerprint.
summary.jsonMachine-readable throughput, latency, error, and validity summary.
summary.mdHuman-readable run summary.
intervals.csvPer-second offered, started, completed, failed, in-flight, and latency samples.
errors.jsonError counts and sampled messages grouped by error code.
reconciliation.jsonCorrectness verification for committed writes and final row versions.

The process exits with a non-zero code when the run is invalid or reconciliation fails.

Bottleneck Report

If the server exposes Prometheus metrics, report can combine a workload run with a /metrics scrape:

dotnet run -c Release --project CamusDB.Workload -- report \
--output /tmp/camus-workload-run \
--metrics /tmp/server-metrics.txt

This writes bottleneck-report.md in the run directory. The report compares client throughput and latency with server request, execution, scan, transaction, runtime, Kahuna, and Kommander metrics. It is diagnostic evidence: use it to see which measured stages deserve attention before tuning.

For one-command local collection, see Performance Diagnostics.

Cleanup

cleanup drops only the explicitly confirmed workload database:

dotnet run -c Release --project CamusDB.Workload -- cleanup \
--endpoint http://127.0.0.1:5096 \
--database workload \
--protocol grpc \
--confirm workload

The command refuses empty, default, system, or unconfirmed database names.