You finish Mar ₹3.2L, Apr ₹1.1L — why? Pipeline 4 leads, 2 proposals felt strong. But sent ₹2.4L + overdue ₹85k Acme 21d, retainer USD 1500 missed because recurringNextDate not tracked, advance ₹30k not logged Project Advance. You see ₹1.1L, not ₹1.1L + ₹85k + ₹1.27L + ₹30k = ₹3.52L pipeline.
Forecasting isn't guess. It's sent + overdue + recurringNextDate + advance as graph.
Why Freelance Forecasts Fail
- Sent = forgotten.
invoices status sentsrc/lib/db/schema.ts:58in SheetsSent? YES—cron daily 30 3 * * *vercel.json:4never flipssent→overduesrc/app/api/cron/daily/route.ts:46lt(dueDate, now)so₹85kstayssenthope, not action. - Retainers as memory.
USD 1500 monthlyisCalendar repeat— forgetMar 5→ invoiceMar 12late →Pay next cycle.recurringInterval monthly|quarterly|yearlysrc/lib/utils/recurring.ts:5+recurringNextDatesrc/lib/db/schema.ts:81should auto-clone; Sheets copiesINV-014→015dup → month lost. - Pipeline detached.
clients status lead|activesrc/lib/db/schema.ts:5+projects budget numericsrc/lib/db/schema.ts:35never sum tosent + recurring + budget×close%. Trello₹1.2L 60%not linked totransactions.
Result: you react Apr low by cold outreach panic vs knowing ₹85k overdue collectable + ₹1.27L retainer due Apr 5 = ₹2.12L already before new sales.
The Linked Forecast Graph
clients(status lead|active)
projects(clientId fk, budget numeric(12,2) src/lib/db/schema.ts:35, advance numeric src/lib/db/schema.ts:36, status active|on-hold|completed, deadline timestamp)
invoices(clientId fk, projectId fk src/lib/db/schema.ts:66, amount numeric src/lib/db/schema.ts:69, status draft|sent|paid|overdue src/lib/db/schema.ts:58, issueDate timestamp src/lib/db/schema.ts:71, dueDate src/lib/db/schema.ts:72, recurringInterval varchar(20) src/lib/db/schema.ts:80, recurringNextDate timestamp src/lib/db/schema.ts:81, items jsonb)
transactions(type income|expense, amount numeric src/lib/db/schema.ts:92, category Invoice Payment|Project Advance, date timestamp src/lib/db/schema.ts:96, invoiceId fk src/lib/db/schema.ts:98)
cron daily flips overdue + generates recurring draft src/app/api/cron/daily/route.ts:69 + nextRecurringDate() src/lib/utils/recurring.ts:5Forecast = 4 buckets:
- Sent.
GET /api/invoicessrc/app/api/invoices/route.ts:43status sent→₹2.4LdueApr 10-20. - Overdue.
status overduelt(dueDate, now)src/app/api/cron/daily/route.ts:49→₹85k12-21d. CronnotificationRows invoice_overduesrc/app/api/cron/daily/route.ts:211+ digestsrc/app/api/cron/daily/route.ts:245— follow up today. - Recurring MRR.
recurringInterval != none && lte(recurringNextDate, now)src/app/api/cron/daily/route.ts:69clones draft —USD 1500 + 40k=₹1.67LApr MRR without new sales. - Advances.
transactions Project Advancesrc/app/api/transactions/route.ts:57sumadvancesrc/lib/db/schema.ts:36₹60k May— floor.
Apr forecast = Sent 2.4L×80% + Overdue 85k×70% + Recurring 1.67L + Advance 60k = ₹4.78L weighted.
3-Scenario Forecast Table
| Bucket | Apr amount | Conservative 60% | Base 80% | Optimistic 100% | Why % varies |
|---|---|---|---|---|---|
Sent ₹2.4L due Apr 15 | 2.4L | 1.44L | 1.92L | 2.40L | dueDate +15 vs history paid 12d avg |
Overdue ₹85k 12-21d | 85k | 42.5k | 59.5k | 85k | Acme 21d needs call, not email |
Recurring MRR USD1500+40k | 1.67L | 1.67L | 1.67L | 1.67L | Auto nextRecurringDate +1mo certain if not churned |
| Project Advance May | 60k | 60k | 60k | 60k | Already transactions |
| Pipeline proposals ₹4L × 30% | 1.20L | 0 | 36k | 1.20L | lead→active close rate |
| Total | ~₹6.12L gross | ₹4.13L | ₹5.14L | ₹6.12L | Base 5.14L = hire/no-hire line |
Update weekly via GET /api/transactions?startDate=&endDate= src/app/api/transactions/route.ts:88 + FinanceOverviewClient Recharts — Sheet Forecast!B2 guess replaced.
Excel vs QuickBooks vs FreshBooks vs RunoSO — Forecast
| Need | Excel/Sheets | QuickBooks | FreshBooks | RunoSO | |||
|---|---|---|---|---|---|---|---|
| Receivables status | Text Sent manual | Auto Sent/Overdue | Auto | `status draft | sent | paid | overdue src/lib/db/schema.ts:58 + cron sent→overdue src/app/api/cron/daily/route.ts:46` |
| Recurring predict | Copy row, forget | Recurring US | Recurring | `recurringInterval none | monthly | quarterly | yearly src/lib/utils/recurring.ts:1 + recurringNextDate auto generates + emails sendInvoiceEmail src/app/api/cron/daily/route.ts:155` |
| Advance visibility | YES text | No Project Advance | No | syncProjectAdvance src/app/api/transactions/route.ts:21 sums transactions Project Advance into projects advance | |||
| Auto compute | =SUM breaks | Auto | Auto | Server computedTotal src/app/api/invoices/route.ts:127 + numeric(12,2) tamper-proof | |||
| Pipeline link | Deals tab separate | No client→project→invoice graph | No | clients→projects→invoices→transactions FK graph src/lib/db/schema.ts:25 queryable | |||
| Cost | Free + panic Apr | ₹1,200/mo | ₹1,500/mo | Free 5/mo src/lib/plans/limits.ts:28 → Solo ∞ finance_charts true |
Excel forecasts hope; QuickBooks/FreshBooks auto overdue but not advance + recurringNextDate + project budget pipeline. RunoSO forecasts from linked graph.
Weekly Rhythm 15 Minutes
- Mon: Check
overdue ₹85k→ callAcme 21d—notificationRows href /finance/invoices/[id]src/app/api/cron/daily/route.ts:216tells which. - Wed: Verify
recurringGeneratedsrc/app/api/cron/daily/route.ts:266—Apr 5 USD 1500drafteddraft→sentifemailedThisInvoicesrc/app/api/cron/daily/route.ts:173. - Fri: Update
projects status active→completed—budget 140kmovespipeline→invoiced→ accuracy±5%in 4 weeks.
Mistakes That Wreck Predictability
Counting draft as forecast. invoices status draft src/lib/db/schema.ts:58 not sent — client hasn't seen. Forecast sent + overdue + recurring only; draft is pipeline 30%, not cash.
Ignoring dueGapMs preservation. Cron clones dueGapMs = dueDate - issueDate src/app/api/cron/daily/route.ts:92 → NET 15 preserved. Sheets copy Apr 5 issue Apr 5 due Apr 12 but original NET 30 → you expect Apr 20 but client pays May 5 — forecast 15 days off.
Not weighting overdue. ₹85k overdue 21d at 100% when Acme always pays 30d — weight 50%. Track invoice turnaround 12d avg vs Acme 28d outlier — forecast honest.
RunoSO turns pipeline into math — sent, overdue, recurringNextDate, advance linked — so next month's income is predicted, not prayed for.
→ Forecast Predictably — Try RunoSO Free
By Gautam Parmar — solo founder. Revenue that forecasts beats revenue that surprises.
Keep Reading
- Keep overdue low: How to Chase Late Payments.
- Retainer MRR: Recurring Invoices for Retainers.
- Metrics: 8 Metrics Solo Businesses Must Track.
FAQ
How far to forecast as freelancer? 30d detailed sent+overdue+recurring + 90d pipeline×close%. recurring yearly src/lib/utils/recurring.ts:5 gives 12-mo MRR base; projects budget src/lib/db/schema.ts:35 give 90d weighted. Beyond 90d is guess.
What if client pays late always? Tag client payment behaviour in projects notes — weight overdue 50% not 80%. Cron sent→overdue src/app/api/cron/daily/route.ts:46 history trains your %. Acme 28d avg → forecast May 5 not Apr 15.
Can I see forecast vs actual? Yes — FinanceOverviewClient src/components/finance/FinanceOverviewClient.tsx income vs expense Recharts compares forecast base ₹5.14L logged vs transactions income Apr actual. Free finance_charts false src/lib/plans/limits.ts:42 vs Solo true src/lib/plans/limits.ts:59 — upgrade unlocks live.



