How I Track Every Dollar in My Side Business Using SQLite and 50 Lines of Code
No dashboards. No SaaS subscriptions. No spreadsheet gymnastics. Just SQLite, Node.js, and a few CLI commands that took 30 minutes to write.
Here's the exact system I use to track revenue, content performance, and product experiments across 6 platforms — and why I'll never go back to Google Analytics or paid tracking tools.
The Problem: Tool Sprawl Kills Side Hustles
When I started selling digital products, I had:
- Gumroad's dashboard for sales
- Dev.to analytics for blog views
- Etsy's seller panel for another product line
- Google Sheets tracking "what I published where"
- A Notion database for experiment ideas
Five tabs open. Zero insight. I spent more time checking dashboards than building products.
The real problem wasn't tracking — it was fragmentation. Each platform knows about itself, but none of them talk to each other. I couldn't answer basic questions like:
- "Which platform drove the most revenue this week?"
- "Did my blog post actually lead to sales?"
- "What did I publish yesterday across all channels?"
The Solution: One Database, Five Tables
SQLite is the world's most deployed database. It runs on your phone, your browser, and probably your TV. It requires zero setup, zero config, and zero monthly fees.
I created a single kai_thorne.db file with five tables:
-- Where the money comes from
CREATE TABLE revenue (
id INTEGER PRIMARY KEY,
platform TEXT,
amount REAL,
product_id TEXT,
notes TEXT,
logged_at TEXT DEFAULT (datetime('now'))
);
-- What I published and where
CREATE TABLE content (
id INTEGER PRIMARY KEY,
platform TEXT,
content_type TEXT,
title TEXT,
url TEXT,
views INTEGER DEFAULT 0,
published_at TEXT DEFAULT (datetime('now'))
);
-- Daily metrics (views, followers, engagement)
CREATE TABLE metrics (
id INTEGER PRIMARY KEY,
date TEXT,
platform TEXT,
metric_name TEXT,
metric_value REAL
);
-- Experiments: hypothesis → result → decision
CREATE TABLE experiments (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE,
hypothesis TEXT,
status TEXT DEFAULT 'active',
result TEXT,
score TEXT,
started_at TEXT DEFAULT (datetime('now'))
);
-- Work log: what I actually did each day
CREATE TABLE work_log (
id INTEGER PRIMARY KEY,
job_name TEXT,
action TEXT,
result TEXT,
content_summary TEXT,
logged_at TEXT DEFAULT (datetime('now'))
);
That's the entire schema. No foreign keys. No migrations. No ORM. Five tables, five minutes.
The CLI: 50 Lines That Changed Everything
Instead of building a web dashboard, I wrote a Node.js CLI tool. Here's the key part — recording revenue:
// db.js — add-revenue command
case 'add-revenue': {
const [platform, amount, productId, notes] = args;
db.prepare(`
INSERT INTO revenue (platform, amount, product_id, notes)
VALUES (?, ?, ?, ?)
`).run(platform, parseFloat(amount), productId || '', notes || '');
console.log(`✓ Logged $${amount} from ${platform}`);
break;
}
Usage:
node db.js add-revenue gumroad 12.99 "ai-prompt-pack" "Morning sale"
node db.js add-revenue etsy 7.50 "notion-template" "First Etsy sale!"
And querying — the part that actually matters:
case 'revenue-today': {
const rows = db.prepare(`
SELECT platform, SUM(amount) as total, COUNT(*) as sales
FROM revenue
WHERE date(logged_at) = date('now')
GROUP BY platform
`).all();
console.table(rows);
break;
}
$ node db.js revenue-today
┌─────────┬──────────┬───────┬───────┐
│ (index) │ platform │ total │ sales │
├─────────┼──────────┼───────┼───────┤
│ 0 │ 'gumroad'│ 25.98 │ 2 │
│ 1 │ 'etsy' │ 7.50 │ 1 │
└─────────┴──────────┴───────┴───────┘
The Real Power: Cross-Platform Queries
Here's where it gets interesting. Questions I can now answer in one command:
"What's my best-performing content type?"
SELECT content_type, AVG(views) as avg_views, COUNT(*) as count
FROM content
GROUP BY content_type
ORDER BY avg_views DESC;
"Which experiments actually made money?"
SELECT e.name, e.hypothesis, SUM(r.amount) as total_revenue
FROM experiments e
JOIN revenue r ON r.notes LIKE '%' || e.name || '%'
GROUP BY e.name
HAVING total_revenue > 0;
"What did I do this week?"
SELECT date(logged_at), job_name, action
FROM work_log
WHERE logged_at > datetime('now', '-7 days')
ORDER BY logged_at DESC;
No BI tool. No SQL client. Just node db.js query "..." and I have the answer.
The Automation Layer: Cron Jobs as Employees
The real magic happened when I connected this database to automated cron jobs. Now my system runs 24/7:
- Morning Briefing (7:00 AM): Reads the DB, tells me yesterday's revenue, top content, and what's scheduled today
- Content Publisher (9:00 AM): Writes and publishes blog posts, logs them to the content table
- Revenue Pulse (every 2 hours): Checks platforms, updates metrics
- Evening Review (9:00 PM): Aggregates daily stats, flags experiments that need attention
Each job reads from and writes to the same SQLite file. No API calls between services. No message queues. Just a shared database file.
Why Not [Other Tool]?
"Why not Google Analytics?"
GA tracks website visitors. I need to track business operations — revenue across platforms, content across channels, experiments across time. Different problem.
"Why not Notion/Airtable?"
I tried. The API is slow, the query language is limited, and I can't run cron jobs against it without building middleware. SQLite is a file. node db.js query is instant.
"Why not Postgres?"
For a solo side hustle? Overkill. SQLite handles millions of rows without breaking a sweat. My entire database is 2MB after 3 months.
"Why not a spreadsheet?"
Because =SUMIFS(A:A, B:B, "gumroad", C:C, ">="&TODAY()-7) is not a query language. And you can't cron a Google Sheet.
The Results After 30 Days
- Time saved: ~45 minutes/day (no more checking 5 dashboards)
- Cost: $0 (SQLite + Node.js + cron = free)
- Insights gained: Found that blog posts drive 3x more Gumroad sales than social media posts
- Experiments tracked: 6 hypotheses tested, 2 scaled, 3 killed, 1 ongoing
The biggest insight was discovering that my "best" platform (by views) wasn't my best platform (by revenue). Without a unified database, I would have kept optimizing for the wrong metric.
Getting Started in 10 Minutes
- Create the database:
sqlite3 business.db < schema.sql
- Write a 50-line CLI (Node.js, Python, or even Bash + sqlite3)
- Start logging everything — revenue, content, metrics, work
- Query weekly — look for patterns, not just numbers
- Automate — set up cron jobs for daily summaries
The system is only as good as the data you put in. Log every sale, every post, every experiment. After 2 weeks, you'll see patterns you never noticed.
I built this system to run my digital products business across Gumroad, Etsy, and Dev.to. If you want the complete template (database schema, CLI tool, and cron job configs), I put together a ready-to-use starter kit on Gumroad.
Have questions? Drop a comment below — I read every one.
Top comments (0)