RunoSO - Business OS for Solo Operators LogoRunoSO
FeaturesPricingTemplatesBlogAbout
Sign inStart free
RunoSO LogoRunoSO

Run your solo business. From one place.

Built in India 🇮🇳

Product

FeaturesPricingBlogChangelogRoadmap

Legal

Terms & ConditionsPrivacy PolicyRefund PolicyCookie PolicyData Deletion

Connect

Twitter/XLinkedInInstagramhello@runoso.in
Made by RunoSO
© 2026 RunoSO. All rights reserved.
Back to Blog

Featured Articles

Build in Public

Why I Ditched Notion & Sheets to Build RunoSO

7 min read
Technical Deep-Dive

How I Built a Zero-Knowledge Vault with AES-256

10 min read
Productivity

Best Freelance Tools in 2026 — Honest Stack Review

11 min read
View all posts
  1. Home
  2. Blog
  3. Expense Tracking for Freelancers: Categories That Reveal Profit
Finance

Expense Tracking for Freelancers: Categories That Reveal Profit

By Gautam Parmar18 September 20268 min read
Expense Tracking for Freelancers: Categories That Reveal Profit — featured image

You earned ₹2.8L last month. Bank shows ₹1.9L. Where did ₹90k go?

Sheet Expenses 2025 has 147 rows, 4 categories Tools | Travel | Food | Misc, no client or project link, amount as 2,000 text. You sum Misc ₹42k and still can't tell if Acme Revamp budget ₹1.2L was profitable after subcontractor ₹30k + hosting ₹2.4k.

You log spends, you don't learn profit.

Why Generic Expense Lists Hide Profit

Most freelancers track expenses like a diary, not a ledger:

  • Flat categories hide margin. Tools ₹12k lumps Figma for Acme (billable) with Notion personal ₹1k (overhead). No clientId | projectId link → can't answer Did Acme profit?
  • No link to revenue. transactions type expense src/app/api/transactions/route.ts:89 lives apart from invoices amount numeric(12,2) src/lib/db/schema.ts:69 and projects budget numeric(12,2) src/lib/db/schema.ts:35. Sheets VLOOKUP breaks on insert.
  • Manual sums drift. Type 5000 as 50000 — no server computedTotal Math.round((taxable+tax)*100)/100 src/app/api/invoices/route.ts:127 guard, chart lies for months.

Profit isn't Income - Expenses in one cell. It's per client/project - overhead over time. Flat lists can't do that.

The 7 Categories That Actually Reveal Profit

Forget 30 categories. Use 7 that map to how freelancers spend and how clients pay:

1. Client-Billable Tools

Figma, Webflow, Stock for a project. Link transactions clientId + projectId src/lib/db/schema.ts:97 + category Billable Tools. Recover via invoices items jsonb src/lib/db/schema.ts:74 line Tools ₹4k.

2. Subcontractors

Dev ₹25k, Content ₹12k per project. Link projectId → Budget ₹1.2L - Subcon ₹37k = Gross ₹83k. Sheets hides this as Freelancer payment without FK.

3. Hosting & Infra Pass-Through

assetsHosting costMonthly numeric(12,2) src/lib/db/schema.ts:196 ₹2,400/mo + assetsDomains expiryDate. Mark billableTo client vs personal — un-invoiced ₹28.8k/yr leak if missed.

4. SaaS Overhead

assetsSubscriptions cost billingCycle monthly|yearly src/lib/db/schema.ts:224 Notion ₹1k. Overhead SaaS billableTo personal src/lib/db/schema.ts:227 — overhead, not project.

5. Marketing & Acquisition

Ads ₹8k to get clients. category Marketing without clientId → CAC via clients status lead→active src/lib/db/schema.ts:5.

6. Professional Services

CA ₹12k/yr → category Professional — prevents March 15% expense surprise.

7. Owner Draw & Investments

investments type stock|sip|crypto|fd|other src/lib/db/schema.ts:267 amount numeric src/lib/db/schema.ts:273 + transactionId src/lib/db/schema.ts:275. Separates profit ₹2L → SIP ₹40k wealth, not cost.

With these 7, every transactions amount numeric(12,2) src/lib/db/schema.ts:92 has a profit question answered: Billable? Which project? Recurring overhead?

The Linked Graph: Expense → Client → Project → Invoice

In RunoSO tenant_${id} src/lib/db/tenant.ts:47, expense is not a row, it's a node:

clients(id, name)
  projects(clientId fk notNull onDelete:cascade src/lib/db/schema.ts:25, budget numeric(12,2), advance numeric(12,2))
    transactions(type income|expense, amount numeric, category varchar(100), clientId fk, projectId fk, invoiceId fk src/lib/db/schema.ts:97, date timestamp)
    invoices(clientId fk, projectId fk src/lib/db/schema.ts:66, amount numeric, items jsonb, taxRate, taxType varchar(50) src/lib/db/schema.ts:77)
  assetsSubscriptions(toolName, cost numeric, billingCycle, billableTo)
  assetsHosting(costMonthly numeric src/lib/db/schema.ts:196)

What linked gives you:

  1. Auto P&L per project. GET /api/transactions?projectId=xxx src/app/api/transactions/route.ts:91 → ₹1.2L - ₹48k = ₹72k 60% no SUMIFS.
  2. Client profitability. transactions + clientId → Acme lifetime ₹4.2L - ₹73k = ₹3.47L.
  3. Overdue-aware. cron daily 30 3 * * * vercel.json:4 flips sent→overdue src/app/api/cron/daily/route.ts:46. Receivables excluded until syncInvoicePaidStatus confirms.

Excel vs QuickBooks vs FreshBooks vs RunoSO

NeedExcel/SheetsQuickBooksFreshBooksRunoSO linked graph
Category depthText Tools — breaks on typo Tols50+ categories, US-centricSimple Expense list7 typed + varchar(100) src/lib/db/schema.ts:94 + clientId/projectId FK
Auto compute=SUM(D2:D90) manual, no guardAuto but US tax onlyAuto totalsServer subtotal - discount + tax src/app/api/invoices/route.ts:119 + transactions amount numeric typed — tamper-proof
Client/project linkVLOOKUP across tabs, failsClient link, no project graphClient link, weak projectclientId + projectId + invoiceId FKs in one query src/app/api/transactions/route.ts:91
Overdue & recurringManual Overdue? YESOverdue flag, no cronReminders onlyCron sent→overdue src/app/api/cron/daily/route.ts:46 + `recurringInterval nonemonthlyquarterlyyearly src/lib/utils/recurring.ts:5` auto next invoice
India GSTYou split 9+9 vs 18 manuallyUS sales taxUS`taxType cgst_sgstigstgst src/app/api/invoices/route.ts:124 + taxRate numeric(5,2)` server computed
CostFree but 3h/mo manual₹1,200/mo+₹1,500/mo+Free 5 invoices/mo src/lib/plans/limits.ts:28 → Solo ∞ + finance_charts true src/lib/plans/limits.ts:59

Bottom line: Excel is free but lies by typo; QuickBooks/FreshBooks auto-compute but aren't built for Indian freelance graph client→project→invoice→transaction+assets. RunoSO auto-computes and links.

Setup in 30 Minutes

  1. Import 90 days. POST /api/transactions src/app/api/transactions/route.ts:131 with type expense category Billable Tools|Subcontractors|Hosting|Overhead|Marketing|Professional + projectId where billable. 40 rows enough.
  2. Tag billable vs overhead. assetsSubscriptions billableTo src/lib/db/schema.ts:227 + assetsHosting costMonthly → client vs personal — leaks visible.
  3. Link invoices. Each invoices projectId src/lib/db/schema.ts:66 → matching transactions invoiceId Invoice Payment. Recharts shows true margin.
  4. Weekly review. Filter transactions date src/app/api/transactions/route.ts:88 per project — Acme 58% vs Beta 32% → price next quote.

Mistakes That Keep Expenses Blind

Misc >20% hides profit — keep Misc <5%. Not linking pass-throughs inflates overhead and hides true margin — always projectId + billableTo:client. SIP as expense destroys P&L — use investments type sip src/lib/db/schema.ts:269 linked transactionId.


RunoSO tracks every expense as a linked node — client, project and invoice aware — so profit per project is auto-computed, not spreadsheet-guessed.

→ Reveal Real Profit — Try RunoSO Free


By Gautam Parmar — solo founder building RunoSO in public. Finance that links beats finance that sums.


Keep Reading

  • Budget before you quote: Budget Planning for Freelance Projects.
  • Income without sheets: Track Freelance Income & Expenses Without Spreadsheets.
  • Metrics that matter: 8 Metrics Solo Businesses Must Track.

FAQ

How many expense categories do freelancers really need? Seven. Billable Tools, Subcontractors, Hosting Pass-Through, Overhead SaaS, Marketing, Professional, Owner/Investments. Enough to reveal margin per project without 30-category fatigue. Each maps to transactions category varchar(100) src/lib/db/schema.ts:94 + FKs.

Can I see profit per client without manual pivots? Yes — filter GET /api/transactions?clientId=xxx src/app/api/transactions/route.ts:87 for income vs expense. RunoSO finance_charts true on Solo src/lib/plans/limits.ts:59 auto renders client P&L; Sheets needs SUMIFS each time.

What about GST on expenses? Log expense amount net, invoice taxType cgst_sgst|igst src/app/api/invoices/route.ts:124 handles GST on income side. For input GST, tag category Billable Tools with note GST 18% — future gst_invoicing Pro can automate input credit view.

Try RunoSO for Free

Manage clients, invoices, vault, content, and finances — all from one beautiful dashboard.

Start free
Meet RunoSO
SaaS
Unified Workspace
Finance & Invoicing
Credentials Vault
Content Pipeline

Unified Workspace

The ultimate command center for solo operators. Replace Notion, Sheets, and password managers.

  • Unified client database
  • Real-time key metrics
  • Intuitive navigation
Start free todayLearn more about RunoSO

Featured Articles

Build in Public

Why I Ditched Notion & Sheets to Build RunoSO

7 min read
Technical Deep-Dive

How I Built a Zero-Knowledge Vault with AES-256

10 min read
Productivity

Best Freelance Tools in 2026 — Honest Stack Review

11 min read
View all posts
Meet RunoSO
SaaS
Unified Workspace
Finance & Invoicing
Credentials Vault
Content Pipeline

Unified Workspace

The ultimate command center for solo operators. Replace Notion, Sheets, and password managers.

  • Unified client database
  • Real-time key metrics
  • Intuitive navigation
Start free todayLearn more about RunoSO

Related Posts

Finance

How to Invoice International Clients from India Compliantly

Invoice international clients from India — LUT, FIRC, USD quote and IGST handling linked to transactions cleanly daily. Track in RunoSO with linked clients,.

Finance

Freelance Health Insurance & GST: What’s Deductible

Health insurance for freelancers — 80D, GST input and category mapping so premium doesn’t hide in misc expenses yearly. Track in RunoSO with linked clients,.