I used to build side projects like most people — code it, ship it, hope for the best. No tracking. No data. No idea what was working.
Then I started logging everything into a single SQLite database. Not analytics. Not dashboards. Just a plain .db file with a few tables and a Node.js CLI wrapper.
It changed how I make every decision.
The Problem With Flying Blind
When you are running a solo operation — a blog, a Gumroad store, a YouTube channel, some automation scripts — you are making dozens of decisions a day:
- What content to create next
- Which product to promote
- Where to spend your limited time
- Whether that "growth hack" actually worked
Without data, you are guessing. And guesses are expensive when you are one person doing everything.
Google Analytics tells you pageviews. Stripe tells you revenue. But nothing ties them together into a single "what is actually happening" picture.
The SQLite Solution
Here is what I set up. One database. Five tables. A CLI tool.
CREATE TABLE work_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
job_name TEXT,
action TEXT,
result TEXT,
content_summary TEXT,
logged_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE content (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT,
content_type TEXT,
title TEXT,
url TEXT,
published_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE revenue (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT,
amount REAL,
product_id TEXT,
notes TEXT,
recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT,
title TEXT,
price REAL,
status TEXT DEFAULT 'draft',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE metrics (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT,
platform TEXT,
metric_name TEXT,
metric_value REAL
);
Nothing fancy. No ORM. No GraphQL. Just tables that mirror the reality of running a one-person business.
The CLI Wrapper
A simple db.js script that turns boring SQL into quick commands:
# What happened today?
node db.js today
# How much money came in?
node db.js revenue-today
# What content was published recently?
node db.js recent-content
# Log what I just did
node db.js log work "Published blog post on SQLite"
# Record revenue
node db.js add-revenue gumroad 29.00 "python-guide"
Total implementation: about 200 lines of Node.js. Took an afternoon.
Why SQLite (Not Postgres, Not a SaaS)
I have tried them all:
Google Sheets — breaks at 10K rows, no programmatic access without API headaches, and you end up with 47 tabs that nobody understands.
Postgres — overkill for a solo operation. Now you need a server, connection pooling, migrations. You are spending time on infrastructure instead of shipping.
SaaS dashboards — Mixpanel, Amplitude, whatever. They cost money, they track their idea of what matters, and you can not easily join your content data with your revenue data.
SQLite — zero config, zero cost, zero infrastructure. It is a single file. You can cp it to back it up. You can query it from any language. It runs on your laptop, your VPS, your Raspberry Pi.
The killer feature: it is your schema. You decide what matters. Not some product manager at Google.
The Decisions It Actually Improved
Here is what changed once I had 30 days of data:
1. Content Timing
I discovered my blog posts published on Tuesday mornings got 3x the engagement of anything published on weekends. Not because of the algorithm — because my audience (developers) checks dev.to at work.
2. Platform ROI
After logging every content piece and its results, the data was clear: one dev.to blog post drove more traffic than 20 Twitter threads. I reallocated time accordingly.
3. Revenue Attribution
When I published a blog post about Python automation and saw Gumroad sales spike the same week, I could actually see the connection. Before the database, those events were separated by different tabs in different apps.
4. Detecting Stalls
The work_log table is brutally honest. When I query "what happened this week?" and see two entries, I know I have been slacking. No hiding from a database.
The Automation Layer
Once the data exists, you can automate around it:
// Morning briefing: what happened overnight?
const today = db.prepare(`
SELECT * FROM work_log
WHERE logged_at > datetime('now', '-12 hours')
`).all();
// Revenue check
const revenue = db.prepare(`
SELECT SUM(amount) as total
FROM revenue
WHERE date(recorded_at) = date('now')
`).get();
// Stale content detection
const lastPost = db.prepare(`
SELECT MAX(published_at) as last_pub
FROM content WHERE platform = 'dev.to'
`).get();
I built cron jobs that run these queries every morning and give me a briefing. No dashboards to check. The data comes to me.
The Session Tracking Pattern
One pattern that has been incredibly useful: session tracking for long-running tasks.
CREATE TABLE session_state (
id INTEGER PRIMARY KEY,
job_name TEXT,
session_run_id TEXT UNIQUE,
status TEXT DEFAULT 'running',
started_at TEXT,
heartbeat_at TEXT,
completed_at TEXT,
summary TEXT
);
Every automated task logs when it starts, sends heartbeats, and logs when it finishes. If a task gets stuck (no heartbeat in 30 minutes), a watchdog script catches it.
This is how I discovered that one of my "working" cron jobs had been silently failing for three days. Without session tracking, I would not have noticed.
Getting Started
If you want to try this approach:
Start with
work_logonly. Just log what you do. Timestamp + description + result. That single table will teach you more about your habits than any productivity app.Add
contentwhen you publish. Track platform, type, title, URL. After a month, query it to find patterns.Add
revenuewhen you earn. Even if it is $0.99. Especially if it is $0.99. Small amounts reveal trends that big amounts hide.Build the CLI first, schema second. You will not use a database you have to open in a GUI. Make the commands fast and memorable.
Back it up. It is one file.
cp kai.db backup-$(date +%Y%m%d).db. Done.
The Meta-Lesson
The database itself is not the point. The point is that data-driven decisions are not just for companies with analytics teams. A solo developer with SQLite and 200 lines of Node.js can make better decisions than a startup with a $50K/year Mixpanel contract.
Because the data is yours. You collected it. You shaped the schema. You know exactly what it means.
Stop building blind. Start logging.
This post is part of my series on solo developer operations. I run everything — blog, products, automation — from a single machine with SQLite as the brain. Follow along for more.
Related Reading
- My LLM API Bill Hit $847/Month — Here's the Open-Source Proxy That Cut It to $89 — How I cut API costs by 89% with smart routing
- I Automated My Entire Side Business with 7 Free AI Tools — The complete automation stack with SQLite at its core
Top comments (0)