Why sheets beat SaaS for solo operators
Most CRMs are built for 20-person sales teams. You end up paying $50 to $150 a month for dashboards you never open, pipeline stages you don't use, and contact limits you'll never hit. For a one-person shop, that's rent for software you're fighting instead of using.
Google Sheets + n8n flips it. You own the data, you control the workflow, and the whole thing costs nothing after the 15-minute setup. New prospect fills out a form? n8n catches it, checks if they're already in your sheet, and either adds them or updates the existing row. Hot lead? You get a Telegram ping before you even check your inbox.
What you're building
Four pieces, all modular — swap any one without touching the rest:
- Triggers — webhooks from your contact form, Gumroad, Stripe, or calendar booking link. Each one feeds into the same pipeline.
- Cleanup — a Code node that normalizes emails, trims whitespace, strips junk. Dirty input in, clean record out.
- Sheet as database — one workbook with tabs for Leads, Deals, and Interaction Logs. No vendor lock-in, no surprise pricing tiers.
- Alerts — Telegram or Slack ping when a high-value lead lands, plus email confirmations to the customer. Speed to lead wins deals.
Step 1 — Set up your sheet
Get the structure right before you wire anything. Create a sheet called Master CRM with these columns in row 1 of your Leads tab:
Lead ID— unique ID (timestamp hash works). Prevents duplicates.Created At— ISO timestamp.Full Name&Email— from the intake form.Company & Website— domain and business name for B2B.Status— dropdown:New,Contacted,Qualified,Won,Lost.Deal Value— estimated contract size.Notes & Context— initial message, project scope, lead magnet origin.
Step 2 — Build the upsert workflow
The trick is handling new leads AND existing contacts without creating duplicates. Here's the n8n flow:
- Webhook node — listen for
POSTrequests from your form. Set response to immediate HTTP 200 so the form doesn't time out. - Code node — normalize: lowercase emails, trim whitespace, extract domains. Quick and dirty.
- Google Sheets (lookup) — search on the
Emailcolumn. Does this person already exist? - IF node — not found → Append Row. Found → Update Row (bump last activity date, append notes). No duplicates, no overwrites.
Step 3 — Triage and alert
Once the row is written, evaluate priority and act fast:
- Telegram / Slack ping — immediate markdown alert with one-click links to the customer's email and your sheet row. For high-volume support, pair with our Customer Support Triage automation to auto-tag inbound requests.
- Calendar routing — technical inquiries go straight to your booking link. General questions flag for email review.
- Enrichment — for B2B contacts, trigger deep profile scraping with our Real Estate Lead Enrichment engine to pull company size, social links, and verified phone numbers.
Gotchas that'll bite you
- Concurrent writes: two webhooks hitting at the same time can overwrite the same row. Always use n8n's Google Sheets node in
Append or Update(upsert) mode keyed on a unique ID. - Rate limits: Google Sheets caps at 300 requests/min per project. For high-volume bursts, use
SplitInBatcheswith small delays. - Data types: currency and date columns need correct formatting — n8n inserts strings by default, and your formulas will break silently if you don't cast them.
What's next
This gives you 90% of what a $100/mo CRM does, for free, with data you actually own. Once the base capture workflow is running, layer on automated follow-ups, invoice tracking, or contract generation — all on the same sheet.
Related reading: for a broader overview of n8n for solopreneurs, see N8N for Solopreneurs: Automate Without Engineers.
Related templates
- Customer Support Triage — auto-tag and route inbound support requests
- Real Estate Lead Enrichment — scrape, AI-score, and route hot leads