For twenty years we added fields straight into the Item table and paid for it at every upgrade. Then extensions put them in companion tables. Now version 29 puts them back in one table. What that history means for a business with three extensions on the Item card, why consolidating them is a data migration, and what to do about it.
Every Business Central customer has fields that Microsoft did not ship: the item's "pallet configuration", the sales order's "despatch window", the customer's "credit insurance limit". Where those fields physically live has changed three times in ten years, and each change has consequences that most businesses only discover at an upgrade, or when they try to tidy up their extensions. This is the history, where it has got to in version 29, and what it means in practice.
In Dynamics NAV, a bespoke field was added directly to the standard table. Item was table 27; your "Pallet Configuration" was field 50001 on table 27, sitting next to Microsoft's fields in the same SQL table, with your code woven into Microsoft's code on the Item card and in the posting routines. It was fast, it was simple, and it was the single biggest reason NAV upgrades were so painful.
Because the moment Microsoft shipped a new version of table 27, someone had to merge: take Microsoft's new object, take your modified object, and reconcile every difference by hand, for every table, page, report and codeunit you had touched. On a system with twenty years of modifications that was weeks of specialist work, it was error-prone, and it was the reason so many businesses stayed on NAV 2009 or 2013 for a decade. The data was never the problem. The merge was.
Business Central's answer, from 2018 onwards, was extensions. You no longer modify Microsoft's objects; you write a table extension that adds your fields to Item, and a page extension that adds them to the Item card, in a separate app with its own ID. Microsoft's objects are never touched, so an upgrade is Microsoft replacing their objects and your extension simply compiling against the new version. No merge. That is the single biggest improvement in the product's history and it is why the twice-yearly release waves are possible at all.
Under the surface, the database had to change too. From the first extension-based versions, each table extension's fields were stored in a companion table: a separate SQL table named for the base table and the app ID, joined to the base table at runtime on the primary key. Three extensions on Item meant three companion tables and three joins every time you read an item. Version 23 (2023) tidied that to one companion table per base table holding all extensions' fields, so at most one join. Better, but a join is still a join, and on the hot tables (Item, Customer, Sales Line, Item Ledger Entry) it was measurable.
Here is the consequence that catches businesses out. A field defined in an extension is owned by that extension. The data in it is stored under that extension's identity. If you have three extensions adding fields to the Item card, you have three owners of the item's bespoke data, and the item card is just a window on to all three.
That is fine until you want to consolidate. And most businesses eventually do, because extensions accumulate: one from the original implementation partner, one from a second partner who did a project later, one from someone using the in-client Designer to add "just one field", one from an ISV app you stopped paying for. Three or four extensions all touching Item, with overlapping purposes, different naming conventions and nobody who remembers why. The sensible thing is to merge them into one well-built customisation extension.
The moment you do, you discover that consolidating extensions is a data migration. The field "Pallet Configuration" in the old extension and the field "Pallet Configuration" in the new extension are two different fields as far as the database is concerned, even if they have the same name and the same ID. The new extension's field starts empty. You have to move the data across, and you have to do it in the right order:
Skip step 3 and the fields look fine (they exist on the card) and are empty. Uninstall the old extension first and the data is archived under the old app's identity, recoverable in some circumstances but not simply, and gone for good if someone chooses "delete data" to tidy up. We have seen both. The second one is not a conversation anyone enjoys.
With 2026 release wave 2 (version 29), Microsoft has changed the storage again. In Microsoft's words: "all fields on an AL table are stored in the same table in the database." The companion tables are gone. Your extension's fields are columns on the Item table itself, named with the extension's ID so they cannot clash, and there is no join at all. Microsoft's reason is performance ("faster performance on all database operations that involve table extensions") and the effect on the busy tables is real.
From a developer's point of view nothing changes: the AL model is the same, extensions compile and run as before, and the data still belongs to the extension that defined the field. From an operational point of view two things change, and they matter:
So we have come full circle: fields in one table, as in NAV, but with the ownership, isolation and upgrade safety of extensions. It is the right design. It just makes extension hygiene matter more, not less.
If you are not sure how many extensions are touching your Item card, or who owns them, that is one of the first things our AL code check reports on, and consolidating them properly is bread-and-butter development work for us. Get in touch before the next release wave rather than after.