The decision usually gets made by accident
Most Dataverse teams never actually decide between extending a standard table and building a custom one. Someone gets an asset tracking requirement in week three of a Dynamics 365 Sales rollout, opens Account in the maker portal because that screen is already in front of them, and starts adding fields. Six weeks later Account carries twenty-two new columns and nobody can say which four the sales team fills in.
I have been burned from both directions. I once signed off on a custom table build that added three months to a project that needed two extra columns on Contact and nothing else. I also spent two days on a call with a client's integration lead debugging a nightly sync that had gone from four minutes to fifty-one, because those extra Account columns meant six plugin steps now fired on every Account update, including the update our own job made just to stamp a sync timestamp.
Both answers hold up in a design review. Both fail in ways you can see coming if anyone asks the right questions first.
What genuinely belongs on a standard table
A column belongs on Account when it describes the account itself, has exactly one value at any moment, and the business expects to see it on the account form. A segmentation code finance maintains, the assigned service region, the date of the last contract review, a credit tier. One value, no history, no approval on it, no lifecycle of its own.
The test I use in workshops is whether someone could fill the field in during one phone call with the customer, and whether the answer stays true next quarter without anyone tracking how it changed. If the business later asks what the value was in March, or wants two of them at once, or wants somebody to approve a change to it, the requirement has a lifecycle and belongs in its own table. Half the arguments I sit in resolve right there, because nobody had asked whether history mattered.
Cardinality settles the rest. An account has many assets. Each asset has a serial number, a warranty window, an owner, and a status that moves through stages. The moment a field list contains asset1serial and asset2serial, the model has already told you what it wants. Serial numbers also deserve a think about how durable your business keys are, because they become the join key in every integration that touches this data.
The plugin load on Account is a real cost
Standard tables in a mature org carry weight that a fresh custom table does not. Account in a five year old Sales and Customer Service org usually has a dozen registered plugin steps, two real time workflows nobody has reviewed since 2022, business rules on half the forms, duplicate detection rules, and at least one Power Automate flow triggered on update with no column filter set.
Your new column inherits all of it. The column itself triggers nothing. Anything that writes to it fires a full update message on Account, and the pipeline does not care that your integration touched one field out of ninety. That was the fifty-one minute sync. The fix was a column filter on one flow trigger plus filtering attributes on two plugin steps left empty since the 2019 build. It took two days to find because the timeout surfaced in the integration log while the cause sat in the plugin registration tool.
Twenty minutes in the plugin registration tool before you add the field is cheaper than the debugging. Count the steps registered on Update of that table, then check how many have filtering attributes set. More than five steps with most of them unfiltered means you are adding your requirement to a hot path, and the bill arrives with the person who picks up the platform incident at eleven at night.
What a custom table quietly gives up
The custom table build fails somewhere else. You create a Customer Asset table with a lookup to Account, model it properly, and every review passes. Then UAT starts, an account manager opens an account, and the assets are not in the timeline. They sit in a subgrid on a tab, which is correct, and which is also a control nobody on that team has clicked in three years.
The behaviours that follow standard tables and do not automatically follow yours pile up fast. Connections, account hierarchy roll ups, cascade and sharing behaviour you now configure by hand, Relevance Search inclusion, the mobile offline profile, and the quiet assumption in half the existing Power BI datasets that customer data hangs off Account. None of them block you. All of them are unestimated days.
Reporting is where it usually surfaces. A new table means the analytics team has to know it exists, add it to the dataflow, and rebuild the relationship in the model. That only happens if somebody made the reporting question part of the requirement instead of an afterthought in week nine. I now ask for the report mock before I approve the table.
What happens when Microsoft ships it natively
The long game decides most of these for me. Custom columns on a standard table age badly against first party features. When Microsoft ships something native that covers the same ground, it arrives with its own columns on Account, and the org ends up with two segmentation fields, each with its own owner and its own set of reports. I watched one team spend a full release cycle deciding which of the two was authoritative, and the answer in practice stayed both.
A custom table ages better because the overlap stays visible. If a first party asset table ships, you have two tables, a mapping document, a migration, and a date you can put in a plan. Ugly work, and bounded work.
The habit that helps either way is reading release notes with your own customisations open beside them. Teams that drown in the volume of monthly release notes usually drown because nobody maps a wave item back to the tables they extended.
A test to run before anyone opens the maker portal
Put four questions in the design review and write the answers into the solution design document where the next consultant will find them. Does this data need history or an approval? Can more than one of it exist per account? How many plugin steps and unfiltered flow triggers already run on update of the standard table? What is the migration story if a first party feature covers this next year?
My default after enough of these is simple. Under five columns, single valued, no history, no approval, put them on the standard table and register every new step with filtering attributes set so the hot path does not get hotter. Anything with its own status, its own owner, a start and end date, or an approval step gets its own table, and you budget the days for timeline behaviour, search, security, and the reports that assume everything hangs off Account. The middle cases, and there are always middle cases, get decided by the plugin count on the standard table.
One habit sits above both choices. Whoever owns the data model should also own the columns a customer record has to carry for every department, because asset tracking built for Sales becomes entitlement checking in Service inside a year, and a design that only answered the Sales question gets reopened.
So the next time somebody in a stand up says it is only a couple of fields on Account, share your screen, open the plugin registration tool, and count the steps registered on Update. Then ask who is going to debug the sync job when that number goes up by one.



