SQLiteSweep
Query millions of SQLite databases across remote hosts via SSH, aggregating results in real-time. Designed for multi-tenant apps where each tenant has their own SQLite database.
Installation
gem install sqlitesweep
Or add to your Gemfile:
gem "sqlitesweep"
Usage
sqlitesweep \
-q 'SELECT count(*) FROM products WHERE price > 0' \
-a sum \
-s 'rails runner "Account.active.find_each { |a| puts a.db_uri }"' \
-c 16
The -s (source) command should output one database URI per line. URIs can be:
- Local paths:
/data/tenants/acme.sqlite3 - File URIs:
file:///data/tenants/acme.sqlite3 - SSH URIs:
ssh://[email protected]/data/tenants/acme.sqlite3
Results go to stdout, progress goes to stderr — so it's pipe-friendly:
sqlitesweep -q "SELECT count(*) FROM users" -a sum -s "cat db_uris.txt" > result.txt
Actions
| Action | Description |
|---|---|
sum |
Sum the first column across all databases (default) |
average / avg |
Average the first column across all databases |
list |
Write all rows to a JSONL file, print the file path |
Options
| Flag | Long | Default | Description |
|---|---|---|---|
-q |
--query |
(required) | SQL query to execute on each database |
-a |
--action |
sum |
sum, average/avg, or list |
-s |
--source |
(required) | Shell command that outputs database URIs |
-c |
--concurrency |
8 |
Max parallel query workers |
--max-ssh |
50 |
Max SSH master connections | |
--no-live |
false |
Disable live progress display | |
--batch-size |
4 |
Databases to query per SSH call | |
--ssh-timeout |
10 |
SSH connect timeout (seconds) | |
--query-timeout |
30 |
Per-query timeout (seconds) |
How it works
- Local databases are queried directly via the
sqlite3gem - Remote databases are queried by shelling out to
ssh+sqlite3on the remote host - SSH connections use
ControlMastermultiplexing — one master connection per host, shared across queries - Multiple databases on the same host are batched into a single SSH call (configurable via
--batch-size) - A thread pool (via
concurrent-ruby) runs queries in parallel with back-pressure
Requirements
- Ruby >= 4.0
sqlite3available on remote hosts (for SSH queries)- SSH agent or key-based auth configured (BatchMode is enforced — no password prompts)
Development
bundle install
bundle exec rake test
Run the integration test:
bundle exec ruby test/integration/test_local_sweep.rb
Watch the live progress display with a slow-drip demo:
ruby test/integration/harness/live_demo.rb
ruby test/integration/harness/live_demo.rb --count 50 --delay 0.5
ruby test/integration/harness/live_demo.rb --action list
Run the benchmark:
ruby test/integration/harness/sweep_bench.rb --db-count 1000
Docker-based SSH testing
docker compose -f test/integration/harness/docker-compose.yml up -d
ruby test/integration/harness/sweep_bench.rb --docker --db-count 500
License
MIT