HubSpot to Snowflake connector for contacts, deals and engagements
The HubSpot to Snowflake integration from Adapters loads contacts, companies, deals, and engagement events from HubSpot into Snowflake tables on an incremental schedule, so pipeline and attribution models run on a full history instead of a manual export. Field mapping is no-code.
The live demo needs no card, and Starter is $49 a month.
Field mapping auto-plugged · tap a port to rewire
Plug a source port into
Transform on this cable
JSON in
JSON out
5 sample records ready
What running HubSpot to Snowflake by hand costs you
- HubSpot list exports are capped and stale, and the built-in reports cannot join to product or billing data.
- The HubSpot API rate-limits and paginates, so hand-built pulls miss updated records and stall on large portals.
- Marketing attribution needs deal, contact, and engagement data in one warehouse, not three CSVs.
The field mapping, out of the box
All 6 of these HubSpot to Snowflake fields arrive mapped. Rewire any of them, or add your own, in the same visual data mapping tool you use for every adapter.
Input / HUBSPOT
Output / SNOWFLAKE
Transforms included
Incremental loads use the HubSpot hs_lastmodifieddate watermark so each run moves only changed records into Snowflake; deal amounts cast to NUMBER, millisecond timestamps become TIMESTAMP_NTZ in UTC, and deals, contacts, and companies land in their own tables so attribution and pipeline models read one clean, deduplicated dataset.
HubSpot to Snowflake in depth
Two things decide whether this pipeline is boring or painful: how you read out of HubSpot without tripping the rate limits, and how you land the types in Snowflake so nothing silently truncates. Numbers below are read from HubSpot and Snowflake documentation on 20 August 2026.
Read in batches, never one record at a time
HubSpot allows 100 requests per 10 seconds per private app on Free and Starter and 190 on Professional and Enterprise, against a daily account total of 250,000, 625,000 or 1,000,000 calls by tier. Those numbers are comfortable if you batch and hostile if you do not. Batch endpoints accept 100 records per request for read, create, update and archive, so a 200,000 contact backfill is 2,000 calls rather than 200,000. The mistake that turns a ten minute load into an overnight one is calling the CRM Search API once per record to resolve an ID: Search runs at 5 requests per second regardless of how much general headroom you have. Full breakdown in the HubSpot API rate limits guide.
The Search API result cap breaks naive backfills
Any single Search query returns at most 10,000 results, and asking for a page beyond that returns a 400 rather than more records. Portals with more than 10,000 contacts therefore cannot be backfilled with one filtered query, no matter how patient the pagination loop is. Slice by a date window on lastmodifieddate and walk the windows. That also makes the load restartable, because a window that fails is a window you can rerun without touching the rest.
Incremental loads hinge on lastmodifieddate, not createdate
Deals move stages and properties get edited long after the record was created, so a nightly pull filtered on creation date will miss exactly the changes your funnel and velocity models care about. Filter on last modified, keep a high-water mark per object, and overlap the window by a few minutes to absorb clock skew. Then upsert into Snowflake with MERGE on the HubSpot object ID rather than appending, or the same deal arrives once per night forever and your stage counts drift upward.
Snowflake NUMBER defaults will quietly eat your cents
Snowflake NUMBER defaults to (38,0), meaning zero decimal places. Land a deal amount into a default NUMBER column and 4,999.50 becomes 5,000 with no error and no warning. Declare money columns as NUMBER(18,2) explicitly. While you are defining the DDL, note that VARCHAR defaults to 16 MB and VARIANT caps at 128 MB, which matters because HubSpot notes fields and long text properties are larger than people expect.
Identifier folding runs the opposite way to Postgres
Snowflake folds unquoted identifiers to UPPERCASE, while Postgres and Redshift fold to lowercase. A HubSpot property named hs_lead_status becomes HS_LEAD_STATUS unless you quote it, and a dbt model written against the lowercase name then fails on a column that visibly exists in the information schema. Pick one convention for the whole warehouse, write it down, and do not mix quoted and unquoted names across the same set of tables.
File sizing decides load throughput
Snowflake recommends staged files of 100 to 250 MB compressed and explicitly does not recommend files of 100 GB or more. The default COPY timeout is 24 hours. Snowpipe lands data within about a minute of the notification, which is why it suits a steady trickle of CRM changes better than a large scheduled COPY does. For highly concurrent loads into a single table, Snowflake recommends Snowpipe over parallel COPY statements outright.
Timestamps need a declared timezone policy
HubSpot returns timestamps in UTC as epoch milliseconds on many properties. Landing them in TIMESTAMP_NTZ stores no zone at all, so any later comparison against a column that does carry a zone silently compares apples to oranges. Either standardize on TIMESTAMP_TZ across the CRM schema or keep everything NTZ and document that it is UTC. The failure mode is a deal that appears to close the day before it did, which nobody notices until a month-end number is off by one day of pipeline.
The native HubSpot Snowflake sync runs the other way
Worth knowing before you evaluate it as an alternative: HubSpot ships a Snowflake sync, but it loads from Snowflake into HubSpot, not the direction described here. It is now called Snowflake Direct Sync, is in beta, requires Data Hub Enterprise, runs on a schedule rather than in real time, and caps at 30,000,000 records per run, 10 GB per table or view and 200 columns. The route described here, HubSpot into Snowflake, is served by HubSpot's separate Snowflake Data Share on the same tier, by Snowflake's own Openflow connector, or by a pipeline like this one, and all of them are compared on what they actually land on HubSpot to Snowflake integration tools. The limit table is on HubSpot integration tools.
How it goes live
Moving HubSpot data into Snowflake on flat data integration pricing from $49 a month.
STEP 01
Pick the pair
Authorize a read scope on HubSpot and a write scope on Snowflake, nothing wider.
STEP 02
Confirm the mapping
Check that contact.vid lands in DIM_CONTACT.contact_id and deal.hs_lastmodifieddate in FCT_DEAL.loaded_at on a sample record.
STEP 03
Schedule the sync
Turn on the HUBSPOT → SNOWFLAKE schedule; failed records retry and every run is logged.
Still choosing how to run this route? Every option, from the vendors' own native paths to managed pipelines, is compared with its billing model and trade-offs on HubSpot to Snowflake integration tools.
HubSpot to Snowflake sync common questions
How do I connect HubSpot to Snowflake?
Authenticate HubSpot with a private app token, select the objects you need (contacts, companies, deals, engagements), map properties to Snowflake columns, and schedule an incremental run on the last modified date. Deals and their stage history are usually the reason the pipeline exists, so map the stage timestamps explicitly.
Which HubSpot objects should you load into Snowflake?
Deals first, then contacts and companies for the associations, then engagements if you report on activity. Association tables matter more than people expect: without the contact to company and deal to contact joins, a warehouse copy of HubSpot cannot answer any account-level question.
How do you handle HubSpot custom properties in Snowflake?
Map each custom property to an explicit, readable Snowflake column rather than dumping a properties blob. HubSpot property internal names are stable even when the label changes, so map on the internal name. Properties nobody reports on are worth leaving out; they cost load time and add columns your analysts have to ignore.
Does HubSpot have API rate limits?
Yes. HubSpot enforces per-account limits over a rolling ten second window plus a daily request cap, and the ceiling depends on your subscription tier. Incremental loads and batch read endpoints keep a normal sync well inside both, while repeated full extracts of every contact are what exhaust the daily cap.
How does the HubSpot to Snowflake sync work?
The HubSpot to Snowflake integration from Adapters loads contacts, companies, deals, and engagement events from HubSpot into Snowflake tables on an incremental schedule, so pipeline and attribution models run on a full history instead of a manual export. Field mapping is no-code.
How much does the HubSpot Snowflake integration cost?
The HubSpot to Snowflake pair is included on every plan: Starter $49, Growth $149, Scale $399 a month. You pay per plan, not per row or task, so a busier month costs the same.
Do I need to write code to connect HubSpot and Snowflake?
No. Fields are auto-mapped the moment you pick the pair, and you can rewire any mapping visually before the first sync. Incremental loads use the HubSpot hs_lastmodifieddate watermark so each run moves only changed records into Snowflake; deal amounts cast to NUMBER, millisecond timestamps become TIMESTAMP_NTZ in UTC, and deals, contacts, and companies land in their own tables so attribution and pipeline models read one clean, deduplicated dataset.
Related HubSpot and Snowflake connectors
Browse the full api connector library, or request a pair you do not see.
HubSpot and Snowflake, finally in agreement
Map the pair once and let it sync on schedule. Flat price from $49 a month, no per-task fees.
The live demo needs no card, and Starter is $49 a month.