DEV Community

Jack Angelini
Jack Angelini

Posted on

The $47/Month Tech Stack Running Our Entire Outbound Sales Pipeline

I'm going to show you the exact architecture we use to run a full outbound sales operation — lead sourcing, enrichment, email sequences, CRM, analytics, and follow-up automation — for under $50/month.

No Salesforce. No HubSpot. No Clay. No Instantly.ai.

Just: n8n + PostgreSQL + Redis + SQLite + Resend + Cloudflare Tunnel, all running on a $10.59/month Hetzner VPS.

The Architecture

[Lead Sources]
    Apollo.io API → n8n Lead Pipeline
    Google Maps (via n8n workflow) → Raw leads

[Processing Layer]
    n8n (VPS) → validates, dedupes, enriches
    PostgreSQL → raw lead storage
    Redis → rate limiting, dedup, cooldowns

[Orchestration Layer]
    Claude claude-sonnet-4-6 (local, Max subscription)
    SQLite → CRM database (47 tables)
    TypeScript orchestrator → cron session manager

[Execution Layer]
    Resend API → email sending (verified domain)
    MillionVerifier → email validation before send
    Playwright + Chrome → platform automation

[Delivery Layer]
    Cloudflare Tunnel → ngrok replacement ($0)
    Hetzner VPS (CPX21) → always-on infrastructure
    Telegram Bot → real-time notifications
Enter fullscreen mode Exit fullscreen mode

Total monthly infrastructure cost: $10.59

n8n Lead Pipeline

The VPS runs n8n v2.9.3 with 9 active workflows. The Google Maps workflow runs every 6 hours, iterating through 157 keyword/location combinations — "plumber New Jersey", "restaurant automation", "HVAC contractor NYC" — and stores raw leads in PostgreSQL.

CREATE TABLE n8n_leads_raw (
    id SERIAL PRIMARY KEY,
    source VARCHAR(50),
    business_name TEXT,
    owner_name TEXT,
    email TEXT,
    phone TEXT,
    website TEXT,
    industry TEXT,
    city TEXT,
    state TEXT,
    imported_to_crm BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE n8n_search_tasks (
    id SERIAL PRIMARY KEY,
    keyword TEXT,
    location TEXT,
    industry TEXT,
    status VARCHAR(20) DEFAULT 'pending',
    results_count INTEGER DEFAULT 0
);
Enter fullscreen mode Exit fullscreen mode

Local orchestrator sessions pick up pending tasks, enrich with Apollo.io, validate emails with MillionVerifier, score leads 0-100, and import to the CRM database.

Lead Scoring

Every lead gets scored before any outreach. This prevents wasting email credits on junk leads.

function scoreLead(lead: Lead): number {
  let score = 0;

  if (lead.email && isBusinessDomain(lead.email)) score += 15;
  if (lead.website) score += 10;
  if (lead.phone) score += 5;
  if (lead.company_name) score += 5;
  if (TARGET_INDUSTRIES.includes(lead.industry)) score += 15;
  if (lead.employee_count > 5 && lead.employee_count < 200) score += 10;
  if (lead.google_rating >= 4.0 && lead.review_count >= 20) score += 10;
  if (lead.apollo_enriched) score += 10;

  return Math.min(score, 100);
}
Enter fullscreen mode Exit fullscreen mode

We ran this against our 549-lead database: 123 high (50+), 336 medium (30-49), 90 low. Email sequences only trigger for high-score leads.

Email Infrastructure

Getting cold email delivered in 2026 requires real infrastructure:

Domain setup:

send.getfluxdata.com → CNAME to Resend's servers
SPF:   v=spf1 include:amazonses.com ~all
DKIM:  [Resend generates this]
DMARC: v=DMARC1; p=quarantine; rua=mailto:dmarc@getfluxdata.com
Enter fullscreen mode Exit fullscreen mode

The subdomain is critical. If cold email gets marked as spam, your root domain's reputation stays clean for transactional emails.

Warmup schedule (we're on day 8):

  • Day 1-3: 5 emails/day
  • Day 4-7: 10 emails/day
  • Day 8-14: 20 emails/day
  • Day 15-30: 40 emails/day
  • 30+ days: 80-100 emails/day

Daily cap stored in the database and auto-incremented by the orchestrator.

Redis: The Glue Layer

Redis runs on the VPS handling four things:

  1. Email rate limiting — enforce daily caps across parallel processes
  2. Action cooldownslead:{id}:contacted key with 72-hour TTL
  3. Circuit breakers — if Resend API fails 3x, open for 6 hours
  4. Session dedup — multiple AI sessions can't process the same lead simultaneously
export async function checkEmailCooldown(leadId: number): Promise<boolean> {
  const key = `lead:${leadId}:email_sent`;
  const exists = await redis.exists(key);
  return exists === 0;
}

export async function setEmailCooldown(leadId: number): Promise<void> {
  const key = `lead:${leadId}:email_sent`;
  await redis.setex(key, 72 * 60 * 60, '1'); // 72 hour TTL
}
Enter fullscreen mode Exit fullscreen mode

The AI Orchestration Layer

This is the interesting part. A TypeScript orchestrator (pm2 daemon) fires 35 cron-scheduled sessions daily. Each session spawns a claude -p process with a specific prompt and subset of MCP tools.

9:30 AM  → outreach_executor  (sends today's emails)
12:00 PM → twitter_engage     (posts + engages on X)
12:45 PM → email_crm          (processes replies)
4:00 PM  → proposal_optimizer (drafts proposals for warm leads)
9:00 PM  → night_audit        (reviews day, updates strategy)
Enter fullscreen mode Exit fullscreen mode

Sessions share a SQLite database and pass context via session_handoffs table. When morning outreach finds a reply, it inserts a handoff for the afternoon session.

const SESSION_MCP_TIER: Record<string, MCPTier> = {
  'outreach_executor': 'light',    // needs Gmail only
  'twitter_engage': 'engagement',  // needs Playwright for browser
  'proposal_optimizer': 'light',   // needs Gmail + search
  'night_audit': 'light',          // needs Gmail + search
};
Enter fullscreen mode Exit fullscreen mode

Real Results

After 7 days running this system:

  • 549 leads in CRM across 6 industries
  • 110 cold emails sent (domain warmup — limited to 15/day)
  • 0 cold email replies (new domain, expected)
  • 1 client from a single Upwork proposal

The cold email machine works technically. The issue is new-domain reputation. Month 2, with proper warmup, this should produce results.

The bigger lesson: the automation stack is sound but I built the machine before validating the message. One Upwork proposal in 15 minutes outperformed 110 automated emails.

Running It Yourself

  1. Hetzner VPS (CPX21, $10.59/month)
  2. n8n self-hosted — Docker Compose on the VPS
  3. Resend — email sending, 100/day free tier
  4. Redis — Docker on VPS, standard Redis 7
  5. Cloudflare Tunnel — free, replaces ngrok for webhooks

Total infrastructure time to set up: 4-6 hours. The business logic takes longer, but the foundation is replicable.


Building revenue automation systems for small businesses at Flux Data Solutions. Free 30-min strategy call: calendly.com/jack-getfluxdata

Top comments (0)