Skip to content
ISSUE / 15 8 MIN READ

The boring layer is the moat

Part 2 of 4: Building a small business's data foundation on Google Cloud and BigQuery - and why the least glamorous work mattered most

Field notes title card, part two of four, reading The boring layer is the moat with the word moat in acid green italic, subtitled: why the least glamorous work mattered most.

This is the second post in a four-part series about the six months I spent building the AI backbone of String Ting, the premium accessories brand my wife founded. Part 1 covered why I made the move. This one is about the layer underneath everything: the data foundation. If you only read one post in the series, read this one - because everything the AI later did well, it did because of decisions made here.



You cannot bolt intelligence onto fragmentation

When people imagine “adding AI to a business”, they imagine the top of the stack: the assistant, the chat interface, the agent doing things. That’s the part you can demo. It’s also maybe twenty per cent of the work.

The other eighty per cent is this: a small business is not one system, it’s a federation of systems that have never been introduced to each other. At String Ting the map looked like this:

  • Shopify Plus - the DTC storefront. Orders, customers, products, inventory.
  • Zedonk - the fashion-industry ERP. Wholesale orders, buyers, invoicing, unit costs, the product master.
  • Klaviyo - email and SMS. Campaigns, flows, profiles, engagement events.
  • GA4 - traffic, funnels, attribution.
  • Meta Ads - the paid performance engine. Spend, impressions, clicks, and Meta’s own version of what it drove.
  • Xero - the financial record.

Six systems, six vendors, six data models, six definitions of “product” and “customer” and “revenue”. Any question worth asking crossed at least two of them. Which wholesale buyers also shop DTC? Is that bestseller actually profitable once you load in unit cost? Did that campaign drive purchases or just clicks?

Before January, answering those questions meant a founder with five browser tabs and an evening she wasn’t getting back. The first decision, therefore, wasn’t an AI decision at all. It was: everything flows into one warehouse, and the warehouse is the truth.


Why Google Cloud and BigQuery

For a business this size the honest requirements were: near-zero maintenance, near-zero fixed cost, scales down as gracefully as it scales up, and speaks SQL so that everything downstream - dashboards, assistants, ad-hoc analysis - has one interface to learn.

BigQuery fits that shape almost perfectly. Serverless, so there is no cluster for a two-person company to babysit. Pay-per-query, so a quiet month costs pennies. And crucially, it’s boring in the best sense - the failure modes are well understood, and it will still be there in ten years.

The architecture that emerged:

  • A single dataset as the spine - orders, line items, products, variants, collections - mirroring Shopify but owned by us.
  • Klaviyo tables alongside - events, campaigns, flows, profiles - synced daily.
  • GA4 exports - daily traffic, a seven-step conversion funnel, page performance, purchase attribution.
  • Meta Ads via the API - spend and performance pulled fresh, alongside a GA4-based view of the same traffic.
  • Zedonk queried live at the API rather than synced - wholesale data changes at fashion-season pace, not e-commerce pace, and duplicating it created more reconciliation risk than it saved in latency.

That last point generalises: not everything belongs in the warehouse. The discipline is deciding what the warehouse must own (anything you aggregate, trend, or join across systems) versus what you fetch fresh (anything operational, low-volume, and authoritative at source).

Paid performance deserves its own note, because it’s where SMBs get misled most expensively. Meta will tell you, with great confidence, what your ad spend drove. GA4 will tell you a different story about the same traffic. Shopify’s order records tell a third. None of them is lying; they’re answering subtly different questions with different attribution windows and different ideas of identity. The design decision that mattered was refusing to crown any of them: the warehouse holds all three views side by side - Meta’s claimed conversions, GA4’s attributed sessions, and the ground truth of orders that actually happened - so that “did that campaign work?” gets answered by triangulation rather than by whichever dashboard shouts loudest. For a business where paid social is a meaningful lever, making the disagreement between sources visible was worth more than any single source’s precision.


Real-time is a feature; reconciliation is the product

The seductive choice for order data is webhooks: Shopify pushes every order into your pipeline within seconds, your numbers are live, everyone is happy.

The problem is that webhooks are a stream, and streams drop things. Deliveries fail. Orders get edited, refunded, cancelled after the fact. A pipeline built on webhooks alone drifts from the truth slowly and silently - which, for a system whose entire value proposition is “you can trust this number”, is fatal.

So the pattern I landed on is the one I’d recommend to anyone building this at any scale:

Webhooks for freshness, nightly batch for truth. Orders land in BigQuery in real time via webhook, and every night a reconciliation job re-walks the Shopify API and corrects the record - filling gaps, catching edits, truing up refunds. The stream makes the system feel alive; the batch makes it honest.

This cost perhaps a week of work and it is the single highest-leverage week of the entire project. Every downstream consumer - every report, every AI answer - inherits its trustworthiness from this one job.


The product-matching problem, or: where the real work lives

Here is the least glamorous thing I have ever spent serious engineering effort on, and the thing I’d defend hardest.

The same physical product - one wristlet phone strap - existed as a Shopify product with variants and SKUs, and separately as a Zedonk style with its own codes, barcodes, unit costs and RRPs. Nobody had ever needed to join them formally, because the join lived in the founders’ heads.

But every commercially interesting question lives across that join. Margin by product requires Shopify revenue matched to Zedonk cost. Reorder decisions require DTC sales velocity matched to the wholesale product master. Without the join, the warehouse is two half-businesses side by side.

The matcher I built works in two passes: exact matches first, on barcode - the EAN-13 is the one identifier both systems secretly share - then a fuzzier second pass normalising SKU and style-code conventions, with product titles and colours as tie-breakers. Everything lands in one of three buckets: matched, ambiguous, or unmatched, with the ambiguous and unmatched cases surfaced for a human decision rather than silently guessed.

Three lessons from that trench:

1. Identity resolution is the hidden kernel of every “AI for business” product. Whatever the pitch deck says, somewhere underneath is code trying to work out whether two records are the same real-world thing. Do it well and everything above it feels magical. Do it badly and no model can save you.

2. Design for the residue. Some fraction will never auto-match - discontinued lines, one-off collaborations, data-entry drift from years ago. The system has to make the unmatched set visible and workable, not pretend to completeness. Honest partial coverage beats confident wrongness.

3. The business taxonomy is infrastructure too. Alongside the matcher, I encoded the operational category scheme - the brand’s own language for its range - so every system downstream groups products the way the founders actually think. That vocabulary, written down for the first time, turned out to be one of the most-used artefacts of the whole build.


When the data lies: a war story

In March, a consent-management change quietly blocked one of the analytics pixels. For four days, part of the checkout funnel simply didn’t fire. No errors, no alerts from the vendor - just a hole in the data that could never be backfilled, because the events were never collected.

We caught it within days because the reconciliation mindset was already in place: server-side purchase records disagreed with browser-side ones, and the discrepancy itself was being watched. The fix took an afternoon. The lesson took root permanently:


Every data pipeline is lying to you somewhere. The design question is whether your system knows where.


The mature response isn’t perfect data - that doesn’t exist. It’s documented imperfection: a known-limitations register that travels with the data, so every downstream consumer (human or AI) knows that this metric is trustworthy, that one has a gap in March, and those two can’t be compared because they’re deduplicated differently. When we later gave the AI layer that register, it started caveating its own answers correctly. That single behaviour did more for founder trust than any capability we shipped.


The unexpected dividend: software on demand

Here’s the part I didn’t design for, and which ended up reshaping how I think about what a data foundation is for.

I assumed the warehouse would feed two consumers: dashboards and, later, the AI assistant (Part 3). What actually happened, once the foundation existed, was a third category I hadn’t planned: standalone applications, conjured as needed, living inside the AI workspace itself.

Working in Claude’s Cowork environment, the pattern went like this. A recurring operational need would surface - reviewing the monthly missing-invoice list from the accountant, checking storefront health before a campaign, watching the week’s trading against last year. Instead of buying a tool or building a “proper” app, I’d have one generated: a self-contained interactive artefact - a live page with its charts, filters and tables - wired directly to the warehouse and the business’s other systems, refreshing with current data every time it was opened. A status page here, a review queue there, a trading dashboard for Monday mornings.

Each one would have been absurd to build conventionally. No SMB commissions a bespoke invoice-review application. But when the data layer is clean and the interfaces are standard, a purpose-built tool costs a conversation - so the economics of internal software invert. You stop asking “is this need big enough to justify a tool?” and start asking “is this need recurring enough to justify keeping the tool?” Some artefacts earned a permanent place in the weekly rhythm. Others did their job for a fortnight and were thrown away without ceremony - and that disposability is the point. Software stopped being a procurement decision and became a byproduct of having asked a good question.

None of that is possible without this layer. The artefacts are thin; every one of them is only as good as the warehouse underneath and the reconciliation jobs keeping it honest. Which is the quiet thesis of this whole post: the foundation doesn’t just answer questions - it changes what it costs to build the things that answer questions.


What this layer cost, and what it replaced

Without numbers, the shape is this: a few weeks of focused build, a running cost closer to a coffee subscription than a SaaS line-item, and near-zero ongoing maintenance by design. Against that, it replaced the standing tax every SMB pays and stops seeing: hours of founder time per week spent swivel-chairing between systems, and decisions delayed or skipped because assembling the picture was too expensive.

That’s the part I want SaaS people to sit with. The technology to give a two-person business an enterprise-grade data foundation now exists, is cheap, and is mostly assembly. What’s scarce isn’t tooling. It’s someone who can hold the business logic and the engineering in one head long enough to encode the former into the latter.

Next post: what I built on top - the AI layer. Claude, the Model Context Protocol, and Bead Bot: the operating assistant that turned this warehouse into something the founders talk to every day. That’s where the leverage gets visible.

START

Forty-five minutes. Bring the constraint.

Tell us where the model is bending. We'll say what we'd do, and whether we're the right people to do it.

WHAT DO YOU NEED?
LONDON — GMT TAKING ENGAGEMENTS