The scale path
Everything I have shipped runs on Postgres at pilot scale, and that was the right call. This is the architecture the same GTM motion needs once it serves many systems, large datasets, and multiple revenue teams — and the honest reason I have not built it yet.
The warehouse-centred loop
Click any stage.
Schedules and coordinates the pipelines: run A, then B, retry the failures, then run C. Nothing downstream fires on a stale or half-finished upstream job.
Salesforce and HubSpot objects, product events, ad platform spend and conversions. Each system stays the owner of its own records.
Managed connectors that land those sources in the warehouse on a schedule, handling schema drift instead of a pile of bespoke sync scripts nobody maintains.
One analytical store where the joins actually work: pipeline, spend, product usage and revenue in the same place, modelled rather than glued together in a spreadsheet.
Pushes the modelled segments and scores back out to where reps and campaigns live, so the warehouse is operational rather than a reporting cul-de-sac.
Scores, segments and signals land on the record a rep opens and the audience an ad platform targets. The loop closes: activity flows back in through the connectors.
In plain language
| Tool | Purpose | What that means |
|---|---|---|
| Fivetran | Moves data into the warehouse | Salesforce, HubSpot and product data land in Snowflake without hand-written syncs. |
| Snowflake | Stores and analyses centralised data | One place where pipeline, spend and revenue can actually be joined. |
| Airflow | Schedules and coordinates pipelines | Run A, then B, retry the failures, then run C. |
| Hightouch | Sends warehouse data back to business tools | Segments and scores go back to Salesforce, ads and email — where reps and campaigns live. |
Why not now
What one agency’s pilot needed
- Postgres as the store and the queue
- pg_cron for scheduling; job state in tables
- Compliance enforced by triggers, not by a pipeline
- One tenant, so the system of record could be the system itself
What forces the change
- Many source systems that each own their records
- Datasets too large to join inside the app database
- Several GTM teams needing the same definitions
- Attribution spanning CRM, product and ad spend
- Scheduled work with real dependencies and retries
Adopting this stack before those conditions exist is resume-driven engineering: four managed services, a warehouse bill, and an orchestration layer to schedule a job that a single cron row was already running correctly. The judgement being demonstrated here is knowing which side of that line a system is on — and today mine is on the left.
What carries over
The parts I did build are the parts that survive the migration: signals normalised and deduped before they are trusted, ownership and territory resolved deterministically, compliance as an invariant below the application, an append-only event log, and attribution that separates an influenced number from a booked one. Swap Postgres for Snowflake and those decisions still hold — which is the point of making them at the database boundary in the first place.