An ERP clean core strategy is a portfolio discipline for keeping the vendor core upgradeable while still meeting legitimate business needs. It does not mean zero extensions. It means choosing supported extension points, separating lifecycles where appropriate, controlling dependencies on internal implementation, and retiring custom behavior that no longer earns its cost. The unit of work is each extension and the business capability it serves, not an abstract target percentage.
The portfolio usually contains a mixture of active differentiators, regulatory requirements, obsolete reports, duplicate workflows, emergency modifications, integrations, forms, and code whose owner has left. A transformation cannot classify these from repository presence alone. It needs runtime use, business criticality, data access, coupling, replacement coverage, change rate, and recovery obligations. That evidence supports four outcomes: retain in-app, rebuild with a supported on-stack model, move side-by-side, or retire.
Define clean core as an operating boundary
Write the boundary in testable terms. New work may use released APIs and extension points, approved language versions, governed events, and supported upgrade contracts. Direct modifications, unreleased internals, hidden database reads, and unmanaged copies require explicit exception. SAP's current guidance distinguishes on-stack key-user or developer extensibility from side-by-side applications on SAP BTP, with separate runtime and lifecycle. The relevant lesson generalizes: placement follows coupling and lifecycle, not fashion.
Assign decision rights. The process owner states the required outcome and acceptable change. The ERP product owner protects process integrity. Architecture decides placement and contracts. Security and data owners approve access. Operations accepts monitoring and support. A clean-core office can govern policy, but should not become the owner of every extension. Without business ownership, technical teams preserve unused code because nobody can authorize retirement.
| Placement | Best fit | Primary advantage | Primary obligation |
|---|---|---|---|
| Standard configuration | Supported process variation | Vendor-tested and upgrade-aligned | Accept process standardization |
| Key-user in-app | Fields, forms, simple logic, approved workflow | Close to business context | Stay within released tools and limits |
| Developer on-stack | Tightly coupled logic needing transactional context | Low-latency access to supported core semantics | Use approved APIs, language model, and lifecycle |
| Side-by-side | Independent UI, workflow, partner app, or fast-changing capability | Separate deployment and scaling | Own identity, data replication, reliability, and integration |
| Retire | Unused, duplicate, or standard-replaced behavior | Lower upgrade and support burden | Prove no active dependency and preserve required records |
Build an evidence-rich extension inventory
Start from code scanners, transport history, enhancement registries, interfaces, jobs, forms, reports, workflow definitions, database accesses, and vendor assessment tools. Then enrich with execution telemetry, user and role access, incident history, business calendar, data classification, upstream and downstream dependencies, and release frequency. SAP Cloud ALM exposes extensibility measures such as customer objects, modifications, usage, and clean-core classifications; use tool output as evidence, not the whole decision.
Give each item a stable portfolio ID and connect code, configuration, documentation, interface contracts, owner, and target disposition. Group technical objects into business extensions. One invoice customization may span code, a form, a job, and an interface; counting four objects would distort cost and migration planning. Conversely, one large program that serves several processes may need decomposition because its parts have different futures.
Classify by business value and core coupling
Score value using mandatory compliance, revenue or service impact, differentiation, user reach, and failure consequence. Score coupling using transaction participation, internal tables, synchronous latency, shared locks, unreleased APIs, implicit user context, and dependency on vendor UI. Add change rate and nonfunctional needs. High-value, tightly coupled behavior may justify supported on-stack placement; high-change, loosely coupled behavior often favors side-by-side ownership.
Do not decide from code size. Ten lines inside an unreleased enhancement can block upgrades more than a substantial side-by-side application using stable contracts. Equally, moving simple validation to a distributed service can add latency and failure modes without improving autonomy. The decision record should name the required transactional boundary, consistency expectation, source of truth, expected change cadence, and vendor contract used.
Prove retirement instead of assuming disuse
An extension with no recent execution may be seasonal, year-end, or emergency-only. Observe across its business cycle and interview accountable owners. Search schedules, variants, role assignments, integration calls, reports, audit procedures, and documentation. Disable in a controlled environment, then use a reversible production deactivation where risk permits. Monitor attempts and dependent failures before deleting code. Retain evidence and records according to policy.
Standard replacement requires process confirmation. A vendor feature can overlap technically while differing in approvals, localization, segregation of duties, output format, or historical behavior. Map requirements to the standard function, record accepted gaps, migrate configuration and data, train users, and remove the old path. Running both indefinitely preserves duplicate controls and confuses record authority.
| Decision factor | Evidence | Favors on-stack | Favors side-by-side or retirement |
|---|---|---|---|
| Transactional need | Commit boundary and rollback behavior | Must participate in supported ERP transaction | Eventual consistency or compensation is acceptable |
| Change cadence | Release history and product roadmap | Changes with core process | Independent frequent releases |
| Data access | Fields, volume, classification, latency | Narrow supported local context | Owned projection or external domain data |
| Differentiation | Business capability assessment | Small process-specific rule | Distinct product experience or no remaining value |
| Vendor coverage | Fit-to-standard and roadmap evidence | Extension point remains necessary | Standard function replaces it or supported API enables decoupling |
Price the side-by-side responsibilities
Moving code out of the core removes one class of upgrade coupling but creates a product to operate. Account for identity, authorization, tenant context, network connectivity, API quotas, event delivery, data replication, privacy, observability, deployment, support, and disaster recovery. Define what happens when ERP is unavailable and how duplicate or delayed events reconcile. A side-by-side extension is clean only if its contract with the core is supported and governed.
Minimize replicated data and assign authority per field. Use released APIs or events, version contracts, and avoid recreating an ERP shadow database. For synchronous calls, set timeouts and failure behavior that preserve the user's transaction. For asynchronous work, use idempotency, replay, and business reconciliation. Include the extension in end-to-end process monitoring so a healthy ERP screen cannot conceal a failed downstream approval or posting.
Govern new extensions at intake and delivery
Require a short extension decision record before build: business outcome, standard-fit analysis, owner, placement, released contract, data, transaction semantics, operational owner, upgrade test, and retirement trigger. Architecture review should be proportional. A simple approved field extension should follow a paved path, while a custom pricing engine touching orders requires deeper review. Fast, predictable governance discourages teams from bypassing policy.
Automate what policy can express. Static checks can detect restricted APIs, language versions, direct table access, or forbidden modifications. SAP describes ABAP Test Cockpit variants for clean-core checks; equivalent controls can be used on other ERP platforms. Keep an exception registry with owner, reason, compensating control, target release, and expiry. A passing scanner does not prove business fit, but it prevents known technical boundary violations.
Sequence the portfolio by upgrade risk and dependency
Create waves that unlock future work. Retire confirmed unused objects first, then replace standard-covered functions, remediate unsupported interfaces, and isolate high-value extensions. Sequence shared APIs and data projections before dependent side-by-side applications. Align changes with process testing and business blackout periods. Do not move the largest objects first solely to show progress; prioritize upgrade blockers, security exposure, and high support cost.
Measure outcomes by unsupported dependency reduction, retired business extensions, exception age, upgrade test effort, incident rate, lead time for approved extensions, and operational cost of side-by-side products. Avoid celebrating raw object counts without weighting use and risk. A portfolio can shrink numerically while retaining the few modifications that make every upgrade difficult.
Example: reclassify a credit approval extension
A custom approval intercept reads internal order and customer tables, calls a spreadsheet-based score, and blocks save. The business needs a synchronous credit limit check but can tolerate asynchronous escalation for exceptional cases. The team adopts the vendor's released credit check for the transaction, moves exception orchestration to a side-by-side workflow using approved events and APIs, and retires the spreadsheet import after reconciling active approvals.
The new design keeps the hard transactional rule close to the ERP while giving the frequently changing approval experience an independent lifecycle. It also creates new duties: event replay, queue monitoring, identity, and reconciliation of pending approvals. The decision is cleaner because those responsibilities are explicit and the unsupported table dependency disappears, not because all customization moved outside.
Key takeaways
- Treat clean core as governed extensibility, not a ban on all custom behavior.
- Inventory business extensions with runtime, dependency, owner, and risk evidence.
- Choose placement from transaction coupling, change cadence, data authority, and operating responsibility.
- Prove retirement across the relevant business cycle.
- Price side-by-side identity, integration, consistency, and support before selecting it.
- Control new extensions while reducing the inherited portfolio.
Frequently asked questions
Does clean core mean zero custom code?
No. It favors supported extension models and explicit contracts so upgrades remain manageable. Necessary differentiation can remain, but placement and dependencies must be justified and governed.
Is every side-by-side extension clean-core compliant?
No. An external application can still depend on unreleased interfaces, copy excessive data, or create fragile coupling. Compliance depends on the supported boundary and lifecycle, not only the runtime location.
When can unused custom code be deleted?
After execution and dependency evidence covers its business cycle, accountable owners approve retirement, required records are preserved, and reversible deactivation produces no unresolved demand. Keep an audit trail of the decision.
Conclusion
A defensible ERP clean core emerges from thousands of explicit portfolio choices. Evidence-rich inventory, business ownership, fit-to-standard analysis, coupling-aware placement, proven retirement, automated checks, and expiring exceptions reduce upgrade risk without freezing innovation. The strategy works when every extension has a reason to exist, a supported boundary, an operator, and an eventual exit condition.