Skip to content

Repository files navigation

Flatbench

Flatbench

Search engine benchmark suite — compare Flatseek against Elasticsearch, tantivy, Typesense, Whoosh, ZincSearch, SQLite, and DuckDB.

PyPI VersionTestLicense

Benchmarks: build speed, search latency, wildcard, range queries, and aggregations. Results saved as JSON + Markdown to ./output/.


Flatbench Report Viewer

Install

pip install flatbench

Requires Python ≥ 3.10, Docker (for full engine comparison).


Quick Start

1. Start all search engines (Docker)

flatbench make up

Starts: Flatseek API (port 8000), Elasticsearch (9200), Typesense (8108), ZincSearch (4080).

2. Generate a dataset

flatbench generate -s article -r 500000 -o ./data/article.csv

3. Run benchmark comparison

flatbench compare -e flatseek_cli,elasticsearch,tantivy,typesense,whoosh,zincsearch -s 500000

Results → output/benchmark_YYYYMMDD_HHMMSS.json + .md.


CLI Reference

Commands

CommandDescription
flatbench generateGenerate synthetic dataset
flatbench compareCompare multiple engines
flatbench runBenchmark single engine
flatbench serveServe report viewer locally
flatbench makeRun infrastructure Makefile targets

Generate

flatbench generate --schema <schema> --rows <N> --output <path> [--format csv|jsonl]

Schemas: standard, ecommerce, logs, nested, sparse, article, adsb, campaign, devops, sosmed, blockchain

Compare

flatbench compare --engines <engines> --sizes <sizes> [options]

Options:

FlagDescriptionDefault
--schemaData schemastandard
--workers, -wParallel index workers1
--formatcsv or jsonlcsv
--source, -SUse existing CSV/JSONL instead of generating
--mode, -mnormal (disk) or tmpfs (RAM)normal
--cache-dir, -cCache generated data for reuse
--skip-buildSkip build (use existing index)
--serveAfter compare completes, build site and serve report

Engines:flatseek, flatseek_cli, elasticsearch, tantivy, typesense, whoosh, zincsearch, sqlite, duckdb

Sizes: multiple sizes supported, e.g. --sizes 1000 10000 500000

Run

flatbench run --engine <engine> --data <path> --index-dir <path> [-o output] [--iterations N]

Serve

flatbench serve [--dir ./output] [--port 8080]

Opens the report viewer in your browser automatically.

Make (Infrastructure)

flatbench make <targets...># Run Makefile targets (default: help)
flatbench make up # Start all services (docker-compose up -d)
flatbench make down # Stop services (keep volumes)
flatbench make clean # Stop and remove volumes
flatbench make status # Show service status
flatbench make logs # View logs (follow mode)
flatbench make benchmark NROWS=500000 # Run benchmark via Make

Service management:

TargetDescription
up/down/clean/status/logsDocker compose lifecycle
fs-health/fs-stats/fs-create/fs-deleteFlatseek API (port 8000)
es-health/es-stats/es-create/es-deleteElasticsearch (port 9200)
ts-health/ts-stats/ts-create/ts-deleteTypesense (port 8108)
zs-health/zs-stats/zs-create/zs-deleteZincSearch (port 4080)

Examples

# Generate article dataset (500K rows)
flatbench generate -s article -r 500000 -o ./data/article.csv
# Compare at single scale
flatbench compare -e flatseek_cli,elasticsearch -s 500000
# Compare at multiple scales
flatbench compare -e flatseek,tantivy -s 1000 10000 500000
# Use existing CSV (reuse generated data)
flatbench compare -e flatseek,elasticsearch -s 500000 -S ./data/article.csv
# RAM-backed index (tmpfs mode, faster builds)
flatbench compare -e flatseek,tantivy -s 500000 -m tmpfs
# Compare and auto-serve report
flatbench compare -e flatseek,tantivy -s 500000 --serve
# Run benchmark via Make
flatbench make benchmark NROWS=500000 ENGINES="flatseek_cli,elasticsearch,tantivy"

Service URLs:

ServiceURL
Flatseek APIhttp://localhost:8000
Elasticsearchhttp://localhost:9200
Typesensehttp://localhost:8108
ZincSearchhttp://localhost:4080
Kibanahttp://localhost:5601 (dev profile)

Available Schemas

SchemaFieldsDescription
article8Blog articles: id, title, content, tags, views, published_at, author
standard12Generic: id, name, email, phone, city, country, status, balance, created_at, updated_at, is_verified, tags
ecommerce12Order tracking data
logs11Log entries: timestamp, level, service, message, etc.
nested6Complex nested JSON objects
sosmed9Social media posts
devops11Infrastructure/monitoring data
adsb10Flight tracking data
campaign10Marketing campaign data
blockchain9Blockchain transaction data

Benchmark Operations

OperationDescriptionMetrics
build_indexBulk API indexing (1000 rows/batch)duration_ms, rows/sec, index_size_mb
searchFull-text queryp50_ms, p95_ms, p99_ms, ops/sec
wildcard_searchPrefix/suffix wildcard queriesp50_ms, p95_ms, ops/sec
range_queryNumeric/date range filteringduration_ms, hits, ops/sec
aggregateTerms/stats aggregationsduration_ms, bucket_count, ops/sec

Output

Results written to ./output/ with timestamps:

output/
├── benchmark_20260501_142947.json # Full structured results
├── benchmark_20260501_142947.md # Markdown summary
└── index.json # Report manifest (for web viewer)

Report Viewer

Live:bench.flatseek.io — hosted Flatbench report viewer.

Local: Run flatbench serve --port 8080 or open report_viewer.html directly in browser.


Build Static Site

Build output directory as a static site (for self-hosted or Vercel deploy):

make build
# or
bash build.sh

Output → public/ directory with index.html, output/*.json, output/*.md.

Deploy to Vercel

make deploy # Deploy to production (flatbench.vercel.app)
make deploy-preview # Deploy preview build

Project Structure

flatbench/
├── Dockerfile # Flatseek API server container
├── docker-compose.yml # All engine containers
├── Makefile # Infrastructure + build commands
├── build.sh # Static site build script
├── report_viewer.html # Web UI for browsing results
├── pyproject.toml # flatbench package definition
├── src/flatbench/
│ ├── cli.py # CLI entry point
│ ├── benchmarks/ # Benchmark orchestration + report generation
│ ├── generators/ # Synthetic data generators (schema-aware)
│ ├── runners/ # Engine runners (HTTP API / CLI)
│ │ ├── flatseek_api.py # Flatseek HTTP API runner
│ │ ├── flatseek_cli.py # Flatseek CLI runner
│ │ ├── elasticsearch.py # Elasticsearch runner
│ │ ├── tantivy.py # tantivy (Rust) runner
│ │ ├── typesense.py # Typesense runner
│ │ ├── whoosh.py # Whoosh runner
│ │ ├── zincsearch.py # ZincSearch runner
│ │ ├── sqlite.py # SQLite FTS5 runner
│ │ └── duckdb.py # DuckDB full-text runner
│ └── output/ # Benchmark results (JSON + Markdown)

Adding a New Engine

fromflatbench.runnersimportBaseRunner, BenchmarkResult, register_engine@register_engine("myengine")classMyEngineRunner(BaseRunner):
name="myengine"supports_aggregate=Falsesupports_range_query=Truesupports_wildcard=Truedefbuild_index(self, data_path: str, **kwargs) ->BenchmarkResult:
# Bulk API indexing logicpassdefsearch(self, query: str, iterations: int=10, **kwargs) ->BenchmarkResult:
# Search via HTTP APIpass

Then add to --engines list: --engines flatseek,myengine,...


Benchmark Results (Latest: 500K rows, article schema)

Latest Full results:bench.flatseek.io

Overall Score (60% speed · 40% correctness)

EngineSpeedCorrectnessScore
Flatseek🟢🟢0.878
typesense🟢🟢0.832
zincsearch🟢🟢0.823
elasticsearch🟢🟢0.820
tantivy🟢🔴0.650
whoosh🔴🔴0.025

Key Takeaways

  • Correctness matters: Flatseek is the only engine with zero correctness errors. Tantivy misses 99.4% of range query hits.
  • Search: Tantivy fastest (0.7ms p50), but wrong. Flatseek second-fastest correct (7.9ms).
  • Build: Tantivy wins (21s for 500K), but Flatseek build is reasonable (217s).
  • Aggregation: Competitors (ES, tantivy) are 20–300× faster — Flatseek aggregation is a known weakness.

About

Benchmarking tool to compare indexing, search and aggregate performance between Flatseek and the competitors

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages