Home Solutions Showcase Insights Pricing Tools Live Website Builder Website Quiz ROI Calculator Architecture Audit Contact
← Back to Insights
Dynamics 365 / X++ Feb 12, 2026 ⏱ 22 min read

D365 X++: What Your Company Doesn't Understand About Your Developers

X++ developers are the most specialized, least understood engineers in enterprise tech. Here's why they're leaving, what companies get wrong about the work, and how the expectations gap is costing you $200K per departure.

The Reality Check Nobody Wants to Hear

Dynamics 365 Finance and Supply Chain Management (F&SCM) — formerly known as AX — runs on X++, a proprietary programming language that exists nowhere else in the technology universe. There is no Stack Overflow community of 10 million users. There are no bootcamps. There are no YouTube tutorials with 500K views.

The global pool of competent X++ developers is estimated at fewer than 25,000 people worldwide. LinkedIn shows roughly 15,000 profiles mentioning X++ — and many of those are consultants who touched it once on a project 5 years ago.

This creates a supply-demand imbalance that companies are either oblivious to or refuse to acknowledge. And it's the root cause of nearly every D365 F&SCM development problem.

25K
Global X++ Developers
11 mo
Avg Developer Tenure
$200K
Cost Per Departure
3–6 mo
Ramp-Up Time

What X++ Actually Is (And Why It's Harder Than You Think)

When leadership hears "it's a programming language like C#," they think: "Great, any C# developer can learn it." This is technically true and practically catastrophic.

X++ is a C#-like language that operates within the Application Object Tree (AOT) — a proprietary model-driven architecture that has no equivalent anywhere else in software engineering. Understanding X++ syntax takes a week. Understanding the D365 application framework takes 6–12 months.

What Makes X++ Development Uniquely Complex:

Aspect What Leadership Assumes What's Actually True
Language difficulty "It's just C# with a different name" The language is 20% of the job. The framework is 80%.
Learning curve "A C# dev can be productive in 2 weeks" Productive in X++ syntax: 2 weeks. Productive in D365: 3–6 months.
Debugging "Same as any other debugger" You're debugging across 18,000+ standard tables and thousands of framework classes.
Customization "Just modify the source code" You're extending via Chain of Command (CoC) — if you modify base code, updates break everything.
Testing "Run unit tests like any project" No test automation culture. SysTest framework exists but adoption is ~5%.
Deployment "Push to prod like any cloud app" Build pipelines take 2+ hours. LCS deployments have 5-hour maintenance windows.
Documentation "Check Microsoft docs" Microsoft docs cover 30% of what you need. The rest is tribal knowledge.

The Application Object Tree Problem

The AOT contains over 18,000 tables, 50,000+ classes, and hundreds of thousands of methods. When a developer needs to customize the posting logic for a purchase order, they don't just write code — they need to:

  1. Understand the PurchFormLetter class hierarchy (5+ levels of inheritance)
  2. Trace the execution path through FormLetterService, FormLetterProvider, and FormLetterContract
  3. Identify the correct extension point (CoC, event handler, or delegate)
  4. Verify their change doesn't break 27 different modules that also use purchase posting
  5. Navigate the number sequence framework, financial dimensions framework, and tax calculation engine

This is not "just C# with a different name." This is the most complex enterprise application framework in existence, and treating it as routine development work is how companies burn through developers.

The Expectations Gap: Company Reality vs Developer Reality

What Companies Say vs What Developers Hear:

Company Says Developer Hears What's Actually Happening
"This should be a simple change" "You have no idea how complex this is" A "simple" field addition touches data entities, forms, security, reports, and integrations
"The partner said 2 weeks" "The partner is lying or clueless" Partners quote optimistic timelines to win deals, developers inherit the fallout
"Just make it work like SAP used to" "You want me to rebuild SAP inside D365" Mimicking another ERP's behavior in D365 fights the platform instead of using it
"Why is this taking so long?" "Let me show you the 18,000 tables I'm navigating" Management can't see the invisible complexity of framework-level development
"Can't you just use a tool?" "There are no tools for this" X++ development tooling is primitive compared to mainstream development
"We need this by Friday" "You need it tested by Friday, that's 6 weeks" Deployments have 2-hour build times and 5-hour maintenance windows
The Core Problem

Leadership evaluates X++ developers using the same yardstick they'd use for a web developer or a .NET developer. But X++ development is closer to embedded systems engineering meets business process consulting. The developer needs to understand both the code AND the business process deeply — and there are only 25,000 people on earth who do.

Why Your X++ Developers Keep Leaving

The average tenure of a D365 X++ developer at a single company is 11 months. That's not because they're flighty — it's because companies create conditions that make staying irrational. Here are the top reasons, ranked by frequency from exit interview data:

1. Compensation Disconnect

Companies benchmark X++ developers against "C# developer" salaries. A mid-level C# developer earns $90K–$120K. A competent X++ developer with D365 F&SCM expertise should command $130K–$180K — because there are 25,000 of them vs. 2 million C# developers.

When an X++ developer leaves for a $30K raise, the company spends $200K replacing them (recruiter fees, onboarding, 3–6 month ramp-up, lost productivity). The $30K raise was the cheapest option, and they refused to see it.

2. "Jack of All Trades" Role Expectations

Most companies hire one X++ developer and expect them to be:

  • A D365 functional consultant (understand all business processes)
  • An X++ developer (write customizations and extensions)
  • A data engineer (manage integrations and data entities)
  • An LCS administrator (manage environments and deployments)
  • A SSRS/Power BI report developer
  • The sole owner of ALL D365-related work, including vendor management

That's 4–5 different roles. The developer burns out because they're constantly context-switching and have no backup.

3. No Development Environment Autonomy

D365 development environments are cloud-hosted VMs managed through Lifecycle Services (LCS). Spinning up a new environment takes hours. Build pipelines take 2+ hours. A developer who wants to test a 10-line code change waits 2+ hours for a build, deploys to their dev environment (30 minutes), then tests.

Compare this to a web developer who saves a file and sees changes in 0.5 seconds. The development feedback loop in D365 is 100x–1000x slower than modern development. Companies that don't understand this will forever be mystified by "why is this taking so long?"

4. Upgrade Treadmill Exhaustion

Microsoft releases major D365 updates every 6 months (10.0.x releases). Each update can break existing customizations, deprecate APIs, or change behavior. Developers spend 20–30% of their time just maintaining compatibility with platform updates — work that leadership sees as "not delivering value" because no new features ship.

5. Isolation

The X++ developer is often the only person in the building who understands their work. There's no peer review. No architecture discussions. No knowledge sharing. No one to ask "does this approach make sense?" They work alone on a proprietary technology with no community, and they feel it.

The Retention Math

X++ developer departs → $30K recruiting fee + $15K onboarding + 4 months of zero productivity ($50K) + 2 months of reduced productivity ($25K) + knowledge loss (unquantifiable but devastating) = $120K–$200K minimum per departure. With 11-month average tenure, some companies are spending this every year.

The 8 Most Overlooked D365 X++ Pitfalls

1. Chain of Command Limitations

Chain of Command (CoC) replaced overlayering as the primary extension mechanism. It's cleaner, but it has silent limitations:

  • CoC on form methods has different behavior than CoC on class methods
  • You can't wrap init(), run(), and certain lifecycle methods on some forms
  • CoC doesn't work on table methods that reference this in certain contexts
  • Debugging CoC extensions is harder because the call stack is obfuscated
// What developers think will work:
[ExtensionOf(tableStr(SalesTable))]
final class SalesTable_Extension
{
    public void validateField(FieldId _fieldId)
    {
        // This may NOT fire when you expect it to
        next validateField(_fieldId);
        // Your custom validation
    }
}

2. Data Entity Versioning Nightmare

Data entities are the backbone of D365 integrations. But Microsoft modifies data entities in updates without versioning. Your integration that worked on 10.0.38 might break on 10.0.39 because a field was renamed, a mapping changed, or a validation was added.

There is no migration path. There is no deprecation warning. You discover it when your integration fails in UAT — or worse, in production.

3. Number Sequence Framework Complexity

Adding a new number sequence in D365 requires touching 5 different layers: the number sequence module, the parameter form, the reference class, the entity, and the data initialization. Miss one layer and the feature works in dev but fails in new environments.

4. Security Model Overhead

D365's security model (duties → privileges → entry points) requires developers to create security artifacts for every new menu item, form, table, and data entity. A developer adding a single new feature may need to create 15+ security objects. This is invisible to project managers tracking "features delivered."

5. Financial Dimensions: The Framework Nobody Masters

Financial dimensions in D365 are stored using a framework of 6+ interrelated tables (DimensionAttributeValueSetItem, DimensionAttributeValueCombination, DimensionAttributeValueGroupCombination, etc.). Querying "show me all transactions for cost center 100" requires joining through this labyrinth. Even experienced X++ developers regularly get this wrong.

6. Batch Framework Gotchas

The batch framework is how D365 processes asynchronous work. The gotchas:

  • Batch jobs run on Batch Server AOS instances, not interactive AOS — different class loading behavior
  • SysOperation framework vs legacy RunBase — most legacy customizations use RunBase, which doesn't serialize properly
  • Batch parallelism requires explicit task bundling — default behavior is sequential
  • Failed batch tasks don't alert anyone by default — they just sit in "Error" state

7. The "ISV Tax"

Independent Software Vendor (ISV) solutions are the D365 equivalent of plugins. Companies buy them to avoid custom development. But ISVs:

  • Often use overlayering or deprecated patterns that conflict with your extensions
  • Update on their own schedule — usually months after Microsoft's platform updates
  • Provide limited source access, making debugging integration issues nearly impossible
  • Can lock you into their approach, making the "build vs buy" decision irreversible

8. Integration Pattern Mismatches

D365 supports multiple integration methods: Data Entities + OData, DMF (Data Management Framework), Dual-Write, Virtual Entities, and custom services. Each has different limitations, performance profiles, and failure modes. The wrong choice costs months of rework.

Integration Method Best For Pitfall
OData / Data Entities Real-time CRUD, Power Platform Performance degrades after ~500 records/batch
DMF (recurring) High-volume batch imports Error handling is file-based; debugging is painful
Dual-Write CE ↔ F&SCM real-time sync Extremely fragile; fails on complex entities
Virtual Entities Read-only access from Dataverse No write-back; query performance is poor on large tables
Custom Services Complex business logic Requires X++ development; no low-code option

The Lifecycle Tax: What Updates Actually Cost

Microsoft mandates that D365 customers stay within 2 versions of the current release. This means you're upgrading at least twice a year. Each upgrade cycle:

  1. Regression testing: 40–80 hours of testing customizations and integrations
  2. Code fixes: 10–40 hours fixing deprecation and breaking changes
  3. Environment management: 8–16 hours managing sandbox → UAT → production deployments
  4. ISV coordination: 4–8 hours verifying ISV compatibility and scheduling aligned upgrades

Annual lifecycle cost: 120–280 hours of developer time — roughly 6–14 weeks of work per year spent just keeping current. That's 1.5–3.5 months of a developer's year consumed by maintenance that delivers zero new business value.

The Customization Trap: When "Standard" Isn't Enough

The D365 sales pitch emphasizes "out-of-the-box" functionality. The reality: most enterprises customize 30–50% of the platform. Each customization creates a perpetual maintenance obligation for every future upgrade.

The compound cost formula:

Annual Customization Cost = 
  Number of Customizations × Avg Hours per Upgrade Test × 2 (upgrades/year) × Developer Rate

Example:
  50 customizations × 2 hrs × 2 upgrades × $150/hr = $30,000/year
  (Just for maintaining what you've already built)

Companies approve customizations one at a time without tracking cumulative maintenance cost. By year 3, they have 80 customizations and wonder why their X++ developer "is so slow" — they're spending half their time on maintenance.

Testing Blind Spots: Why UAT Always Finds Problems Too Late

Automated testing in D365 X++ is theoretically possible with SysTest and the Regression Suite Automation Tool (RSAT). In practice:

  • SysTest adoption is below 5% across the D365 community — developers aren't trained on it
  • RSAT requires Task Recorder recordings as test scripts — these break when forms change
  • No mocking framework exists for X++ — you're testing against live data in dev environments
  • Build-time unit tests execute during the 2+ hour build pipeline — developers skip them to save time
  • Data-dependent tests pass in dev (where data was hand-crafted) and fail in UAT (where data is real and messy)

The result: UAT is where bugs are discovered, not prevented. And UAT happens 2 weeks before go-live, when the cost of fixing bugs is 10x higher than catching them during development.

Performance Landmines: The Queries Nobody Monitors

D365 X++ abstracts database queries through its ORM layer. This is convenient but hides catastrophic performance problems:

// This innocent-looking code generates 10,000 database calls
while select salesLine
    where salesLine.SalesId == salesTable.SalesId
{
    // Nested select inside a loop — the classic N+1 problem
    select inventTable
        where inventTable.ItemId == salesLine.ItemId;
    
    // Process...
}

In a web application, N+1 queries are caught by monitoring tools. In D365, there is no APM by default. Developers often don't know their code is generating thousands of unnecessary queries until users report that "the posting is slow."

Other performance killers:

  • while select without proper indexes — the database plan does a full table scan on a 50M-row table
  • Misuse of RecordInsertList vs. single-row inserts — 1000x performance difference
  • Calling find() inside a loop instead of joining — the most common X++ anti-pattern
  • Financial dimension lookups in loops — each lookup hits 6+ tables

The Developer Retention Playbook

# Action Cost Impact
1 Pay market rate ($130K–$180K for mid-senior X++) $20K–$40K above current Eliminates #1 reason developers leave
2 Never have a single X++ developer — minimum 2 $130K–$180K for second hire Eliminates isolation, enables vacations, reduces bus factor
3 Separate functional consulting from X++ work Functional consultant hire Developer codes instead of attending 4 hours of meetings/day
4 Budget 30% of developer time for maintenance/upgrades $0 (planning change) Stops leadership from asking "why is nothing shipping?"
5 Create a D365 technical architect role $160K–$200K Career path + governance + mentorship
6 Annual training budget ($5K–$10K/developer) $5K–$10K Skill development + retention signal
7 Track customization count as a KPI $0 (process change) Makes invisible maintenance burden visible to leadership

Setting Realistic Expectations: A Guide for Leadership

If you're a CIO, VP of IT, or ERP Program Manager, here's what you need to internalize:

Timeline Reality:

  • A "simple field addition" = 2–5 days, not 2 hours (form + data entity + security + testing)
  • A new integration endpoint = 2–4 weeks, not 2–4 days
  • A custom workflow = 3–6 weeks, not 1 week
  • A module-level customization = 2–4 months, not 2–4 weeks

Hiring Reality:

  • Recruiting an X++ developer takes 3–6 months (not the 2–4 weeks it takes for a web developer)
  • A C# developer needs 3–6 months to become productive in D365 — budget for this
  • Offshore X++ developers are cheaper per hour but communication overhead doubles estimated timelines
  • Partner hourly rates ($200–$350/hr) are expensive, but full-time utilization below 60% makes FTE more expensive

Budget Reality:

  • Your D365 license costs $180/user/month. Your annual development and maintenance costs will be 3–5x the license cost.
  • Each customization costs $5K–$50K to build and $500–$2,000/year to maintain forever.
  • Your "Phase 2" will cost more than Phase 1, because Phase 1 created the customization debt that Phase 2 has to work around.
The Bottom Line

D365 F&SCM is the right ERP for many enterprises. X++ is a powerful extension language. But the platform demands specialized talent, realistic timelines, and management understanding that most companies refuse to invest in. The ones who do retain their developers, ship quality customizations, and stay current on updates. The ones who don't burn through developers every 11 months, accumulate technical debt, and blame the platform for what are really organizational failures.

GG
Garnet Grid ERP Practice
D365 Architecture & X++ Engineering • New York, NY

Need D365 X++ Expertise?

We provide specialized X++ development, architecture reviews, and team augmentation. Let's talk about what your D365 environment actually needs.

Schedule a D365 Technical Review → ← More Insights