{"record":{"id":"8111f0cbcb287b2d","repo":"tursodatabase/turso","slug":"seconds-requires-benchmark-throughput","errorCode":null,"errorMessage":"--seconds requires --benchmark throughput","messagePattern":"--seconds requires --benchmark throughput","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"perf/fts/src/main.rs","lineNumber":71,"sourceCode":"    ensure!(args.connections > 0, \"connections must be positive\");\n    eprintln!(\"bundled SQLite version: {}\", rusqlite::version());\n    let runtime = match args.benchmark {\n        Benchmark::Search => tokio::runtime::Builder::new_current_thread()\n            .enable_all()\n            .build()?,\n        Benchmark::Throughput => tokio::runtime::Builder::new_multi_thread()\n            .worker_threads(args.connections)\n            .max_blocking_threads(args.connections)\n            .enable_all()\n            .build()?,\n    };\n    runtime.block_on(run(args))\n}\n\nasync fn run(mut args: Args) -> Result<()> {\n    let (query_limit, min_seconds) = match args.benchmark {\n        Benchmark::Search => {\n            ensure!(\n                args.seconds.is_none(),\n                \"--seconds requires --benchmark throughput\"\n            );\n            let queries = args\n                .queries\n                .unwrap_or(if matches!(args.state, QueryState::First) {\n                    args.connections\n                } else {\n                    10_000\n                });\n            ensure!(\n                queries >= args.connections,\n                \"need at least one query per connection\"\n            );\n            ensure!(\n                !matches!(args.state, QueryState::First) || queries == args.connections,\n                \"first-query latency requires one query per connection\"\n            );","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/tursodatabase/turso/blob/8d4a589f8d13ac184700d2a8f724f27e1995be3b/perf/fts/src/main.rs#L53-L89","documentation":"The FTS benchmark runner only accepts --seconds (benchmark duration) when running the throughput benchmark. In the Search benchmark branch of run(), ensure! rejects any invocation where --seconds was supplied, because search benchmarks are query-count driven, not time driven. This is CLI argument validation to prevent ambiguous benchmark configurations.","triggerScenarios":"Running the perf/fts binary with both --benchmark search (or default search) and a --seconds value, e.g. `fts-bench --benchmark search --seconds 10`. The ensure! at perf/fts/src/main.rs:71 fires inside run() whenever args.benchmark is Benchmark::Search and args.seconds.is_some().","commonSituations":"Developers copying a throughput-benchmark command line and switching only the benchmark name; scripting harnesses that always pass --seconds regardless of benchmark mode; misunderstanding that search mode measures fixed query counts rather than a time window.","solutions":["Remove --seconds from the command line when using the search benchmark","Switch to --benchmark throughput if a time-limited run is actually desired","If a wrapper script always passes --seconds, make it conditional on the benchmark mode"],"exampleFix":"// before\nfts-bench --benchmark search --seconds 10 --queries 1000\n// after\nfts-bench --benchmark search --queries 1000","handlingStrategy":"validation","validationCode":"if benchmark == Search && seconds.is_some() { panic!(\"--seconds only applies to --benchmark throughput\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one script per benchmark mode with only that mode's flags","Read --help output before composing flags","Validate CLI flags in wrapper scripts before invoking the binary"],"tags":["cli","argument-validation","benchmark"],"backgroundTag":"conflicting-config-options","analyzedSha":"8d4a589f8d13ac184700d2a8f724f27e1995be3b","analyzedAt":"2026-09-20T13:18:14.658Z","contentChangedAt":"2026-09-20T13:18:14.658Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}