The Journey of Storing Data for Extensions in BC

Introduction

Microsoft Dynamics 365 Business Central (BC) is a modern ERP solution that has always prioritized flexibility and extensibility. One of the core mechanisms enabling customization is the extensions model, introduced in 2018 with BC 13 (formerly Dynamics NAV 2018). Extensions allow developers to modify standard objects such as tables, pages, and codeunits without altering Microsoft’s base code.

We have already explored one important aspect of this evolution — how the rules and possibilities for changing and adding fields have evolved over the years — in the article Evolution of Field Changes in Business Central .

Today we’re diving into an equally critical, yet often less visible topic: how the data added by extensions is physically stored in the database, and how Microsoft radically transformed this mechanism from 2018 to 2025. What started as a fully isolated model with one companion table per extension has evolved — through years of performance challenges and community feedback — into the highly optimized, consolidated storage model we have from BC 23 onward. The result? Operations that once took 7–10 seconds on large datasets now complete in under a second, often with just a single SQL query change behind the scenes.

This is the story of that journey.

7 Seconds to 1 Second – The Hidden Performance Story of BC Extensions

Early Years: Introduction of the Extensions Model (BC 13–BC 16, 2018–2019)

The extensions model debuted in October 2018 with BC 13, replacing traditional C/AL customizations with the AL language and AppSource. Table extensions made it possible to add new fields to standard tables (e.g., Customer, Item), but the data from those fields was not stored directly in the base table. Instead, the platform automatically created companion tables — separate SQL tables for each extension.

Key characteristics:

  • Complete data isolation: Each extension had its own companion table (e.g., Customer$<AppID>), with the same primary key as the base table. This ensured that installing, updating, or uninstalling an extension never affected standard data.
  • Data reading: Whenever AL code accessed a record (e.g., Customer.FINDSET), the BC server automatically performed joins with all relevant companion tables, presenting the extended table as a single logical entity.
  • Problem: With a single extension the join was trivial, but each additional extension multiplied the SQL cost. Five extensions meant five joins — a major slowdown for reports, web services, and large datasets.

No significant storage changes occurred in BC 14–BC 16 (2019), but Isolated Storage was added for sensitive extension data (passwords, certificates), improving security without touching the companion-table model.

VersionKey ChangeImpact on storage
BC 13 (2018)Table extensions + companion tables introducedOne companion table per extension; automatic joins
BC 14–BC 16Isolated Storage for sensitive dataAdditional isolation layer, no change to companion tables

Intermediate Optimizations: On-Demand Joining & Partial Loading (BC 17–BC 22, 2020–2022)

As AppSource grew in popularity, Microsoft began addressing performance pain points.

  • BC 17 (2020 wave 2) introduced on-demand joining of companion tables and the SetLoadFields method. Fields from extensions were loaded only when actually needed, significantly reducing unnecessary joins.
  • BC 18–BC 20 (2021) added the MovedTo/MovedFrom properties, allowing tables and fields (along with their data) to be migrated between extensions without loss.
  • BC 21–BC 22 (2022) introduced the DataTransfer codeunit type for ultra-fast bulk data movement between tables using optimized SQL operations.

These versions focused on read-performance optimization and data migration, but the core problem remained: every installed extension still created its own companion table. Seven extensions = seven joins, which could degrade performance by 50–80 % on large record sets.

VersionKey ChangeImpact on storage
BC 17 (2020)On-demand joining & SetLoadFieldsFewer unnecessary joins; partial record loading
BC 18–BC 20MovedTo/MovedFrom propertiesAutomatic data transfer between companion tables
BC 21–BC 22DataTransfer codeunits (bulk SQL transfer)Much faster mass data migration

The Revolution: Companion Table Consolidation (BC 23+, 2023–2025)

The real breakthrough came in BC 23 (2023 wave 2). Microsoft completely redesigned the storage model: instead of one companion table per extension, all extension fields for a given base table are now consolidated into a single shared companion table with the suffix $ext (e.g., Customer$<TenantID>$ext).

Why this change?

  • Performance: Only one join (base table + $ext) is needed, regardless of how many extensions are installed. Real-world tests show 50–80 % faster reads and writes on large datasets (e.g., looping 100 000 records dropped from ~7 s to ~1 s).
  • Backward compatibility: No AL code changes required — the platform handles everything automatically during schema synchronization.
  • Isolation preserved: Fields are still separated by App ID inside the consolidated table.

Subsequent waves continued polishing the model:

  • BC 24–BC 25 (2024) added tooltips on extension fields and staging moves for breaking changes.
  • BC 26 (2025 wave 1) extended analysis mode to include fields from related tables, leveraging the new consolidated structure.
VersionKey ChangeImpact on storage
BC 23 (2023)Consolidation into single $ext tableOne join only; 50–80 % performance gain
BC 24–BC 25Tooltips, staging movesSmoother migrations and better UX
BC 26 (2025)Related-table field analysis in analysis modeFurther utilization of consolidated model

Impact on Developers and End Users

  • Developers: No longer need to worry about performance penalties when adding fields. Tools like Table Information (page 8700) make it easy to monitor companion table sizes.
  • End users: Faster page loads, reports, and API calls — especially noticeable in SaaS environments with many installed apps.
  • Remaining limitations: System tables (ID > 2 billion) and virtual tables still cannot be extended. Changing the primary key in an extension can still cause data loss in companion tables.

Summary and Outlook

The journey from isolated companion tables (2018) → read optimizations (2020–2022) → full consolidation (2023+) demonstrates how Microsoft has successfully balanced extensibility with performance. BC 23 was the true game-changer, reducing joins to a minimum and paving the way for rich AppSource ecosystems. Future waves (BC 27 and beyond) are expected to bring even deeper AI/Copilot integrations that will further capitalize on this efficient storage model.

Official documentation: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-table-ext-object

Leave a Reply

Your email address will not be published. Required fields are marked *