You close the month with ₹2.3L invoiced. You feel good.
Then you open Sheets. Filter Transactions tab. Sum Income: ₹2.1L actually received (₹20k overdue). Sum Expenses: ₹68k hosting + tools + subcontractor. Real Profit: ₹1.42L. Not ₹2.3L.
You check Investments tab. SIP ₹15k, Stocks ₹30k — but no link to Transactions, so you don't know if you invested profit or revenue you haven't collected.
You guess runway. You guess pipeline health. You guess whether Acme concentration risk is 40% or 65%.
Spreadsheets answer how much did I type?. A dashboard answers how healthy am I?.
Why Spreadsheets Lie to Solo Operators
Sheets are storage with formulas. Dashboards are systems with links. The difference costs you clarity:
- Stale status breaks truth: Sheet
Invoices → Status: SentstaysSentafterdueDatepasses. Nocron sent→overduesrc/app/api/cron/daily/route.ts:69. YourReceivablesformula sumsSentas healthy when it'sOverduerisk. You think₹80k incomingbut₹45kis 22 days late. - Disconnected tables hide profit:
Invoicesin Sheet1,Transactionsin Sheet2,Investmentsin Sheet3 have noFK.transactions.invoiceIdsrc/lib/db/schema.ts:98linkage missing → you don't know whichincometies to whichinvoiceorproject.MRRis manual math,pipelineis guess. - Manual month math drifts:
usageCounters month:2026-06src/lib/db/schema-public.ts:75auto-increments viaincrementUsageCountersrc/lib/plans/limits.ts:193atomictx. In Sheets youSUMIF date >= June1manually. One filter wrong, one row mis-typed₹12,000vs₹1,20,000, your dashboard lies and you won't notice for a month. - No live investment sync:
investments.transactionId → transactions.idsrc/lib/db/schema.ts:275links SIP to banked income. In Sheets,Investmentstab floats free — you invest₹30kyou haven't collected, thinking profit is bigger.
A Sheet dashboard is a monthly snapshot you rebuild. A linked dashboard is a live graph you trust.
The Solo Business Metrics That Matter (6, Not 26)
You don't need 26 KPIs. You need 6 that tell you can I pay rent and grow:
1. MRR & Realized Income
MRR = sum invoices recurringInterval:monthly where status paid this month derived via recurringNextDate src/lib/db/schema.ts:81 src/lib/utils/recurring.ts:5 + transactions type:income src/lib/db/schema.ts:87.
Dashboard FinanceOverviewClient Recharts src/components/finance/FinanceOverviewClient.tsx shows Income: bar per month from transactions — not invoiced, received. Sheet shows invoiced, which is vanity until banked.
2. Receivables & Overdue Ratio
Receivables = sum invoices status sent|overdue src/lib/db/schema.ts:59 + pendingInvoices GET /api/sidebar/stats src/app/api/sidebar/stats/route.ts:55. Overdue ratio overdue / receivables >30% means collections problem, not sales problem. cron sent→overdue makes ratio live, not stale.
3. Pipeline Health
activeProjects where status:active src/lib/db/schema.ts:21 + totalTasks/doneTasks src/app/api/projects/route.ts:28 per project. projects budget numeric(12,2) src/lib/db/schema.ts:35 sum active = pipeline value. DashboardFilter.tsx live, Sheet needs manual hunt.
4. Net Profit & Expense Ratio
transactions type:expense category:Hosting|SaaS|Subcontractor summed vs income → net = income - expense. Expense ratio >35% signals tool/subcontractor bloat. Linked transactions.clientId/projectId src/lib/db/schema.ts:97 lets you drill Acme profit = Acme income - Acme expenses — Sheet can't without VLOOKUP hell.
5. Runway
runway = (cash + receivables×0.7) / avgMonthlyExpenses. Finance → Transactions 3-month avg auto; Sheet you estimate. Receivables haircut 0.7 because overdue is uncertain — dashboard knows overdue ratio, Sheet doesn't.
6. Investment Rate
investments amount per month src/lib/db/schema.ts:273 vs net profit → rate = investments / net. investments.transactionId linkage proves invested realized income, not phantom invoiced. FinanceOverviewClient charts it beside income — Sheet has two tabs that don't talk.
These 6 fit one Dashboard screen src/app/(dashboard)/dashboard/page.tsx — TodayFocusCard + FinanceOverviewClient + Investments chart. You see health in 60 seconds.
How RunoSO Dashboard Computes Live
Not by formulas you maintain. By FK graph:
invoices (clientId, projectId) —FK→ clients, projects
transactions (invoiceId, clientId, projectId) —FK→ invoices, clients, projects
investments (transactionId) —FK→ transactions
personalTasks (projectTaskId) —FK→ tasks —FK→ projects
assets_subscriptions (cost, renewalDate, billableTo) —cost→ transactions
notifications (invoice_overdue, domain_expiring) —trigger→ dashboard badges- Create
invoicePOST /api/invoices/route.ts:84withitems jsonbsrc/lib/db/schema.ts:74+taxRatesrc/lib/db/schema.ts:76→ server recomputestotal = subtotal - discount + taxsrc/app/api/invoices/route.ts:118 - Pay →
POST /api/transactions/route.ts:131syncInvoicePaidStatusflipssent→paidsrc/app/api/transactions/route.ts:21→FinanceOverviewClientbar rises live cron dailyflipsoverdue+notifications+digest emailsrc/lib/emails/send.ts:469→pendingInvoicesbadge onsidebar statswarns before you open Financeinvestmentscreatedsrc/lib/investments/create-investment.ts:15auto-creates linkedexpensetransaction if needed — graph stays consistent
You don't rebuild dashboard monthly. You create business objects and dashboard is the view.
Mistakes That Keep Metrics Opaque
Mistake 1: Tracking invoiced, not received.
Invoices total ₹2.3L means nothing until Transactions income ₹2.1L confirms. Filter Finance → Invoices paid vs Transactions income gap is your collection risk. In Sheets you compare two tabs manually and miss gap.
Mistake 2: Lumping expenses as Expenses.
₹68k expenses without category:Hosting 12k, SaaS 18k, Subcontractor 38k hides where to cut. Use transactions.category src/lib/db/schema.ts:94 consistently — dashboard grouping shows bloat instantly.
Mistake 3: Investing without linking.
Creating investments row SIP ₹15k without transactionId src/lib/db/schema.ts:275 link breaks investmentRate truth. Always link via transaction — proof you invested collected profit, not invoiced hope.
Sheets vs Dashboard: Comparison
| Metric question | Sheets (manual) | RunoSO Dashboard tenant_${id} live |
|---|---|---|
Are we profitable? | SUMIF across tabs, stale Sent | FinanceOverviewClient Recharts income - expense linked transactions |
What's overdue? | Cell Sent never flips, no alert | cron sent→overdue + notifications + badge remainingTasks/pendingInvoices |
Pipeline value? | Sum budget column manually, misses tasks | activeProjects + budget sum + done/total per project GET /api/projects |
Client concentration? | PIVOT fragile, no FK | transactions group by clientId → Acme 65% risk visible |
Runway? | Receivables guess, investment separate | receivables×0.7 + cash / 3mo avg expense live |
Investment rate healthy? | Two tabs disconnected | investments.transactionId FK → Investments chart vs net |
| Maintenance | 2 hrs/mo rebuild formulas, breaks | 0 — create invoice/transaction/investment, view updates |
You don't need a better spreadsheet. You need fewer reconciliations and more linked truth.
Get Dashboard Truth in 20 Minutes
- Link last month's invoices to
transactions— ensure eachpaidhastransaction invoiceIdPOST /api/transactions→ watchFinanceOverviewbars correct from invoiced to received. - Categorize transactions — tag every
expensewithcategoryHosting|SaaS|Subcontractor|Other→Expense ratiobecomes actionable. - Create 1 investment linked
investmentssrc/lib/investments/create-investment.ts:15withtransactionId→Investment chartlive vsnet. - Pin Dashboard as home:
src/app/(dashboard)/dashboard/page.tsxis now your Monday review start —TodayFocusCard+FinanceOverviewClient+ badgespendingInvoicesin one glance.
Stop rebuilding Sheets. Start seeing health.
RunoSO turns freelance finance from 3 disconnected Sheets into one live graph — invoices, transactions, and investments linked, with cron, Recharts, and runway you can trust.
→ See Your Metrics Live — Free on RunoSO
By Gautam Parmar src/app/(marketing)/about/page.tsx:44 — solo founder, Next.js 16 Razorpay Resend, building 26-table Neon Drizzle OS in public on X.
Keep Reading
- Keep money flowing: invoice automation draft to paid.
- Weekly rhythm: freelance weekly review operating rhythm.
- Organize business: how to organize your freelance business.
FAQ
What are the 6 solo metrics? MRR/realized income, receivables + overdue ratio, pipeline health, net profit + expense ratio, runway, investment rate — all live on Dashboard FinanceOverviewClient.
Why does overdue ratio matter more than total? ₹80k receivables healthy vs ₹80k with 60% overdue is crisis. cron sent→overdue makes ratio live; Sheet hides it.
How is runway calculated? (cash + receivables×0.7) / avgMonthlyExpenses — dashboard builds it from transactions + invoices graph, not manual Sheet math.



