Your client calls at 9 PM on a Friday.
"Our website is down. It says the domain expired. Can you fix it?"
You check the registrar. The domain expired two days ago. Auto-renew was off. The renewal email went to an old address you no longer check. The client is furious. You're scrambling to pay $80 in redemption fees for a domain you manage.
This is not a technical failure. It's a systems failure. And for freelancers managing 15-50 domains across 8-12 clients, it happens constantly — until you build a system.
The Hidden Cost of Scattered Asset Tracking
Most solo operators don't think of themselves as asset managers. But you are. Every client relationship leaves behind a trail:
- A domain at GoDaddy or Namecheap with its own expiry date
- Hosting on Hostinger, DigitalOcean or AWS with monthly billing
- An SSL certificate that expires every 90 days
- A GitHub repo with production credentials
- 3-4 SaaS subscriptions billed to your card or theirs
- Social accounts whose passwords live in your password manager — or worse, a Slack DM
Where do you track all this?
Be honest: a Google Sheet called Copy_of_CLIENTS_2024_FINAL_v3.xlsx. A Notion table you stopped updating in March. A "passwords.txt" file on your desktop. Sticky notes on your monitor for renewal dates.
This scattered approach has a real cost:
1. Direct financial loss: The average freelancer manages $1,200-$2,400/year in client-billable subscriptions and hosting. Missing one auto-renewal and paying redemption or downtime costs wipes out your margin. One expired SSL on an e-commerce client costs them sales — and you, trust.
2. The 20-minute dig: You need the Hostinger IP for Client X. You search email. You check Notion. You ask in Slack. You finally find it in a vault entry named server_old2. Twenty minutes to find one IP. Multiply by twice a week and you're burning 70+ hours a year searching, not building.
3. The handover nightmare: A client offboards. They ask for "all access." You spend a day collecting domains, hosting logins, repo URLs, and Cloudflare zones from five places. You miss one API key. Two weeks later they call because a cron job broke.
4. The security hole: Assets linked to credentials that live in spreadsheets are not secure. One shared sheet with edit access = every intern sees every client password in plaintext.
A client record without its assets is an incomplete record. An asset without its client, project, and credential is an orphan.
What a Real Asset Management System Looks Like
Forget enterprise CMDBs. Freelancers need a simple, linked structure that mirrors how you actually work:
Layer 1: Every Asset Has a Home
Create one asset type per reality, not one generic table:
- Domains:
name,registrar(GoDaddy/Namecheap),expiryDate,autoRenewtrue/false,dnsProvider, linkedclientId+projectIdsrc/lib/db/schema.ts:149 - Hosting/Servers:
provider,ipAddress,os,plan,costMonthly,renewalDate,vaultItemIdsrc/lib/db/schema.ts:190 - Cloudflare Zones:
zoneDomain,accountEmail,plan, linkeddomainAssetIdsrc/lib/db/schema.ts:164 - GitHub Repos:
repoName,url,visibility,techStack[]src/lib/db/schema.ts:176 - Social Accounts:
platform,handle,vaultItemId,followerCountsrc/lib/db/schema.ts:206 - SaaS Subscriptions:
toolName,plan,cost,billingCycle:monthly|yearly,renewalDate,billableTosrc/lib/db/schema.ts:220
In RunoSO, these are not six spreadsheets. They are six linked tables in one tenant_${id} schema src/lib/db/tenant.ts:67, all queryable via one API GET /api/assets/[category] src/app/api/assets/[category]/route.ts:97 with buildPaginatedQuery pagination.
Layer 2: Every Asset Is Linked
This is where sheets fail. In a sheet, a domain row and its hosting row and its vault credential are three disconnected rows. In RunoSO, they are foreign keys:
assets_hosting.vaultItemId → vaultItems.id src/lib/db/schema.ts:200
assets_cloudflare.domainAssetId → assets_domains.id src/lib/db/schema.ts:170
Open Acme Corp in src/app/(dashboard)/clients/[id]/page.tsx, you see their 3 domains, 2 hosting boxes, 1 Cloudflare zone, 2 repos — and the encrypted credentials to access them via VaultPageClient, without leaving the client view.
No more Ctrl+F across tabs.
Layer 3: Expiry Is Not a Calendar Event — It's an Automated Workflow
A date in a sheet does nothing. A date in a system does:
- Domain expiries: RunoSO's cron
src/app/api/cron/daily/route.ts:275checksDOMAIN_MILESTONES [14,7,3,1,0]every day at 03:30 UTC (vercel.json:4). IfexpiryDatehits7days andautoRenew:false, it creates anotificationsrowsrc/lib/db/schema-public.ts:190type:domain_expiring+ inserts into digest emailsendReminderDigestEmailsrc/lib/emails/send.ts:469. - Hosting/Subscription renewals:
RENEWAL_MILESTONES [7,3,1,0]forrenewalDate, skips ifcostis zero. - Result in UI: Asset detail
src/components/assets/AssetDetailPageClient.tsxshows amber7 daysbadge, not a silent sheet cell.
You stop checking dates. The system nags you.
The difference: A spreadsheet is storage. RunoSO's asset manager is storage + linkage + automation.
The Common Mistakes That Cost Money
Mistake 1: Tracking Renewals in Your Head or Calendar
"I'll remember the Hostinger renewal on the 18th."
You won't. Not across 12 clients with different billing cycles. One Google Calendar event per renewal becomes notification fatigue. You snooze it, you miss it.
Fix: Let renewalDate drive a notification, not your memory. The assets_subscriptions table with billingCycle monthly|yearly ensures you track solitary annual Figma renewal differently from monthly Vercel.
Mistake 2: Storing Assets and Credentials Separately
You have a domains sheet. And a 1Password vault with an entry called acme-hosting. No link between them. When you need to restart Nginx, you open the vault, search acme, find 4 entries, guess which IP matches which domain.
Fix: Link at the DB level. In RunoSO, creating a hosting asset asks for vaultItemId — you pick the server credential from your encrypted vault src/lib/vault/crypto.ts:22 AES-256-GCM. One click copy, no plaintext juggling.
Mistake 3: No Handover Artifact
When you offboard, you Slack a list: "Here's your domain, here's hosting, good luck." The client loses it in a week.
Fix: Use Digital Asset Handover Template /templates/domain-handover-template — export a branded PDF from RunoSO with every assets_domains, assets_hosting, vaultItems linked to that client. The portalTokens src/lib/db/schema-public.ts:169 lets the client view it via portal/[id] without a login. Clean exit = referral.
Putting It Together: Your 15-Minute Asset Audit
- List every domain you manage. Add to
Assets → DomainswithexpiryDateandautoRenew. IfautoRenew:false, set phone reminder and let RunoSO's7-daynotification be backup. - Link hosting to domains. For each domain, add its hosting
provider,ipAddress,renewalDate, and link itsvaultItemId(the SSH credential). Verify the IP resolves. - Catalog SaaS. Add every tool billed to you or the client in
SubscriptionswithcostandrenewalDate. FilterbillableTo:clientto invoice cleanly. - Connect to clients. Open each
clients/[id]and verify their asset count matches reality. IfAcmeshows0 domainsbut you know they have two, you found a gap. - Enable digest. Check
/notifications— you will start receiving the14/7/3/1/0reminder digest, not silent sheet cells.
In RunoSO, this audit lives in one view: src/app/(dashboard)/assets/page.tsx AssetsPageClient tabs Domains | Hosting | Social | Subscriptions, each paginated via src/lib/utils/pagination.ts:11.
Why This Beats Notion / Sheets / Generic Trackers
| Spreadsheet/Notion | RunoSO Asset Manager |
|---|---|
6 disconnected tables, manual VLOOKUP | 6 normalized tables with FK links in tenant_${id} |
| Dates inert, no alerts | cron/daily creates notifications + email digest |
| Credentials plaintext in sheet | vaultItems AES-256-GCM gcm:iv:tag:enc src/lib/vault/crypto.ts:28 |
| Cost is just a number | costMonthly + billingCycle → Finance transactions linkage for profitability |
| Handover = copy-paste | One-click handover PDF + portalTokens share link |
You are not buying a domain tracker. You are replacing the archaeology dig with a single query: SELECT * FROM assets_domains WHERE clientId = ?.
RunoSO is a personal business OS for freelancers — clients, projects, invoices, encrypted vault, content pipeline, digital assets, and finance, all linked in one dashboard. Stop hunting sheets for an IP. Build the linked system.
→ Try RunoSO Free — Track 5 Assets
Solo building in public by Gautam Parmar — src/app/(marketing)/about/page.tsx:44 founder of RunoSO & Creovira Digital, Google Certified Marketer, building secure Next.js 16 Tailwind v4 Drizzle architectures. Follow on X and LinkedIn.
Keep Reading
- Secure what you track: where freelancers should never store passwords.
- The engine behind it: scalable 26-table SaaS schema.
- Renewal checklist: domain renewal checklist never lose domain.



