Benchmark Telemetry Ingestion and Query Performance
A useful benchmark is a reproducible measurement with disclosed conditions, not a single fast screenshot. This guide provides a bounded client-side harness for the public Log and Query APIs and explains what its numbers do and do not prove.
Telemetry does not publish a performance claim from this harness until the exact script, environment, event shape, row count, time, result, and limitations are retained together.
Questions to answer before running
Choose one question:
- How long does this client take to submit a known synthetic batch?
- How quickly can a query read the just-submitted run with realtime data enabled?
- How does payload width change client-observed ingest time?
- How do query time window, selected columns, and grouping cardinality affect response time?
Do not mix all of these into one “speed” number. A client wall-clock measurement includes network distance, TLS, local scheduling, and serialization in addition to service time.
Safety and scope
The included harness writes synthetic rows to telemetry_benchmark_events. It refuses to run unless:
TELEMETRY_API_KEYis set at execution time;--confirm-writeis present;- the requested row count is between 1 and 10,000.
Use a dedicated test team or API key. The script does not delete rows. Apply the table’s normal retention policy or remove test data later through an approved data-management process.
The environment variable is optional for the website and application. It becomes required only when a person deliberately executes the benchmark script.
Run the bounded harness
From this repository:
TELEMETRY_API_KEY="YOUR_TEST_KEY" \
node scripts/benchmark-telemetry-api.mjs \
--confirm-write \
--rows 500 \
--batch-size 100
The output is one JSON document containing:
- an opaque
run_id; - UTC start and finish times;
- requested rows and batch size;
- total payload bytes;
- client-observed ingest wall time;
- calculated rows per client wall-clock second;
- client-observed query wall time;
- the query result for that run.
Redirect the output into agent_space/ if you want to compare local runs without committing diagnostic data:
node scripts/benchmark-telemetry-api.mjs \
--confirm-write \
--rows 500 \
--batch-size 100 \
> agent_space/benchmark-500.json
What the script sends
Every row uses a deterministic shape:
{
"run_id": "unique-per-run",
"sequence": 42,
"event_name": "benchmark_request_completed",
"route": "/synthetic/orders",
"region": "test-west",
"status_code": 200,
"latency_ms": 47,
"payload_size_bytes": 768,
"success": true
}
Values vary by sequence using a deterministic formula. The run therefore contains successful and failed rows plus bounded latency values, without random customer-like data.
The verification query is:
SELECT
COUNT(*) AS rows_observed,
SUM(CASE WHEN success THEN 1 ELSE 0 END) AS successful_rows,
AVG(latency_ms) AS average_synthetic_latency_ms,
MAX(sequence) AS maximum_sequence
FROM telemetry_benchmark_events
WHERE run_id = 'RUN_ID';
latency_ms is a synthetic payload field. It does not represent Telemetry service latency. The query and ingest wall times measured by the harness are separate fields.
Reproducibility record
Keep this context with every result:
| Field | Why it matters |
|---|---|
| script commit | identifies the exact generator and timer |
| UTC timestamp | anchors service version and external conditions |
| client region and runtime | explains network and local differences |
| API origin | separates production, staging, and local tests |
| rows and batch size | changes request count and payload size |
| event schema | affects serialized width and table shape |
| table state and retention | can affect query scan work |
| SQL and realtime option | defines the measured query |
| warmup policy and repetitions | separates cold behavior and variance |
| median and tail values | avoids choosing one favorable run |
For comparative results, alternate candidates instead of running all trials for A and then all trials for B. External load can drift over time.
Improve the experiment without hiding failures
Run a small warmup separately and label it. Then collect enough repetitions to report the median plus a high percentile or the complete distribution. Keep timeouts explicit and count timeouts as outcomes rather than deleting them.
Change one variable at a time:
- fix the row count and vary batch size;
- fix batch size and vary payload width;
- fix ingest conditions and compare selective versus broad queries;
- fix the query and compare a warm versus idle interval.
If a rate limit or paywall response occurs, record the HTTP status and stop. Do not interpret client retry time as raw ingestion performance.
What you can responsibly claim
A defensible statement is narrow:
From a named client environment at a recorded UTC time, this commit submitted a disclosed number of synthetic rows in disclosed batches. The measured client wall time distribution was attached to the run artifacts.
That is not a universal throughput guarantee, a server-side capacity limit, or a competitor comparison. Production workload results require representative schemas, concurrency, retention, query patterns, regions, and a coordinated test environment.
Use Telemetry Cost and Volume Management to measure collection volume and Troubleshooting Event Ingestion when a benchmark exposes rejected or missing events.