Case studyGrove

Turning 10k MySQL orders / week into personalized HubSpot marketing

How we moved a corporate benefits company's live order data into HubSpot as first-class objects, and built personalized assets on top.

10korders / week
10minbetween syncs
2modules, 1000s of unique emails
The situation

The company runs subsidized workplace meals for office employees.

Everything worth knowing about a customer lives in the production database: what they order, from which location, how often, what's left in their wallet, how they rated the last meal.

Marketing lives in the CRM, and the CRM knew none of it.

Every campaign started with a manual export, and "personalization" meant a first name in a subject line.

Two things stood between the data and the campaigns:

Architecture diagram — Turning 10k MySQL orders / week into personalized HubSpot marketing
What we did

Step 1: Getting the data across, continuously

A production database can't be queried on a marketing tool's schedule, and a manual export is stale the next morning.

A Cloudflare Worker queries the production MySQL database directly through Hyperdrive, every ten minutes, across twelve tables.

Incremental state sits in KV, so each run moves only what changed since the last one — the sync stays cheap whether the week is quiet or busy, and the production database only ever answers for the delta.

Step 2: Making it usable once it arrives

Copying orders into contact properties would have made them visible but not composable. An email can't reason about "this recipient's orders" when the orders are text inside a field.

So the sync writes into HubSpot as custom objects: orders, locations, dishes, menus, reviews, wallet movements.

Once orders are first-class objects inside the CRM, an email can be assembled from a recipient's actual history. Two custom HubL modules do the work.

The first builds an order recap. It queries the recipient's order objects and groups everything from the same fifteen-minute window into a single message — order three dishes, get one confirmation instead of three.

The second renders a grid of four highlighted dishes priced for the recipient's own location. Same module, different prices depending on where you work.

What made it hard

A production database that cannot be strained

Ten thousand orders a week, every week, and the sync has to stay out of the way of the thing serving customers.

Personalization that renders in an email client

Whatever the module assembles has to survive being opened in software written a decade ago.

Twelve tables, one incremental state

Each run moves what changed, or the cost of the sync tracks the size of the database instead of the size of the change.

10k orders a week, turned into emails that feel personal.

The idea behind it — Turning 10k MySQL orders / week into personalized HubSpot marketing
The benefits gained

One template produces thousands of genuinely different emails, and the difference is real data rather than a merge field.

Campaigns stop beginning with an export. The data marketing needs is already in the platform they build in, no more than ten minutes old.

The two modules are where it started, not the limit. Order objects are queryable from any HubSpot template, so every asset built from here on — emails, pages, campaigns — can be assembled from a recipient's real history instead of a merge field.

The same objects feed reporting natively, so order behavior is queryable where the campaigns are built rather than in a separate tool.

And none of it required replacing the marketing platform. The CRM they already ran simply learned to do something it couldn't.

More of the same shape

Data problems shaped like this one?

If some of this reads like your situation, say which part. Datsugi replies within 2 business hours, guaranteed (CET).

Arrigo Lupori

Arrigo Lupori

Founder & Managing Director

Get your free systems design session

Required
Required