Skip to main content

Subscriber Key strategy

SubscriberKey is the column every other system in Marketing Cloud joins on — the identifier that defines who 'the same person' is across DEs, sends, Journeys, and CRM. The choice of what goes into it is one of the bootstrap decisions you live with for the tenant's lifetime. The decision tree, the candidate values, the patterns to prefer, the patterns to refuse, and the migration cost of getting it wrong.

Decision framework·Last updated 2026-05-19·Drafted by Lira · Edited by German Medina

SubscriberKey is the column every Marketing Cloud system joins on. SQL Activities join master DEs to log DEs by SubscriberKey. AMPscript reads _subscriberKey and uses it as the lookup parameter against segment DEs. SSJS scripts pass it across Cloud-writes to Salesforce. Journeys route recipients between waits and decision splits keyed by it. The All Subscribers list keys recipients by it. It is the single identifier that defines who "the same person" is across the entire tenant, and the choice of what goes into it is one of the bootstrap decisions you live with for the tenant's lifetime.

This page is the decision framework for that choice: the candidate values, the criteria a good SubscriberKey value satisfies, and the migration cost of getting it wrong. The shape mirrors BU architecture — decision tree at the top, patterns to prefer and refuse below, checklist at the bottom.

The decision tree

Start here ─→ What identifier already exists for "the same person"
              across the systems Marketing Cloud will integrate with?
              ├── CRM customer ID    → strong candidate
              ├── Internal user ID   → strong candidate
              ├── External hash of   → if no other ID exists, but with
              │   email or phone        explicit caveats (see below)
              └── Email address      → AVOID — fails the immutability
                                        test; see gotcha #1
              
For each candidate, verify:
  ├── Is it stable across the recipient's lifetime?
  ├── Is it unique within the audience (no collisions)?
  ├── Is it opaque (doesn't reveal the recipient's identity in
  │   tracking links or DE row IDs)?
  ├── Is it the same value the downstream systems (Salesforce,
  │   data warehouse, support tools) use to identify the recipient?
  └── Does it survive a CRM migration or re-platforming?

If all 5 are yes ─→ Use this value as SubscriberKey.
If any are no    ─→ Either compose a synthetic key, or pick a
                    different candidate.

The hardest of the five criteria is survives a re-platforming. CRM customer IDs are stable as long as you stay on the same CRM; when you migrate (Salesforce → Snowflake → HubSpot), the IDs change. The defense is to map the SubscriberKey to a value you control independently of any one downstream system.

Candidate values, ranked

| Candidate | Stability | Uniqueness | Opacity | Recommendation | |---|---|---|---|---| | Internal user ID from your application database | ✓ stable across re-platforming if you keep your own DB | ✓ unique by your DB constraint | ✓ opaque (just an integer or UUID) | Default choice when you have an application of your own | | CRM customer ID (Salesforce ContactId, HubSpot vid, etc.) | ✗ changes if you migrate CRMs | ✓ unique within the CRM | ✓ opaque | Acceptable if you're committed to the CRM long-term; risky for organizations that have migrated before | | UUID generated at first signup | ✓ stable forever once issued | ✓ globally unique | ✓ opaque | Strong choice when no existing system has the right ID; requires the upstream system to mint and persist the UUID | | Hash of email (SHA256(email_lowercased_trimmed)) | ✗ changes when email changes | ✓ unique per email | ✓ opaque on the wire | Avoid unless email is genuinely immutable for your audience; same failure mode as raw email but harder to debug | | Email address (raw) | ✗ changes whenever recipient updates email | ✓ unique per email | ✗ leaks PII in tracking links | Refuse — fails immutability and opacity; see Config gotcha #1 | | Phone number | ✗ changes; varies by region for normalization | ✓ unique per number | ✗ leaks PII | Refuse for the same reasons as email; harder to normalize across regions | | Sequential integer (1, 2, 3, ...) | ✓ stable | ✗ collisions when merging audiences from multiple systems | ✗ predictable (allows enumeration attacks) | Refuse for any tenant beyond a single-source audience |

The recommendation: a UUID minted at signup and stored in your application database is the safest default. It survives re-platforming (you own the value), it's opaque, it's stable, and it's unique. CRM IDs work but couple your SubscriberKey lifetime to your CRM choice — which can shift over years.

What a good SubscriberKey value satisfies

The five criteria, expanded:

Stability across the recipient's lifetime

The same person should have the same SubscriberKey across years, across CRM migrations, across email changes, across phone changes. The SubscriberKey is not a sortable / mutable attribute of the recipient — it is the recipient's identity. Anything that can change about the recipient (email, phone, address, even name in some cultures) is unsuitable as the identity itself.

Uniqueness within the audience

Two distinct people must never have the same SubscriberKey. The All Subscribers list merges rows by SubscriberKey; a collision means person A and person B become one row in MC, with downstream consequences (one of them gets the other's emails; both stop getting their own; suppression flags merge incorrectly).

Opacity in the wire

SubscriberKey appears in URL parameters (preference centers, unsubscribe links, tracking redirects) and in DE row identifiers. If the SubscriberKey is the recipient's email address, every tracking URL leaks the email — to ISPs, to anyone watching the network, to anyone with access to MC's log DEs. Opacity means the SubscriberKey is a value with no inherent meaning outside the tenant.

Alignment with downstream systems

When MC sends a Cloud-write to update a Salesforce Contact, the SubscriberKey has to map to a value Salesforce can use to find the Contact. When MC reads a webhook from the data warehouse, the warehouse has to be able to send the SubscriberKey for the recipient. Alignment doesn't mean the same value — it means a reliable mapping exists between SubscriberKey and the downstream identifier.

Survives re-platforming

The hardest criterion. A SubscriberKey that depends on a specific downstream system (Salesforce ContactId) becomes a liability when that system is replaced. The defense is to mint the SubscriberKey in a system you own — your application database, a service-owned UUID generator, an enterprise-wide identity service. The SubscriberKey then survives the downstream system being replaced.

Patterns to prefer

Mint the SubscriberKey upstream of MC, in a system you control

The upstream system is your application database (the row representing the user in your own product), a customer-identity service (Auth0, Okta, internal identity platform), or an enterprise-wide CDP that survives downstream tool migrations. The SubscriberKey value is created once in that upstream system and passed unchanged into MC, into the CRM, into the data warehouse, into every other downstream consumer.

Make the SubscriberKey opaque

A UUID, a hash, an internal integer ID — anything that doesn't reveal the recipient's email, phone, or other PII. The opacity matters because the SubscriberKey appears in URLs (preference centers, unsubscribe links, CloudPage parameters). A URL that contains the recipient's email is the recipient's email leaking into ISP logs, ad-tech tracking pixels, and corporate firewall logs.

Pin the SubscriberKey column type at NVARCHAR(254)

Per the DE architecture page — #3. Don't narrow the type hoping for performance gains; the gains don't materialize and the future hand-off failure is severe.

Document the SubscriberKey source of truth in the runbook

The team runbook should answer:

  • Which system mints the SubscriberKey value
  • What format the value has (UUID, integer, hash)
  • How a new recipient gets a SubscriberKey at signup
  • How downstream systems (CRM, warehouse) receive the SubscriberKey for sync
  • What happens when a SubscriberKey needs to be revoked (PII deletion request)

Without runbook documentation, the second person to touch the tenant doesn't know whether the SubscriberKey is safe to change, whether it's PII, or how to provision a new one.

Use the same SubscriberKey in test sends as in production

Test sends to a staging Business Unit (see SAP setup — Step 6) should use a real SubscriberKey from a real test recipient. Synthetic test SubscriberKeys (test-1, test-2) succeed in MC and fail at downstream sync because the receiving systems don't have rows for those values. The test send doesn't reproduce the production behavior.

Run a synthetic-SubscriberKey audit on every audience-build SQL Activity

-- Audit pattern — run weekly to catch synthetic / test SubscriberKeys
-- that leaked into production audiences
SELECT
  SubscriberKey,
  COUNT(*) AS RowsAcrossAllDEs
FROM (
  SELECT SubscriberKey FROM de_send_audience_a
  UNION ALL
  SELECT SubscriberKey FROM de_send_audience_b
  UNION ALL
  SELECT SubscriberKey FROM master_subscribers
) all_keys
WHERE SubscriberKey LIKE 'test-%'
   OR SubscriberKey LIKE '%@example.com'
   OR SubscriberKey LIKE 'synthetic-%'
   OR LEN(SubscriberKey) < 5
GROUP BY SubscriberKey;

Any rows returned are bugs: a synthetic SubscriberKey reaching a production DE. The pattern is hard to find without the audit because synthetic values look legitimate at a glance.

Patterns to refuse

Email Address as SubscriberKey

Fails immutability (email changes), fails opacity (leaks PII in URLs), and creates downstream coupling that's impossible to unwind. The Config gotcha #1 is unequivocal: SubscriberKey, never Email Address. The cost of changing later is rebuilding the All Subscribers list and re-keying every audience DE.

Mutable IDs from downstream systems

A CRM that lets users change their own ID, a data warehouse that re-issues IDs on dedup operations, a billing system that assigns IDs at first purchase (so users without a purchase have no ID) — none of these are stable enough to be SubscriberKey. When the source system mutates the ID, every MC row keyed by the old value becomes orphaned.

SubscriberKeys that change between staging and production

A SubscriberKey scheme where staging recipients have stage-<id> and production recipients have just <id> creates a hard boundary between the two environments. Test sends in staging don't reproduce production behavior; promoted code that depends on SubscriberKey shape fails differently in each environment. Use the same scheme across environments; the data is segregated by tenant / BU, not by key shape.

Sequential integers when merging audiences from multiple sources

If you have a User ID from system A (1, 2, 3, ...) and a User ID from system B (also starting at 1), naively using either as SubscriberKey causes collisions when audiences merge. The defense is to namespace the keys (a:123, b:456) or to mint a tenant-level UUID separate from either source.

Re-using a SubscriberKey after a recipient is deleted

When a recipient is fully removed (PII deletion under GDPR, account closure), their SubscriberKey should be retired — not reassigned to a new recipient. Reassignment creates the worst-case scenario: emails intended for the original recipient land in the new recipient's inbox; old log rows in de_log_* DEs are misattributed to the new person.

Encoding PII into the SubscriberKey

john.smith.NY.1990-01-01 is a SubscriberKey that contains identifying information — first name, last name, region, birthdate. The opacity criterion fails. The right form is a UUID + a separate mapping DE that holds the recipient's actual attributes; the SubscriberKey is the index, the mapping DE is the payload.

"We'll add SubscriberKey later" — sending without one

A tenant sending its first email using only Email Address as the recipient identifier (no SubscriberKey populated) becomes locked into Email Address by default — the All Subscribers list builds itself based on what's there. The fix is rebuilding from scratch. SubscriberKey must be populated before the first send fires.

The decision checklist before the first send fires

Before any production send goes out from a new tenant, walk through this checklist:

  • [ ] Marketing Cloud's All Subscribers configuration reads SubscriberKey as the identifier (not Email Address)
  • [ ] The SubscriberKey value is minted upstream in a system you control
  • [ ] The value is opaque (no PII; UUID, internal integer, or hash)
  • [ ] The value is stable (you can guarantee it won't change for the same person over the next several years)
  • [ ] The value is unique within your audience (no two distinct people share a key)
  • [ ] The SubscriberKey is populated in every sendable Data Extension at the moment of creation, not retrofitted
  • [ ] The SubscriberKey column type is NVARCHAR(254) everywhere it appears
  • [ ] The mapping from SubscriberKey to downstream identifiers (Salesforce, warehouse, support tools) is documented in the team runbook
  • [ ] The reverse mapping (downstream → SubscriberKey) is implemented in the audience-build SQL Activities
  • [ ] A weekly synthetic-SubscriberKey audit is scheduled (the SQL pattern above)
  • [ ] PII deletion procedure documented (how to retire a SubscriberKey when a recipient is fully removed)
  • [ ] Test sends use real SubscriberKeys from real test recipients, not synthetic values

When all twelve fire, the tenant's SubscriberKey strategy is durable. If any are unclear, the answer is "delay the first send until the strategy is locked" — the cost of changing later is years of operational drag.

Related

Catalog progress: with this page, Config has 6 page-pairs. Remaining: Config Style Guide (decision-framework) to close the section at 7.