Performance benchmarks for CipherStash's searchable encryption operations using Order-Revealing Encryption (ORE) and the Encrypt Query Language (EQL).
The latest benchmark results are available in the report/ directory:
- Benchmark Report - Comprehensive report with performance tables and charts
- Includes ingest throughput, query performance, SQL statements, and index configurations
- Performance indicators (
โ ๏ธ ) highlight queries exceeding 100ms
The benchmarks are designed to run on a local development machine with the following stack:
- Database: PostgreSQL 17 (running in Docker)
- Language: Rust (latest stable)
- Framework: Criterion.rs for benchmarking
- Encryption: CipherStash EQL v2 with ORE support
PostgreSQL 17
Port: 5400 (mapped from container port 5432)
User: postgres
Database: postgresThe benchmarks use three types of encrypted data:
- Integer values - ORE-encrypted integers for range queries
- String values - Encrypted strings for exact and pattern matching
- JSON objects - Small encrypted JSON documents
Benchmarks are run against multiple data set sizes:
- 10,000 rows
- 100,000 rows
- 1,000,000 rows
- 10,000,000 rows (optional)
Three categories of queries are benchmarked:
EXACT Queries - Exact match lookups
- Using EQL cast operator
- Using EQL HMAC-256 hash
MATCH Queries - Pattern matching
- LIKE queries with EQL cast
- Bloom filter containment queries
ORE Queries - Range queries on encrypted integers
- Exact match
- Range queries (>, <)
- Ordered range queries with ORDER BY
Each query is tested with and without decryption of results.
-
Install mise (tool version manager):
curl https://mise.run | sh -
Install Rust (via mise):
mise install
-
Set up environment variables:
cp .env.example .env # Edit .env with your CipherStash credentials
# Start PostgreSQL
mise run postgres
# Set up database (creates tables and installs EQL extension)
mise run setup-db
# Run all ingest benchmarks
mise run bench:ingest
# Run query benchmarks for a specific row count
mise run bench:query:exact 10000
mise run bench:query:match 10000
mise run bench:query:ore 10000
# Run all query benchmarks (all row counts)
mise run bench:query:all
# Generate report
mise run reportmise run postgresThis starts PostgreSQL 17 in a Docker container on port 5400.
mise run reset-db # Reset database (if needed)
mise run setup-db # Install EQL extension and create tables# Run individual ingest benchmarks
mise run bench:ingest:encrypt_int
mise run bench:ingest:encrypt_string
mise run bench:ingest:encrypt_json_small
# Or run all at once
mise run bench:ingestResults are saved to results/ingest/*.json
Before running query benchmarks, tables need to be populated and indexed:
# Prepare string_encrypted table with 10,000 rows
mise run prepare:string_encrypted 10000
# Prepare integer_encrypted table with 10,000 rows
mise run prepare:integer_encrypted 10000This process:
- Checks current row count
- Drops indexes
- Inserts additional rows if needed
- Creates indexes
# Run specific query benchmark with specific row count
mise run bench:query:exact 10000
mise run bench:query:match 100000
mise run bench:query:ore 1000000
# Run all query benchmarks for all row counts (10k, 100k, 1M, 10M)
mise run bench:query:allResults are saved to results/query/*.json
mise run reportThis generates:
report/BENCHMARK_REPORT.md- Markdown reportreport/*_chart.png- Performance charts (requires matplotlib)
To enable chart generation:
pip3 install matplotlibore-benches/
โโโ benches/ # Criterion benchmark definitions
โ โโโ exact.rs # EXACT query benchmarks
โ โโโ match.rs # MATCH query benchmarks
โ โโโ ore.rs # ORE range query benchmarks
โโโ src/
โ โโโ bin/ # Binary utilities
โ โ โโโ encrypt_int.rs
โ โ โโโ encrypt_string.rs
โ โ โโโ combine_benchmark.rs
โ โโโ lib.rs # Shared benchmark code
โโโ sql/
โ โโโ schema.sql # Database schema
โ โโโ indexes/ # Index creation scripts
โโโ results/ # Benchmark results (JSON)
โ โโโ ingest/ # Ingest throughput results
โ โโโ query/ # Query performance results
โโโ report/ # Generated reports
โ โโโ BENCHMARK_REPORT.md
โ โโโ *.png # Charts
โโโ report_benchmarks.py # Report generator script
โโโ mise.toml # Task definitions
โโโ README.md # This file
# Prepare and benchmark custom row count
mise run prepare:string_encrypted 50000
TARGET_ROWS=50000 cargo criterion --bench exact# Build in release mode
mise run bench:build
# Run specific benchmark manually
TARGET_ROWS=10000 cargo criterion --bench ore --message-format json > results/query/ore_rows_10000.json# Connect to database
mise run psql
# View PostgreSQL logs
mise run postgres-logs
# Stop PostgreSQL
mise run postgres-stop# Generate report with custom filename
mise run report custom_report.md
# Or use Python script directly
python3 report_benchmarks.py --output report/my_report.md
# Specify custom directories
python3 report_benchmarks.py \
--results-dir results \
--sql-dir sql \
--output report/BENCHMARK_REPORT.mdMeasures how many encrypted records can be inserted per second. Higher is better.
Query times are reported both:
- Without decryption - Time to execute query and retrieve encrypted results
- With decryption - Time including client-side decryption
Times exceeding 100ms are marked with
Query performance is affected by:
- Data set size - Larger datasets generally increase query time
- Index type - Hash indexes are faster for exact matches; ORE indexes enable range queries
- Query complexity - Pattern matching is slower than exact lookups
- Result set size - LIMIT clause affects decryption overhead
# Check if PostgreSQL is running
docker ps | grep postgres
# Restart PostgreSQL
mise run postgres-stop
mise run postgresmise run setup-dbCheck that:
- Database is running and accessible
- Tables have been prepared with correct row counts
- Environment variables are set in
.env - CipherStash credentials are valid
- Report Generator Documentation - Detailed guide for the report generation script
- Report Directory - Information about generated reports
- CipherStash Documentation - Official CipherStash docs
When adding new benchmarks:
- Add benchmark definition to
benches/ - Update
mise.tomlwith new tasks - Add query descriptions to
report_benchmarks.py - Document the benchmark in this README
- Run benchmarks and commit results to
report/
MIT License - see LICENSE for details.