About Work Services FAQ Insights Let's Talk
Insights

We replaced a sales stack with one Worker, one database, and one intelligence layer.

A Shopify design and development agency I work with was running outbound on HubSpot, Instantly, and Apollo, and nobody trusted what any of them said. We cancelled the strategy underneath them, cut the target list down to companies we actually wanted, and built a small system that does all the homework but cannot send a single message.

The before-state: a wide net made of subscriptions

The stack looked responsible from a distance. HubSpot held the CRM. Instantly ran cold email that simply was not working. Apollo did double duty: email flows on one side, sourcing people from LinkedIn on the other. Three subscriptions, and every one of them overlapped the other two.

The overlap was the quiet killer. A prospect could live in three systems at once, each with its own idea of who they were and what we had sent them. When the picture lives in three places, it lives nowhere. Nobody trusted any single system's view, so every pipeline conversation started with reconciliation instead of decisions.

Underneath the tooling sat the real problem: the strategy was spray. Throw a huge wide net and hope. The tools were not broken. The approach was. And each subscription made it easier to keep not fixing it, because a tool you are paying for always feels like a plan.

Here is the confession that makes the point. An Apollo enrichment workflow, left running unattended, burned through more than 6,000 credits in a single cycle. Nobody was watching, because the whole promise of the automation was that nobody had to watch. That is what renting on autopilot looks like: motion you pay for, aimed at no one in particular, spending money while you sleep.

The turn: fewer, realer conversations

The fix was not a fourth tool. We broke the whole motion down and rebuilt it around a genuinely narrow ICP: the specific kind of company the agency is actually right for, and the specific human inside it worth talking to. Apollo stayed, demoted to the thing it is good at: a data source. Claude became the intelligence layer on top of it, verifying every prospect before anyone gets a message. Is this really the right company? Is this really the right person at that company? If either answer is no, no message exists.

Volume went down. Quality went up. The number we cared about stopped being sends and became real discussions with the right people. That reframe sounds small and changes everything, because sends are a cost and conversations are the product.

One lesson earned its own paragraph. On companies we checked by hand, enrichment-tool revenue data was wrong by as much as 40x. Not off by a rounding error. Wrong by a multiple that turns a filter into a random number generator. So revenue became something we verify on the open web before a prospect advances, and never a field we let a database decide. Treat enrichment data as a claim to check, not a fact to filter on.

The build: own the system, rent nothing but the rails

What we built is small on purpose. One edge application, a Cloudflare Worker, serves everything. One SQLite database is the single source of truth: every contact, every touch, every stage. There is no second system to reconcile against, which was half the disease we were curing.

Each weekday morning, an AI agent runs the day. It scans for replies, sources and verifies new prospects when a campaign runs short, and drafts every email and LinkedIn note that is due, in each operator's own voice. Voice is studied, not asserted. The system reads about 25 of the operator's real sent emails, takes pasted writing samples and standing rules in plain words, and diffs every human edit against the draft it wrote. Patterns that repeat become permanent voice rules.

The cadence engine lives in SQL, not in anyone's memory. The day's queue is a database view: cadence offsets, weekend roll-forward, and reply-halts are all computed there, across a six step sequence on two channels. When a reply comes in, a trigger flips the contact's stage, and that contact structurally cannot appear in the queue again. The sequence stops because the schema says it must, not because someone remembered to pause it.

The one rule

Nothing sends unless a human sends it.

That rule is enforced by architecture, not policy. The system cannot send anything. Emails are drafted into each person's own Gmail: the integration can compose drafts and read the mailbox, and no send capability exists anywhere in the tooling. LinkedIn notes are prepared for copy and paste. A person presses every key. Even the bookkeeping is honest about it: the activity ledger is append-only, and a drafted message is structurally distinct from a sent one, so the machine can never claim a send that did not happen.

The system also learns from every touch. Every edit a human makes before sending teaches the voice model. Every "wrong person, and here is why" teaches the sourcing gate, and repeated reasons become gate rules. A note on any contact, even something as small as "I know this founder," is read by the machine before it drafts a word. The humans are the sensors. The system just refuses to forget what they noticed.

Two smaller rules do outsized work. Prospects are deduped by domain, never by company name, so the same brand cannot slip in twice under two spellings. Sourcing collects work emails only, never phone numbers. And a watchdog checks every weekday whether each queue opened, finished, and covered its due work, then says nothing when the answer is yes. A message from it means a human is genuinely needed. Silence means healthy, which is a surprisingly hard discipline for software and worth insisting on.

Build vs. rent, honestly argued

The rented stack cost hundreds of dollars a month, and the honest accounting is worse than the invoice: it taught us nothing. Every correction we made inside those tools stayed inside those tools. The replacement runs on infrastructure that costs almost nothing, plus AI usage, and it compounds. Every human correction makes tomorrow's drafts better. Renting optimizes for starting fast. Building optimized for getting smarter.

Now the caveats, because this is not a universal recipe. It took real design work: the thinking about ICP, cadence, and failure modes was most of the job, and no subscription would have done that thinking for us. You need someone technical on the team, or an AI pair that effectively is. And SaaS is still the right answer when your process is a commodity. If your outbound motion is the same as everyone else's, rent the commodity version and spend your energy elsewhere. Ours was not. The process was the product, and you should not rent your product.

If you are considering the same move

  • Audit for overlap before cost. If two tools hold the same record, neither is your source of truth, and the reconciliation tax is bigger than either subscription.
  • Shrink the list before you touch architecture. A narrow, verified ICP did more for reply quality than any tooling decision. Verify the person, not just the company.
  • Trust no enrichment field you have not spot-checked. Revenue data was wrong by as much as 40x on companies we verified. Check what matters on the open web, and treat database fields as leads, not facts.
  • Put the cadence in the database and the send in a human's hands. A schema does not forget, and a message a person sends is a message that person owns.
  • Count what the stack teaches you, not just what it costs. If your corrections vanish into a vendor's black box, you are renting your own learning back.

Running outbound on a stack nobody trusts?

Tell us what you are paying for, what is overlapping, and what a real conversation is worth to you. We will give you an honest read: consolidate the rentals, or build the small system your process deserves. Sometimes the answer is "keep the SaaS," and we will tell you that too.

Let's Talk
Keep reading
Do you actually need Shopify? → When to hire fractional executives → Fractional CMO → All insights →