Deutsch

MAP and CRM Architecture Without the Duct Tape: A MOps Rebuild Playbook

You opened the field manager and counted 247 custom fields. Half are owned by people who left in 2023. The lead-to-contact sync has been broken since the last admin "fixed" it back in Q2. Two of the picklists have free-text values that shouldn't exist. Lifecycle stage gets written by both Marketo and Salesforce, so 14% of records flap between MQL and Lead every sync cycle.

Welcome to MOps.

If you just inherited this stack, or you've been staring at it for two years promising yourself you'd clean it up "after the next campaign," this is the playbook. It's the one I wish someone had handed me three jobs ago. The goal isn't a pretty diagram. The goal is one source of truth per data point, one owner per field, and an integration that doesn't wake you up at 3 a.m.

MAP to CRM Data Flow: The Actual Contract

Most teams treat the MAP-to-CRM integration like a black box. It isn't. It's a contract, and if nobody wrote the contract down, you have duct tape.

The contract has four parts. Get these wrong and nothing else matters.

Lead vs Contact: what carries over, what dies

When a Lead converts to a Contact in Salesforce (or whatever your CRM calls it), you lose data unless you've explicitly mapped it. Default behavior in most CRMs:

  • Standard Lead fields with matching Contact fields: carry over
  • Custom Lead fields without a matching Contact field: vanish
  • Activity history: usually preserved, sometimes orphaned
  • MAP-side scoring fields: depends entirely on whether your MAP writes to Lead-only or to both objects

The dirty secret is that 80% of MOps teams write demographic and behavioral scores to the Lead object only, and then act surprised when an SDR converts a Lead and the score disappears. If your MAP is Marketo or Pardot, you should be writing scoring fields to both Lead and Contact, OR converting Leads to Contacts on creation (the "all Contacts, no Leads" model HubSpot defaults to).

Pick one. Document it. Stop the bleeding.

Lifecycle Stage: MAP writes, CRM reads. Never both.

This is the single most important rule in the whole playbook. If both systems can write to lifecycle stage, you will have race conditions. You will have records that flap. You will have an SDR closing a deal on a Contact that the MAP just demoted back to MQL because of an unsubscribe webhook fired three minutes after the Closed-Won update.

Pick a writer. The MAP is usually correct because it sees the behavioral signals first. The CRM reads lifecycle stage; it doesn't fight for it. If sales needs to override (e.g., manually mark someone as SAL), build a separate field (sales_stage_override__c) and let an automation in the MAP respect that override. Don't let two systems argue about the same column.

Sync timing: real-time isn't always better

The default impulse is "make it real-time." This is wrong about half the time.

Real-time syncs make sense for:

  • Form fills (lead has to land in CRM before the SDR queue refreshes)
  • Lifecycle stage transitions that drive routing
  • Closed-Won status (revenue attribution can't wait)

Batch syncs (15 min, hourly, nightly) make sense for:

  • Bulk score recalculations
  • List membership flips
  • Activity history backfills
  • Anything that fires more than 1,000 record updates per hour

Why does this matter? Because "every 10 minutes" is the worst possible setting for scoring sync. It's slow enough that SDRs can't trust it, fast enough to crash your API limits during a campaign send, and just frequent enough to make race conditions invisible until your monthly reconciliation query catches them.

If you only remember one thing: real-time for handoff, batch for hygiene.

The MQL handoff: one field, one owner, one definition

Stop. Open your Salesforce. Search for any field with "MQL" in the name. I will bet you a coffee you have at least three:

  • MQL_Date__c (set by Marketo)
  • Marketing_Qualified__c (set by a workflow rule from 2022)
  • Lifecycle_Stage = "MQL" (set by HubSpot)

Pick one. Delete the other two. The MQL handoff is one field, one owner (MOps), one definition (written down in a Confluence doc that has a date on it). If sales doesn't trust the field, that's a definition problem, not a field problem. Adding a fourth field never fixes a definition problem.

The Field Bloat Problem

Field bloat is how MAP+CRM stacks die. Not a single dramatic failure. A slow accumulation of fields nobody owns, used by one report nobody opens, set by one workflow nobody documented.

How you got to 247 custom fields

Every field has a creation story. Roughly:

  • 30% are real, used, owned. These are fine.
  • 25% were created for a campaign in 2022, are still being written to, and aren't read by anything.
  • 20% were created by a sales leader who left, mapped to a dashboard that was deprecated, but the field is still on every page layout.
  • 15% are duplicates with slightly different names (Industry__c, industry_v2__c, Account_Industry__c).
  • 10% are integration "ghost fields" created automatically by an integration that was disconnected 18 months ago, but the field stayed.

Nobody deletes fields because deletions feel risky. That's exactly why you need a process.

The 90-day field audit framework

Run this every quarter. Block four hours on a Friday. It's the highest-leverage cleanup work in MOps.

Step 1: Pull a usage report. For every custom field, count:

  • How many records have a non-null value (last 90 days of writes)
  • How many reports reference the field
  • How many workflows/automations reference the field
  • How many integrations write to it

If all four are zero, the field is dead. Tag it.

Step 2: Find the owner. Every field needs a name attached. Pull the "Created By" and check if that person is still at the company. If not, walk the field through the team. Does anyone claim it? If nobody claims it within seven days, it's an orphan.

Step 3: Build the kill list. Three buckets:

  • Hard delete: Zero usage AND no owner. Delete next sprint.
  • Deprecate: Has some usage but the owner agrees it's redundant. Mark as deprecated in description, hide from layouts, schedule deletion in 90 days.
  • Document: Active, owned, no further action. Write the description if it's blank.

Step 4: Make it stick. Add a field-creation policy: every new custom field requires a description, an owner, and a "review by" date. No description = no field. Get the CRM admin to enforce it. If they won't, get yourself admin rights for that one workflow.

You won't get to 50 fields. You probably can get to 100. That's the goal.

Naming Conventions That Survive Turnover

If the next admin to inherit your stack can't guess what a field does in five seconds, the name is wrong. Rename it.

The naming convention I use, which has survived three job changes:

  • mkt_*: written by the MAP. Marketing owns.
  • sfdc_*: native Salesforce field or sales-owned custom field.
  • ext_*: written by an external integration (Clearbit, ZoomInfo, 6sense, etc.). Read-only for everyone else.
  • ops_*: operational/calculated fields (region, segment, account tier).
  • No prefix: standard fields you didn't create.

Picklist discipline matters more than you think. Free-text country fields where you have "USA", "U.S.A.", "United States", "US", and "America" all in the same dataset will destroy your reporting. Lock down picklists. If sales argues, show them the segment report where USA-revenue is split across five buckets.

The five-second rule: if a new admin opens the field manager and can't guess what cust_dt_2_v3__c does in five seconds, that field is named wrong. Rename it. Yes, it'll break two reports. Fix the reports. Future-you will send a thank-you note.

MAP Selection: Marketo vs HubSpot vs Pardot vs Rework

Half of MAP integration pain comes from choosing the wrong MAP for the company. Here's how I think about it.

Marketo (now Adobe)

Pick Marketo if:

  • You have a dedicated MAP admin (not a "marketing manager who also does Marketo")
  • Your campaign programs are genuinely complex (multi-touch nurtures, account-based plays, dozens of segments)
  • You're enterprise (1,000+ employees) or running enterprise-style demand gen
  • You can stomach the price and the learning curve

Don't pick Marketo if you're a 50-person startup. You will use 8% of the platform, pay 100% of the price, and the integration to Salesforce will eat one FTE.

HubSpot

Pick HubSpot if:

  • Marketing leads the GTM motion
  • Your team lives in the UI (not in API calls and SQL)
  • You're mid-market (50 to 500 employees)
  • You want CRM and MAP from the same vendor and you're okay with HubSpot's CRM (which is fine for SMB, gets thin at enterprise)

HubSpot's strength is that the CRM and MAP are one system, so the duct tape problem partially disappears. The weakness is that if you outgrow HubSpot CRM and bolt on Salesforce, you've recreated the integration problem with extra steps.

Pardot (Marketing Cloud Account Engagement)

Pick Pardot if:

  • You're a Salesforce-native shop and the Salesforce admin owns marketing automation too
  • You don't need fancy program logic
  • You want lifecycle stage and scoring tightly coupled to SFDC objects

Pardot's strength is the SFDC integration is native (it lives inside SFDC). The weakness is the MAP itself is dated; if your team needs modern UX, they'll fight you.

Rework

Pick Rework if:

  • You're a small or mid-size B2B (20 to 500 employees)
  • Sales and marketing share one pipeline and you don't want two tools fighting over it
  • You don't have a dedicated MAP admin and you don't want one
  • You'd rather have one CRM with built-in lead capture, scoring, and routing than maintain a separate MAP+CRM integration

Rework's pitch on this specific problem: there is no MAP-to-CRM integration to maintain because there's no separate MAP. Lead capture, scoring, lifecycle stage, and pipeline live in one system. You give up some of Marketo's enterprise program complexity. In exchange you give up the duct tape.

For a 30-person B2B SaaS team with one MOps generalist, the Marketo+SFDC stack costs maybe $80K/year in licenses plus a half-FTE to maintain. The same workflow on Rework runs $12/user/mo on the CRM tier (about $10K/year for a team of 30) and the MAP integration goes from "maintain" to "doesn't exist."

That's not the right answer for everyone. It's the right answer for more teams than admit it.

The Rebuild-From-Scratch Decision

At some point, patching costs more than rebuilding. The hard part is knowing when.

The 40% rule: if more than 40% of your MOps team's time is spent on integration fixes, ghost fields, and reconciliation queries, and has been for two consecutive quarters, you are past the patch point. Rebuild.

Other signals:

  • Three or more "trusted" lifecycle fields exist and people argue about which is correct
  • Sync errors run more than 0.5% of records per day
  • A new MOps hire takes more than 90 days to ship their first non-trivial change
  • The audit trail on critical fields is "ask Sandra, she remembers"
  • The MAP-CRM integration has more than two custom middleware components (Workato recipes, Zapier zaps, custom Apex)

Rebuilds are not a "blow it all up" operation. They're a parallel-build. You stand up a new instance (or a clean schema in the existing instance), migrate one campaign at a time, validate, then deprecate the old. It takes 90 to 180 days. It is faster than the next 18 months of patches.

Tell your boss it's an investment, not a project. Investments compound. Patches don't.

Integration Health Monitoring

A healthy MAP-CRM integration has telemetry. If you can't see it, you can't fix it.

The three alerts every MOps lead should have running:

1. Sync error rate alert. Fires if sync errors exceed 0.5% of attempted records in a 1-hour window. This catches API limit issues, validation rule conflicts, and middleware failures before sales notices.

2. Lifecycle flap alert. Fires if any record's lifecycle stage changes more than three times in 24 hours. This catches the race conditions where two systems are fighting for the same field.

3. Form-to-CRM latency alert. Fires if any form submission takes more than 90 seconds to land in the CRM. SDRs trust the system based on this metric more than any other.

A daily reconciliation query should also run every morning at 6 a.m. and email you (and only you, until you trust it). The query I run on Salesforce + Marketo:

-- Records in MAP with no CRM counterpart, last 7 days
SELECT email, lifecycle_stage, last_modified
FROM map_leads
WHERE crm_id IS NULL
  AND created > DATEADD(day, -7, CURRENT_DATE)
  AND lifecycle_stage IN ('MQL', 'SAL');

Anything in that result set is a lead that should have made it to a sales rep but didn't. If the query returns more than 5 rows in a day, you have an integration problem you don't know about yet.

The dashboard variant: a weekly view of sync error count by error type, MQL handoff latency P50/P95, and total records under each lifecycle stage. Make it the homepage of your MOps Confluence space. When a VP asks "is the system healthy?" you point at the dashboard and say "yes" or "no" with data.

One Source of Truth, One MQL Definition, One Owner

If this playbook had a single takeaway, it would be this: every data point in your MAP+CRM stack has exactly one source of truth, one owner, and one definition. Everything else is duct tape.

When a sales rep argues that an MQL "isn't really an MQL," that's not a field problem. That's a definition problem. Fix the definition. Document it. Get sales leadership to sign off in writing. Then the field becomes irrelevant, because everyone agrees on what it means.

When two systems write to the same field, pick one. The other one becomes read-only or gets a separate override field. Race conditions don't get better with more workflows.

When a custom field has no owner, kill it. If someone notices it's missing in three months, you'll find out who actually used it. Most of the time, nobody notices, and you've made the system simpler for the next admin who inherits it.

The duct tape compounds. Every shortcut you take this quarter is a problem your successor inherits next year. Sometimes the right answer is to rebuild. Sometimes it's to switch to a stack that doesn't require the integration in the first place. Almost always, it's to delete more than you add.

That's the job.

Learn More