Show HN: Lightweight data analytics using SQLite, Bash and DuckDB

5 points by hilti ↗ HN
Over the last 12 months, in parallel to using Google BigQuery, I have built my own processing pipeline using SQLite and DuckDB.

What amazes me is that it works surprisingly well and costs much less than using BigQuery.

Roughly speaking, here's what I do: A SQLite database receives IoT sensor data via a very simple PHP function. I currently use the FlightPHP framework for this. The data is written to a table within the SQLite database (WAL mode activated) and states are updated by the machines using triggers.

Example of a trigger

CREATE TRIGGER message_added AFTER INSERT ON messages BEGIN INSERT OR REPLACE INTO states VALUES ( new.id, new.status, new.time_stamp, new.current_present, new.voltage_present)

This allows me to query the current status of a machine in real time. To do this, I again use a simple PHP function that provides the data via SSE. In the frontend, a simple Javascript method (plain vanilla JS) retrieves the JSON data and updates the HTML in real time.

    const source_realtime = new EventSource("https://myapi/sse_realtime_json");
    source_realtime.onmessage = function(event) {
        var json = JSON.parse(event.data); };
For a historical analysis - for example over 24 months - I create a CSV export from the SQLite database and convert the CSV files into Parquet format.

I use a simple BASH script that I execute regularly via CronJob.

Here is an excerpt

# Loop through the arrays and export each table to a CSV, then convert it to a Parquet file and load into the DuckDB database for (( i=0; i<${arrayLength}; i++ )); do db=${databases[$i]} table=${tables[$i]}

  echo "Processing $db - $table"
  
  # Export the SQLite table to a CSV file
  sqlite3 -header -csv $db "SELECT * FROM $table;" > parquet/$table.csv
  
  # Convert the CSV file to a Parquet file using DuckDB
  $duckdb_executable $duckdb_database <<EOF

 -- Set configurations
 SET memory_limit='2GB';
 SET threads TO 2;
 SET enable_progress_bar=true;

 COPY (SELECT * FROM read_csv_auto('parquet/$table.csv', header=True)) TO 'parquet/$table.parquet' (FORMAT 'PARQUET', CODEC 'ZSTD');
 CREATE TABLE $table AS SELECT * FROM read_parquet('parquet/$table.parquet');
EOF

Now finally my question: Am I overlooking something? This little system works well for currently 15 million events per month. No outtages, nothing like that. I read so much about fancy data pipelines, reactive frontend dashboards, lambda functions ...

Somehow my system feels "too simple". So I'm sharing it with you in the hope of getting feedback.

6 comments

[ 3.7 ms ] story [ 29.0 ms ] thread
Out of curiosity, what's the advantage of SQLite over file-based DuckDB directly?
From my findings it’s been a lot easier to insert data into SQLite first and then proceed them for time-series queries or extensive aggregation in DuckDB.

Especially the WAL mode by SQLite is really performant.

I appreciate the perspective. I’m currently bouncing around a similar decision myself and have used SQLite and DuckDB both, and there’s something about DuckDB that i just like better (roadmap, features, range requests), but trying to understand the full picture
It’s not. If it holds up well in terms of operating it and extending it when things change, then it’s not “too simple”. You’ve just built on 4 extremely resilient and scalable technologies which have made the kind of “Big Data” hoop-jumping of the past 20+ years rather moot.

You know the drill: SQLite and DuckDB mean you’ve got transactional database and data warehouse that live in the single machine and unless it’s terabytes runs analytics performance comparable to bigquery and snowflake.

No need to write an etl pipeline that runs on a Hadoop cluster, provision that Hadoop cluster, spin up a Hive/Pig instance for analysis. Nah, it fits in *your* computer and is scripted using the same language in the pipelines as in the analysis without a performance cost.

If you need to scale it, it’s not technical scaling, it’s team knowledge scaling (still hard, but not a fundamental stumbling block). So bring in DBT/Dagster (or airflow) and now it’s got supported frameworks that others already know and use.

Thank you for your valuable feedback - much appreciated!

Team knowledge scaling is hard - I totally agree and learned a lot of lessons.

Top management usually works „email only“. No matter what cool dashboard you’re building: they don’t use it, because they’re working almost exclusively on their phones.

And that‘s one tough challenge in my opinion: making data easy to understand on small screens.

Then there is this group of CFOs … they love to connect their Excel to a live datastream. Once. Because at some point they return to static sheets just to prove that a 35 MB Excel file shows their latest forecast.

> Am i overlooking something

Analytics. Have you checked the read latency/potential table scans due to insufficient indexes?

Eg How would you replicate every view of Google analytics while inserts are going on.