Benchmark Tool
The hlquery benchmark tool measures indexing and query performance under configurable load profiles.
Overview
The benchmark binary provides multiple test modes:
- Standard benchmark: Create collections and insert documents with configurable parameters
- Search benchmark: Test search performance on existing data
- Flood mode: Continuous stress testing with random operations
- Detailed benchmark: Comprehensive testing of all API routes
- Fake mode: Insert sample data for quick testing
Installation
The benchmark tool is built alongside the main HLQuery server. After building HLQuery, you'll find the benchmark executable in the run/bin/ directory:
./run/bin/benchmark --help
Basic Usage
Standard Benchmark
Run a standard benchmark with default settings:
./run/bin/benchmark --url http://localhost:9200
Customize the benchmark:
./run/bin/benchmark \
--url http://localhost:9200 \
--collections 50 \
--documents 10000 \
--threads 8 \
--batch-size 200
Search Benchmark
Test search performance on existing collections:
./run/bin/benchmark --url http://localhost:9200 --search
Flood Mode (Continuous Stress Testing)
New in recent update: Flood mode now runs continuously until stopped with Ctrl+C, randomly creating collections and documents.
./run/bin/benchmark --url http://localhost:9200 --flood
Flood mode features:
- Continuous operation: Runs until you press Ctrl+C (like
--noforkmode) - Random operations: Each worker thread randomly performs:
- 40% probability: Create a new collection
- 50% probability: Insert random documents into existing collections
- 10% probability: Perform random searches
- Real-time statistics: Prints stats every 10 seconds showing:
- Runtime
- Collections created
- Documents inserted
- Searches performed
- Errors encountered
- Thread-safe: Uses mutexes and atomic variables for safe concurrent operations
- Graceful shutdown: Handles SIGINT/SIGTERM signals for clean termination
Example output:
----------------------------------------------------------------
FLOOD MODE: Continuous Stress Testing
----------------------------------------------------------------
This will continuously:
- Randomly create collections
- Randomly insert documents into collections
- Randomly perform searches
Press Ctrl+C to stop...
Flood benchmark running... Press Ctrl+C to stop.
[Stats] Runtime: 10s | Collections: 15 | Documents: 234 | Searches: 3 | Errors: 0
[Stats] Runtime: 20s | Collections: 28 | Documents: 567 | Searches: 8 | Errors: 0
...
Fake Mode
Insert sample data quickly:
./run/bin/benchmark --url http://localhost:9200 --fake
This creates:
- 100 synthetic people profiles with first, middle, and last names plus short biographies
- 100 ranked university profiles
- 50 documents in each of the
saas,finance,fashion, andecommercecollections - 10 documents for each additional sample collection, including food, stocks, music, science, books, movies, art, travel, sports, history, technology, and math
- shared
embedding(float[]) andlocation(geo_point) fields on every fake collection, so vector and geo search can be tested immediately
Example vector search against fake data:
curl -X POST http://localhost:9200/collections/technology/vector_search \
-H "Content-Type: application/json" \
-d '{"field_name":"embedding","vector":[0.1,0.2,0.3,0.4],"topk":5,"metric_type":"cosine"}'
Example geo search against fake data:
curl "http://localhost:9200/collections/food/documents/search?q=*&filter_by=_geo_radius(location,40.7306,-73.9352,5km)&sort_by=_geo_distance(location,40.7306,-73.9352):asc"
Detailed Benchmark
Run comprehensive testing of all API routes:
./run/bin/benchmark --url http://localhost:9200 --detailed
Dump Collections
List all collections and their documents:
./run/bin/benchmark --url http://localhost:9200 --dump
Command Line Options
Options:
--url URL Server URL (default: http://localhost:9200)
--auth TOKEN Authentication token
--collections N Number of collections to create (default: 2, max: 1000 without --flood)
--documents N Total number of documents to insert (default: 50000 per collection, max: 1000000 without --flood)
--threads N Number of threads (default: 8)
--batch-size N Documents per bulk insert batch (default: 50)
--advanced [FILE] Output detailed JSON metrics (default: adv.json)
--detailed [FILE] Run comprehensive benchmark testing ALL routes
and functionalities (includes --advanced)
--search Run search benchmark on previously inserted data
--dump Dump all collections and their documents
--fake Insert realistic sample collections, including 50-item SaaS, finance, fashion, and ecommerce collections
--flood Flood server with continuous random data generation for stress testing
(runs until stopped with Ctrl+C, randomly creates collections and documents)
--id ID Run UUID/ID for correlation (default: auto-generated timestamp)
--seed SEED Seed for deterministic runs
--no-fake-collections Disable fake helper collections (products/foods/cart/items)
--verify-after-restart Verify counts after server restart (requires manual restart)
--check-consistency Check consistency of /status, /stats, /metrics, /doctotal at end
--dry-run Generate collections/docs in memory but don't send to server
--cleanup Delete all benchmark-tagged collections at end
--log-file FILE Structured log file (JSON lines format)
--verbose, -v Show detailed progress information
--help, -h Show this help message
Examples
Quick Performance Test
# Start server
./run/hlquery start --nofork &
# Run benchmark
./run/bin/benchmark --url http://localhost:9200 --collections 10 --documents 1000 --threads 4
Stress Testing
# Run continuous flood test
./run/bin/benchmark --url http://localhost:9200 --flood --threads 4 --verbose
# Press Ctrl+C when done
Advanced Metrics
# Generate detailed JSON metrics
./run/bin/benchmark --url http://localhost:9200 --advanced metrics.json --collections 20 --documents 5000
Understanding Results
Standard Benchmark Output
The benchmark provides:
- Collection creation time: How long it took to create all collections
- Document insertion time: Time to insert all documents
- Throughput: Documents per second
- Error count: Number of errors encountered
Flood Mode Statistics
Flood mode prints periodic statistics:
- Runtime: Total elapsed time
- Collections: Number of collections created
- Documents: Total documents inserted
- Searches: Number of searches performed
- Errors: Error count
Advanced JSON Output
When using --advanced, you get detailed metrics in JSON format including:
- Per-operation timings
- Success/failure rates
- Throughput metrics
- Error details
Advanced Features
Run ID and Correlation
The benchmark automatically generates a unique run ID (timestamp-based) for each run. You can also provide your own with --id:
./run/bin/benchmark --id my-test-run-001 --collections 50 --documents 5000
The run ID is stored in the advanced JSON output and can be used to correlate benchmark runs with server logs.
Persistence and Verification
The benchmark automatically:
- Flushes all pending HTTP requests before exiting
- Calls flush/sync endpoints to ensure data persistence
- Records final collection/document counts from the server
- Compares server-reported counts with benchmark-inserted counts
Use --check-consistency to verify that /status, /stats, /metrics, and /doctotal all report consistent counts:
./run/bin/benchmark --check-consistency --collections 10 --documents 1000
Verifying After Restart
To verify that data persists correctly after a server restart:
- Run benchmark with
--advancedto save final counts:
./run/bin/benchmark --advanced results.json --collections 50 --documents 5000
-
Restart the server manually
-
Run with
--verify-after-restartto compare counts:
./run/bin/benchmark --verify-after-restart --advanced results.json
Latency Percentiles
The advanced JSON output includes latency percentiles (P50, P90, P99) for batch insertions and other operations, useful for regression testing and performance analysis.
Monotonic Checks in Flood Mode
Flood mode now includes monotonic checks to ensure counters never decrease, helping detect data loss or counting issues during stress testing.
Best Practices
- Start with small tests: Begin with fewer collections and documents to verify connectivity
- Monitor server resources: Watch CPU, memory, and disk usage during benchmarks
- Use appropriate thread counts: Too many threads can overwhelm the server
- Test incrementally: Gradually increase load to find performance limits
- Use flood mode for stress testing: Perfect for finding breaking points and testing stability
- Check server health: Ensure the server is healthy before and after benchmarks
- Use --check-consistency: Verify endpoint consistency after benchmarks
- Save advanced metrics: Use
--advancedto save detailed metrics for analysis - Limit defaults: Default collections/documents are limited to prevent accidental huge runs (use
--floodto bypass) - Clean up after tests: Use
--cleanupto remove benchmark collections when done
Troubleshooting
Connection Errors
If you see connection errors:
- Verify the server is running:
./run/hlquery status - Check the URL is correct
- Ensure firewall rules allow connections
- Check authentication token if required
Performance Issues
If benchmarks are slow:
- Check server resource usage
- Reduce thread count
- Increase batch size for bulk operations
- Check network latency
- Verify server configuration
Flood Mode Not Stopping
Flood mode should stop on Ctrl+C. If it doesn't:
- Check for signal handling issues
- Verify you're using the latest version
- Try sending SIGTERM:
kill -TERM <pid>
Count Mismatches After Restart
If document/collection counts don't match after restart:
- Check that flush/sync completed successfully (look for "✓ Flush/sync completed" in output)
- Verify WAL and SSTables are persisted correctly
- Use
--check-consistencyto identify which endpoints disagree - Check server logs for errors during benchmark
Data Loss Warnings
If you see "ERROR: Server reports X documents but benchmark inserted Y":
- This indicates potential data loss or counting issues
- Check server logs for errors
- Verify disk space is available
- Check for server crashes during benchmark
- Use
--check-consistencyto verify endpoint consistency
Modes and Caveats
Persistence Expectations
The benchmark automatically flushes and syncs data at the end, but note:
- WAL (Write-Ahead Log) is synced to disk
- SSTables are flushed from memtable
- Final counts are recorded for verification
- Use
--verify-after-restartto explicitly test persistence
Fake Collections
By default, the benchmark creates helper collections (products, foods, cart, items) unless --no-fake-collections is used. These collections:
- Are separate from benchmark collections
- Don't count toward
--collectionsparameter - Can be excluded with
--no-fake-collectionsto avoid confusion in doctotal/hlquery-cli cols results
Fake collections include embedding, location, and location_name fields. Use embedding for vector search and location for geo radius, box, and distance-sort tests.
The 50-item category collections are available at /collections/saas, /collections/finance, /collections/fashion, and /collections/ecommerce.
Default Limits
To protect against accidental huge runs, default limits are applied:
- Maximum 1000 collections (without
--flood) - Maximum 1,000,000 documents (without
--flood) - Use
--floodto bypass these limits for stress testing