Where we started
Our client operates a vertical SaaS platform serving a specific professional services category. At engagement start the website was a marketing-pages-only WordPress instance with 28 indexed pages, an average page-load time over 4 seconds, no programmatic SEO architecture, and no internal-linking discipline. Organic traffic was approximately 12,000 monthly visits, almost entirely brand queries. The product had product-market fit but the marketing motion was overwhelmingly outbound — cold sales calls and conference presence — and the unit economics of inbound sourced revenue were strong enough that the client wanted to flip the ratio.
The plan
We agreed on a nine-month programme, three phases:
- Foundations (months one to three): site speed, technical SEO, schema, internal-linking architecture, the keyword universe definition, the editorial process, and a small Google Ads programme on bottom-of-funnel commercial queries.
- Content build (months four to six): publishing pace of three to five articles per week, anchored around four pillar topics. Tools-page programmatic templates for category-comparison queries.
- Scale (months seven to nine): broaden Google Ads to mid-funnel, layer in retargeting, build out the editorial calendar to a sustainable steady-state of two articles per week, monitor and prune underperforming content.
Foundations
The technical work in phase one was unglamorous and disproportionately impactful. Site speed dropped from 4.1 second LCP to 1.3 seconds via a hosting migration and image-handling overhaul. Schema markup applied across Organization, Article, FAQPage, SoftwareApplication and Review entities. Internal linking restructured around four pillar topics with a deliberate hub-and-spoke pattern. The keyword universe was defined at 1,800 commercial-and-informational queries, segmented into the four pillar topics plus a navigation-and-brand cluster. Tracking was rebuilt from the GTM container up: GA4, server-side tagging, Google Ads conversion actions tied to qualified-lead events fired from the CRM via API.
Content
The editorial process is the critical success factor on a programme like this. We installed a single-author-per-article model with a senior in-house subject expert as the editor for every piece. Drafts went through structured AI-assisted production (research and outlining via tooling, drafting by senior writers, final editing by the in-house expert) but were never published as AI-generated text. Cadence: three articles per week in months four and five, scaling to five per week in month six. Each article was published into the relevant pillar cluster with internal links, distributable as a LinkedIn post, and tagged for follow-on work (newsletter mention, video derivative, podcast topic).
Paid programme
The Google Ads programme started small — a single Search campaign with five ad groups on commercial-intent queries, £3,000 monthly budget — and scaled to a four-campaign portfolio (Brand, Commercial Intent, Comparison, Mid-funnel Informational) at £28,000 monthly by month seven. Performance Max was tested in month five and removed in month six; the asset-group structure that suits an e-commerce catalogue wasn’t a fit for a single-product B2B SaaS, and the lack of negative-keyword control was costing us mid-funnel quality.
The results
By month nine: 980,000 monthly organic visits, growing roughly 12% month-on-month. Inbound qualified pipeline up 184% versus month-zero baseline (measured as net-new opportunity ARR). Share of voice on the defined keyword universe at 39%, up from 4% at month zero. Customer acquisition cost on inbound-sourced new business approximately one-third of the outbound CAC.
What worked, what didn’t
What worked: the discipline of one editor across all content, the technical-foundations work in phase one, and the decision to run the Google Ads programme small and tight rather than aggressive and broad. The biggest single mistake was the four weeks of Performance Max experimentation that we could have skipped — the structural mismatch was visible in week one and we should have called it then rather than waiting for the data to confirm what we already suspected.