Migrating a CEP Means Moving Customer State
🇮🇹 Leggi in italiano

The customer still waiting when the platform switches

Imagine a retailer moving its customer engagement programme to a new CEP on Monday morning. The templates have been rebuilt, the profiles imported, the triggers connected and the first test sends approved. On the migration tracker, the post-purchase journey is green because its replacement has the same messages, conditions and waiting periods.

One customer bought a coat on Friday. She has received the order confirmation and is waiting for a product-care message that the old journey will send seven days after purchase. Another customer bought the same coat a month ago and has already completed the sequence. Both profiles arrive in the new platform with a purchase date and the correct product information, and the question is what happens to each of them next.

The example is constructed, but it is the question I would put on the migration plan before discussing how many journeys have been rebuilt. If the new platform sees two customers with the same purchase attribute, the difference between them (one is waiting for an action, the other has already finished it) has to exist somewhere, and a perfectly successful profile import can lose it completely.

A CEP migration succeeds when the next customer interaction remains correct across the cutover. Reproducing the configuration is part of that work, and usually the part easiest to count, while preserving the behaviour of a system already in motion requires a different inventory.

In the CDP-CEP architecture patterns, I separated the responsibility for customer data from the responsibility for deciding and acting. Migration exposes that separation particularly clearly, because the customer profile can be moved while the customer’s operational position remains behind.

The question is also about to reach a lot of planning meetings. Salesforce signed a definitive agreement to acquire Braze on 20 October 2026, with closing expected during Salesforce’s fiscal 2028 and still subject to shareholder and regulatory approval. Nothing has to move while the deal is pending, but Marketing Cloud Engagement and Braze customers will reasonably ask what a future consolidation could mean for their programmes, and I have read the deal as an architect elsewhere. Whatever the product roadmap eventually says, the part this piece is about depends on what each organisation decides to move, and on how carefully it moves customers who are already in the middle of something.

The customer state hidden behind the journey canvas

A canvas tells you what the programme could do, while the running system also knows what it has already done, what it is waiting for and what it must avoid doing again. Those are different kinds of information, and treating them as one export makes the migration look much simpler than it is.

Profile data describes the customer: identifiers, preferences, purchases, attributes and whatever business context the engagement layer consumes. Execution state describes a particular participation in a particular process: the journey version entered, the branch taken, the current step, the event that started it and the deadline of a wait. A person can participate in more than one process, and sometimes more than once in the same process, so a single field called journey status will rarely describe everything that matters. The same distinction between what happened and what is true now runs through every journey, and a migration is where confusing the two becomes expensive.

Contact history crosses both. A record that an email was sent can determine whether another journey is eligible, whether a pressure rule permits the next message or whether an experiment has already exposed the customer to treatment. Suppression may come from a current preference, a previous delivery failure, a business rule or a temporary operational restriction. Each needs an owner and a meaning that survives the move.

Diagram of what a profile import carries from the old CEP to the new one. The old CEP holds four kinds of state: profile data (identifiers, preferences, purchases), execution state (current step, entry event, wait deadline), contact history (sends, suppressions, pressure counts) and experiment assignment (test or control group). A solid arrow labelled profile import carries only profile data into the new CEP's profile record, which has the same attributes and no position. Dashed arrows from the other three, labelled progress is not imported, history must be reconciled and assignment kept or ended, lead to one box marked as needing a deliberate disposition: finish in place, reconstruct or end. A closing line reads: two customers with the same profile can need different next actions.

The waiting period in the coat example makes the problem tangible. Seven days after purchase means a particular deadline calculated from a particular event. Restarting a seven-day wait on import moves that deadline, replaying the purchase can repeat the sequence, and ignoring the purchase avoids duplication while stranding the customer before the useful care message, so every shortcut changes behaviour in a way the customer can notice.

Experiment assignment adds another dependency. If the old platform placed a customer in a control group, assigning them again in the new one changes their exposure and the meaning of the results. Preserving the original assignment may be necessary, or the experiment may need to end and a new one begin with a clearly declared measurement window. That is a measurement decision to make with analytics, before the migration quietly makes it through implementation.

I would inventory state by asking which fact can change the next action for each live programme, a question that keeps the exercise bounded. An old technical variable with no effect on remaining behaviour may be irrelevant, while a small list of customers already sent a welcome incentive can be critical. Retaining every historical object is a different project from retaining what safe continuation requires.

Choose what to carry, reconstruct or end

Once the inventory exists, each active journey needs a disposition. The options should be visible on the plan, with an owner and a completion condition, because otherwise they emerge accidentally from what the destination platform happens to accept.

One option is to let existing participants finish on the old platform while new entrants start on the replacement. Adobe Journey Optimizer documents a useful distinction here: closing a journey to new entrances allows existing participants to continue, while stopping it ends their progress. In Marketing Cloud Engagement, stopping a journey in Journey Builder likewise ejects every contact still in it. These behaviours are specific to each product and other platforms may differ, but they show why “turn off the old journey” is an insufficient instruction.

Finishing in place can preserve difficult execution state without translating it. It also prolongs the dependency on the old system, including integrations, support, content and the data updates those remaining participants need, and the last scheduled message may be weeks away. A journey that waits for an external event needs an explicit maximum continuation window, otherwise the retirement date can keep moving.

A second option is to reconstruct the remaining behaviour in the destination. The target may not support importing an internal execution position, and I would never assume that it does. Instead, a migration-specific entry path can use declared facts such as the original qualifying event, actions already completed and the remaining deadline. The result is a newly designed continuation, and it needs testing as one.

A third option is to end the old participation deliberately. Some promotional sequences are no longer useful after the move, and continuing them can cost more than the customer value they contain. Ending them is defensible when the consequence is understood, while ending a service obligation or leaving an expected follow-up unowned requires a different judgement.

These choices can differ within one programme. Recent purchases might finish in place, customers waiting on a dated follow-up might be reconstructed, older unfinished records might be closed, and new purchases might enter the replacement. What matters is that the cohorts are distinguishable and cover the population without overlap or unexplained gaps. A customer who falls between two migration rules is still a customer whose experience somebody has to own.

Diagram of cutover cohorts for the post-purchase programme, each routed to one disposition by a labelled arrow. Recent purchases, finish in place, go to the old CEP until a maximum continuation window. Customers waiting with a deadline, through a migration entry path, go to the new CEP with the remaining deadline kept. Older unfinished records, ended deliberately, are closed with the consequence agreed. New purchases, through normal entry, go to the new CEP standard journey. A closing line reads: every customer sits in exactly one cohort, with no overlap and no gap.

Two CEPs, one right to contact the customer

Coexistence is often described through the systems: old platform here, new platform there, integrations between them. I find it more useful to describe it through permissions to act: which platform may send which interaction to which customer, and during which period.

Splitting by customer alone may be too coarse, since a person can still be finishing post-purchase education in the old platform while receiving a new lifecycle campaign from the replacement. Splitting by journey alone can miss a shared contact limit. The actual boundary may combine programme, cohort and interaction purpose, with a stable identifier connecting both systems’ view of the customer.

Pressure management becomes particularly awkward because a platform can only enforce the history available to it. Braze documents frequency capping at campaign and Canvas component send level, configured within a workspace. Moving part of the programme elsewhere creates a coordination requirement outside that local control, and two individually correct caps can permit a combined load the business never intended, which is the same blind spot I described when looking at what the frequency cap cannot see.

The same is true of changed preferences. A customer who opts out through the old platform during coexistence must have that change reflected wherever the relevant interaction can still be executed. This is an operational requirement, so the project should establish the applicable preference and policy rules with the teams that own them. An initial import cannot keep a changing state aligned indefinitely.

For a limited overlap, shared exclusions and a clear routing rule may be enough. A longer coexistence period may justify a common contact record or a decision service. I would choose the mechanism against the required latency and failure behaviour, and I would be wary of introducing another permanent platform simply because two systems are temporarily live.

The awkward question is what happens when that coordination fails. If the shared preference feed is unavailable, the design has to say whether a promotional interaction waits, stops or uses an explicitly permitted recent snapshot, and who receives the alert. These decisions belong in the coexistence design, because the customer will experience whichever default the implementation leaves behind. It is the same test I proposed for judging the Salesforce-Braze deal by the work it removes: eligibility and timing need an explicit owner whichever company owns the platforms, and a migration makes that ownership visible one cohort at a time.

Prove the cutover through customer outcomes

Record counts and template comparisons remain useful checks, because they prove that parts of the move arrived, although they cannot establish that the right customer gets the right next interaction.

I would build a small set of representative histories around the migration’s actual risks. For the post-purchase programme, that means a customer waiting for the care message, one who already received it, one whose order was cancelled, one whose preference changed and one whose purchase event arrives late. Each history has an expected next action, an expected non-action and a deadline where relevant.

The test must follow the history across the boundary, because looking at the destination alone can miss the message still scheduled in the source. Looking at both canvases without their participant records can miss the fact that a reconstructed journey has reset the waiting period. A controlled execution against test identities should demonstrate the combined result, while production comparison should initially avoid creating extra contact.

Timing needs its own acceptance criteria. Equivalent behaviour does not always require identical timing to the second, but the tolerance has to be agreed. A care message delayed by several hours may be acceptable; a limited offer sent after expiry is a different outcome. The migration team cannot resolve both through one generic statement that the sync is near real time.

This is where the conclusion of the Field Notes synthesis comes back. The recurring constraint is the organisation’s ability to govern how quickly a platform can act, and a migration concentrates that problem into a short period when more systems are able to act and everyone is under pressure to declare the work complete.

Rollback begins with what has already happened

A rollback plan that restores the old configuration is incomplete once the replacement has contacted real customers. Delivered messages are part of the new state of the world, and reopening the source without accounting for them can repeat an incentive, restart a sequence or contaminate an experiment the move was intended to preserve.

The cutover therefore needs a record of actions completed during the overlap, tied to the customer and the interaction they represent. That record should distinguish a planned action, a request submitted for delivery, a confirmed execution and an unresolved outcome. If the destination timed out after accepting a send, treating the result as a definite failure can create a duplicate when the old platform resumes.

Recovery should be rehearsed against that ambiguity, so the team knows what it can reconcile, which actions it can safely retry and which require investigation. The useful rollback question is whether the recovered operating arrangement can make the next correct decision with the information now available.

Retirement has similar conditions. Existing participants have finished or received a deliberate disposition, required preference changes and contact history have been reconciled, dependent integrations have an owner, and the records needed for agreed retention and measurement remain accessible. A zero count of active journeys helps, but it cannot establish all of that on its own.

Return to the customer who bought the coat, who has no reason to know that the retailer changed its engagement platform. The useful care message should arrive according to the programme’s promise, with no repeated welcome sequence and no unexplained disappearance halfway through the relationship.

That continuity is the migration deliverable I would defend in the steering meeting.

The new platform is ready when it can inherit the next decision without forgetting the last one.

Sources

Adobe Journey Optimizer

  • Adobe Experience League, Journey ending. Documents the different effects of closing a journey to new entrances and stopping it.



Salesforce Marketing Cloud Engagement

  • Salesforce Help, Stop a Journey. Documents that stopping a journey in Journey Builder ends its activities and ejects all contacts.



Braze



Salesforce and Braze agreement

Open full size