You quote ₹1.2L for 5 pages because last was ₹1.2L. Client Add blog+shop? +18h unpaid. Pay subcon ₹30k + hosting ₹2.4k from same pot. Month-end ₹42k for 78h = ₹538/h — below ₹1500 floor.
Why Freelance Budgets Fail Before Work Starts
Three detachments kill profit before kickoff:
- Quote detached from costs.
projects budget numeric(12,2)src/lib/db/schema.ts:35is120000typed in RunoSO vs₹1.2Ltext +Rate×Hoursthat breaks on insert. No link toassetsHosting costMonthlysrc/lib/db/schema.ts:196₹2.4k/mo ×3 = ₹7.2ksilent leak. - Advance detached from cash. Log
advance YEStext, nottransactions category:Project Advance projectIdsrc/app/api/transactions/route.ts:57thatsyncProjectAdvancesrc/app/api/transactions/route.ts:21sums intoprojects advancesrc/lib/db/schema.ts:36. Unfunded 15d → discount next quote to₹1L— impatience tax. - Invoice detached from budget.
invoices amount + items jsonb + discountsrc/lib/db/schema.ts:69live inInvoice tabwhilebudgetinQuote tab. Overrun never becomes change-order because noprojectId fksrc/lib/db/schema.ts:66.
Profit needs budget → advance → tasks → invoice → transactions as one graph.
The Pre-Quote Budget Graph
In tenant_${id} src/lib/db/tenant.ts:47, budget is typed and linked:
clients(id)
projects(clientId fk notNull onDelete:cascade src/lib/db/schema.ts:25, title, type dev|content|design|other src/lib/db/schema.ts:20, budget numeric(12,2), advance numeric, deadline timestamp, status active|on-hold|completed)
tasks(projectId fk notNull src/lib/db/schema.ts:47, status todo|in-progress|done, priority low|medium|high, dueDate)
invoices(clientId, projectId fk, invoiceNumber unique, amount numeric, items jsonb, discount, taxRate numeric(5,2) src/lib/db/schema.ts:76, taxType varchar(50) src/lib/db/schema.ts:77, recurringInterval varchar(20) src/lib/db/schema.ts:80)
transactions(type income|expense src/lib/db/schema.ts:87, amount numeric, category, projectId, invoiceId src/lib/db/schema.ts:98)Budget planning in 4 typed steps:
- Anchor by
type.POST /api/projects type:dev|content|designsrc/lib/db/schema.ts:20sets floor —dev ₹1.5k/h,design ₹1.2L,content ₹40k/mo. Type beats gut. - Set
budget + advancenumeric.budget 140000 advance 35000src/lib/db/schema.ts:35autotransactions Project Advancesrc/app/api/projects/route.ts:145→ receivables drop. Ruleadvance 25-30%. - Map tasks to price.
9 tasks × 8h × ₹1500 = ₹1.08Lsanity-checks₹1.2L→₹12k buffer 10%visible. Without tasks, quote₹1.2Lfor13 tasksand bleed. - Spawn invoice lines that match budget.
POST /api/invoicessrc/app/api/invoices/route.ts:84withitems jsonb[{Discovery 20000},{Build 70000},{Buffer 17000}]→ serversubtotal - discount + taxsrc/app/api/invoices/route.ts:119computedTotalsrc/app/api/invoices/route.ts:127— no typo.
Now budget is queryable: filter projects type:design budget avg → next Shopify quote ₹1.38L anchored, not guessed.
Hourly vs Fixed vs Value — Budget Implications
| Model | budget numeric behavior | Trap | RunoSO guardrail |
|---|---|---|---|
Hourly ₹1500/h | No cap, transactions per log | Speed → 60h = ₹90k for ₹1.2L value | Use for type:other spike only |
Fixed ₹1.4L | budget 140000 + advance 35k one invoice | Creep +shop stays 140k — margin dies | Included/Excluded in description |
Value ₹1.6L | budget 160000 + advance 50k items jsonb + portal proof | No proof → discount to ₹1.1L | Show 14/14 done + paid 100% dossier |
No model wins alone. Mix: Fixed base ₹1.4L + Value anchor ₹1.6L + Hourly +₹4k/revision. items jsonb holds mix.
Budget vs Actual — Without Re-typing
Flat Sheet Budget vs Actual is Budget!B2 - Actual!D2 that you update Sunday. Linked graph auto:
- Budget:
projects budget 140000src/lib/db/schema.ts:35 - Funded:
projects advance 35000viasyncProjectAdvancesrc/app/api/transactions/route.ts:21 - Invoiced:
sum invoices amount where projectId + status sent|paid|overduesrc/lib/db/schema.ts:58 - Spent:
sum transactions type:expense projectIdsrc/app/api/transactions/route.ts:91 - Margin live:
Invoiced - Spent = ₹72k 51%— noSUMIFS.
GET /api/transactions?projectId= src/app/api/transactions/route.ts:88 + GET /api/invoices?page=1 src/app/api/invoices/route.ts:43 feed FinanceOverviewClient Recharts.
Excel vs QuickBooks vs FreshBooks vs RunoSO — Budget Truth
| Need | Excel/Sheets | QuickBooks | FreshBooks | RunoSO | |
|---|---|---|---|---|---|
| Budget typed | Text 1.2L — can't sum | Estimate but no advance | No field | budget numeric src/lib/db/schema.ts:35 + advance + transactions sync | |
| Task→cost | Manual Hours | No tasks | No tasks | tasks projectId fk src/lib/db/schema.ts:47 maps cost | |
| Auto compute | Rate×Hours breaks | Auto | Auto | Server taxable*rate/100 src/app/api/invoices/route.ts:121 | |
| Overdue & recurring | Manual Overdue? | Flag only | Reminder | Cron sent→overdue src/app/api/cron/daily/route.ts:46 30 3 * * * vercel.json:4 + recurringInterval src/lib/utils/recurring.ts:5 | |
| India GST | Manual 9+9 vs 18 | US tax | US | `taxType cgst_sgst | igst src/app/api/invoices/route.ts:124` auto |
| Cost | Free + 4h rebuild | ₹1,200/mo | ₹1,500/mo | Free 5/mo src/lib/plans/limits.ts:28 → Solo ∞ |
Excel lies by typo; QuickBooks/FreshBooks auto-compute but aren't freelance project graph with advance + costMonthly. RunoSO is.
Template You Can Ship Tomorrow
Keep in projects notes:
| Scope item | budget share |
|---|---|
| Discovery | ₹18k |
| 5 pages | ₹68k |
| Blog CMS | ₹12k |
| Revisions | ₹15k |
| Hosting 3mo | ₹7.2k |
| Buffer 15% | ₹19.8k |
| Total 75h | ₹1.4L → quote ₹1.45L advance 35k |
Mistakes That Leak Budget After Quote
Forgetting advance. ₹1.4L NET-15 without advance 35k → unfunded 15d → discount next to ₹1.1L. Always advance numeric at quote.
Bundling pass-throughs silent. Pay hosting ₹2.4k yourself then quote ₹1.2L all-in — hide ₹7.2k leak. Split invoices items Hosting ₹7200 billableTo:client.
RunoSO budgets with linked truth — budget numeric + advance + tasks + invoices items + assets costs — so every quote carries profit, not hope.
→ Quote With Margin — Try RunoSO Free
By Gautam Parmar — solo founder, Next.js 16 + Tailwind v4 + Neon + Drizzle + AES-256-GCM, building in public on X.
Keep Reading
- Keep profit visible: Expense Tracking: Categories That Reveal Profit.
- Price cases: Pricing Freelance Projects Profitably.
- Automation: Invoice Automation Draft to Paid.
FAQ
Should beginners start fixed or hourly? Fixed with buffer budget +15% src/lib/db/schema.ts:35 + Included/Excluded guardrail. Add hourly +₹4k/revision change-order and value anchor outcome/10 as you collect portal proof. Linked graph supports blend; Sheets forces one.
How do I stop discounting under pressure? Show tasks estimate + assets lines in invoices items jsonb + past dossier proof. Make discount numeric src/lib/db/schema.ts:75 explicit ₹5k off = remove 1 revision task — never free value.
Can I compare budgets across projects? Yes — filter projects type:design + budget vs transactions income src/lib/db/schema.ts:92 + invoices status paid. FinanceOverviewClient src/components/finance/FinanceOverviewClient.tsx tells you fixed ₹1.4L avg 55% margin vs hourly ₹90k fast penalty — next quote smarter.



