CRM Data Model Antipatterns: Objects, Properties, Associations and Their Corrections
CRM data model antipatterns hold a HubSpot fact in the wrong object, property or association, and this catalogue gives eleven with the report each one breaks.
Paul Maxwell, PhD
AUTHOR
GET WEEKLY REVOPS INSIGHTS
No spam. Unsubscribe anytime.
Six deal properties named Product 1 to Product 6 hold one fact, the products sold on a deal, in six places. On the sample portal this article measures, a HubSpot report grouped by Product 1 counts 96 payroll deals closed last year, while a filter across all six properties finds 312. A grouping reads one property, and 216 of those deals list payroll second or later. A referral partner typed as text fails differently: a report reaches another record only through an association, so no report can group the deals by the partner's tier. Both faults are corrected in the data model: line items for the products and a labelled association for the partner.
This article catalogues eleven CRM data model antipatterns in HubSpot, grouped by where the defect sits: in objects, properties or associations. It starts with the three documented reporting rules that turn each antipattern into a failed report, then gives the catalogue, each antipattern's correction and the symptoms that point back to them. A sample portal of 412 custom properties measures the results, and the article closes with placement rules, an audit procedure, the business case and the catalogue's boundaries.
An object is a type of record, such as contacts, companies, deals or a custom object, and a property is a field on an object. An association is a link between two records, always two-way in HubSpot, and an association label names the role a record plays in it, such as Billing contact. The three correspond to the entity, attribute and relationship of Peter Chen's entity-relationship model, and the catalogue's three groups follow them. An antipattern here is a placement that looks right when it is made, produces one of three report results, and has a known correction.
The Three HubSpot Reporting Rules a Data Model Must Satisfy
Three documented rules govern how HubSpot reporting reads a fact, and under them every data model antipattern gives one of three report results: several reports, two answers or no answer. The custom report builder, on Professional and Enterprise, gives a chart one field on its X-axis and one Break down by field, so a grouping reads one property. Sum and Average are available for number fields only, so a figure held as text can be counted but not added. A second data source enters a report through its association with the primary source, and where HubSpot cannot create a path between two sources, the second becomes unavailable.
Under these rules a fact split across properties, spellings or a delimited string needs several reports; a fact held twice gives two answers, because each copy satisfies every rule; and a relationship or a number held as text gives no answer. The test for an antipattern is therefore a report that cannot answer its question once, or two reports that disagree; the custom report builder article sets out the chart types.
Where a fact is split or held as text, every stored value can be correct, so the defect is where the fact sits. Where it is held twice, each copy can be correct when written, and blanks and drift give the two answers. Wang and Strong's study of what data quality means to data consumers separates intrinsic quality, which data has in its own right, from the representational and accessibility quality that depends on the system holding it. Data model antipatterns are defects of the second kind, so a clean-up of values leaves them in place. HubSpot's data quality tools flag duplicate, empty and unused properties, but no documented check finds a numbered slot, a relationship held as text or a company fact on the contact.
CRM Data Model Antipatterns in One Table
The last column gives the first edition on which HubSpot documents each correction. Organisational antipatterns, such as a definition nobody owns, are catalogued in RevOps antipatterns, and the antipatterns index lists every catalogue by area.
| Antipattern | Symptom | Report result | Correction | Correction needs |
|---|---|---|---|---|
| Antipattern1. A custom object copying a standard object | SymptomThe same people in two objects | Report resultTwo answers | CorrectionA type property on the standard object | Correction needsAny edition |
| Antipattern2. A custom object used as a picklist | SymptomRecords holding a name and nothing else | Report resultTwo answers | CorrectionA dropdown property | Correction needsAny edition |
| Antipattern3. An entity flattened into numbered properties | SymptomProduct 1 to Product 6 on the deal | Report resultSeveral reports | CorrectionLine items, or labelled associations | Correction needsAny edition; Professional for labels |
| Antipattern4. A company fact stored on the contact | SymptomThe contact's Company name differs from its company's name | Report resultTwo answers | CorrectionReading through the association; a sync property | Correction needsProfessional |
| Antipattern5. Free text holding a closed list | SymptomLinkedIn and linked in as separate groups | Report resultSeveral reports | CorrectionA dropdown with its options merged | Correction needsAny edition |
| Antipattern6. Several values in one text property | SymptomFilters built on contains | Report resultSeveral reports | CorrectionMultiple checkboxes, or associated records | Correction needsAny edition |
| Antipattern7. Two properties for one fact | SymptomTwo reports disagree on one question | Report resultTwo answers | CorrectionOne survivor, the other archived | Correction needsAny edition; Professional to copy by workflow |
| Antipattern8. Numbers and dates stored as text | SymptomNo sum, average or time between | Report resultNo answer | CorrectionA typed property loaded by import | Correction needsAny edition |
| Antipattern9. A relationship stored as text | SymptomA partner's name typed on the deal | Report resultNo answer | CorrectionA labelled association | Correction needsAny edition; Professional for labels |
| Antipattern10. Associations without roles | SymptomThe buyer cannot be told from the user | Report resultNo answer | CorrectionAssociation labels and limits | Correction needsProfessional |
| Antipattern11. Parent and child companies for a link that is not ownership | SymptomA company needs a second parent | Report resultNo answer | CorrectionA custom paired label | Correction needsProfessional |
Object Antipatterns
1. A Custom Object Copying a Standard Object
HubSpot's custom objects documentation gives its own example of an object that should not exist: parents and teachers kept as custom objects beside a school's contacts. Its reasons are that a person can be both, and that bulk marketing emails can be sent only to contacts. A Partners object beside companies repeats the pattern, although the company property Type already lists partner among its options. HubSpot's duplicates manager covers only contact and company duplicates, so no documented check compares a copy with its original. The correction is a type property on the standard object, such as HubSpot's Contact type dropdown of Student, Parent and Teacher. Custom objects need Enterprise, with 10 definitions on Marketing, Sales, Service or Content Hub under the product catalog, and a deleted custom object cannot be restored.
2. A Custom Object Used as a Picklist
A Region object whose records carry a name and nothing else, each associated with hundreds of companies, holds an attribute of the company: a region with no owner, quota or lifecycle is a value. The object also moves report totals, since the report builder can count a record once for each associated record that meets a filter, and totals shift with the primary data source. A dropdown holds up to 5,000 options under the enumeration limits without using an Enterprise object definition, so it is the correction unless each value carries properties of its own, such as a territory's owner and quota.
3. An Entity Flattened Into Numbered Properties
Properties named Product 1 to Product 6 on a deal, or Contact 2 to Contact 5 on a company, hold a second entity inside the first. The set caps the count at its last slot, and a report grouped by Product 1 counts first products only. Products belong in line items, available on every edition, each with its own record ID, unit price, quantity and term; their copies across quotes and invoices are set out in quote-to-cash antipatterns. People belong in contacts labelled by role. A location with its own address and service history needs a custom object on Enterprise, like the site object for managed service providers. On Professional the alternative is a company joined by a paired label such as Headquarters and Regional Office, HubSpot's example in its association label documentation.
Property Antipatterns
4. A Company Fact Stored on the Contact
HubSpot's default contact properties include employer fields such as Company name, Annual revenue and Number of employees. They keep the contact's Company name separate from the associated company's and unaffected by association, and define Industry only as "the contact's industry". A portal that collects the employer's industry there holds a second copy of a company fact, which the automatic association setting does not sync, so a report of contacts by industry has two answers. The correction reads company facts through the association. Where a contact needs the value, for an email token or a segment, a sync property on Professional or Enterprise copies it read-only from the company labelled Primary and keeps it current.
5. Free Text Holding a Closed List
A single-line text property that collects a value from a short list, such as a lead source, records one value in as many spellings as users type. HubSpot's field-type documentation treats LinkedIn, linkedin and linked in as three unique values, each becoming its own option when the property is converted to a dropdown. That conversion is also the correction, since the options can then be merged. A merge moves every record holding a merged option to the surviving option but does not update the segments, workflows or filters that use a merged value. HubSpot recommends an export before converting, because a field-type change can invalidate stored values.
6. Several Values in One Text Property
A text property holding a list, such as Products owned containing CRM; Payroll; Benefits, stores several values in one field. Filters rely on contains conditions, and a report groups each combination string as a value of its own, so a count of customers per product needs a report per product. A closed list belongs in a multiple checkboxes property, and items with dates or amounts of their own belong in associated records. A field-type change would make each combination string an option, so the documented route is an import of multiple checkbox values separated by semicolons, once every option exists.
7. Two Properties for One Fact
A portal holding Lead source beside Lead source (new), or a custom Company type beside the default company property Type, answers one question twice, and the two reports disagree by however far the properties have drifted. HubSpot's property guidance asks for a check of the default properties before any custom property is created. The correction keeps one survivor, preferring the default, copies the values across, repoints every report, segment, form and workflow, and archives the other. A workflow copies only between compatible field types: text to text, and dropdown to dropdown where the target holds every internal value of the source. Lifecycle stage held beside a custom status is set out in lead status vs lifecycle stage.
8. Numbers and Dates Stored as Text
Contract values or renewal dates imported into single-line text properties read correctly on a record but cannot be summed, averaged, rolled up across associated records or used in a Time between calculation. A workflow cannot convert them, since text copies only to text, and changing the field type in place can invalidate stored values. A new number or date property loaded by export and import keeps every value; the text property is archived once the values are checked. A property that must stay text can carry validation rules, which apply to new entries only and are not enforced on workflow updates.
Association Antipatterns
9. A Relationship Stored as Text
A partner's name typed into a Referral partner text property on the deal records a relationship as a value, which no report can join. Referred deals cannot be grouped by a property of the partner company, and a renamed partner leaves the old spelling on every deal. The correction is an association labelled Referral partner, or a HubSpot user property for a colleague such as an account manager. The Create associations workflow action, on Professional or Enterprise, converts the text only where it matches a record exactly, case included. An import converts the rest by record identifier, so the work grows with the distinct spellings rather than with the deals.
10. Associations Without Roles
A deal associated with six unlabelled contacts cannot say which contact signs, which uses the product and which pays. An association label records the role, and the association label documentation gives labels as the selector in segment filters, workflow filters and the Send email action. Without them, a filter on associated contacts matches any contact that meets it, an email cannot be limited to the signer, and a sync property picks among the contacts by create date. Labels need Professional or Enterprise, are created by a Super Admin and are limited to 50 per object pair, and a deleted label cannot be restored. Association limits fix a count, such as one Billing contact per company, and HubSpot blocks any association beyond it.
11. Parent and Child Companies for a Link That Is Not Ownership
HubSpot implements parent and child companies as a pair of default association labels, and its parent and child documentation allows a child company only one parent. A portal that records a reseller or a buying group as a customer's parent therefore cannot also record its corporate owner. A custom report also accepts only one same-object association label, so it shows the ownership hierarchy or one other company-to-company relationship, never both. The correction reserves parent and child for ownership and records every other company-to-company relationship with a custom paired label, such as Reseller and Resold customer, with its limit set to many in each direction.
Symptoms Traced to Their Antipatterns
Three symptoms can each come from two antipatterns, and a check in HubSpot separates the candidates.
One count needs several filters or reports: a numbered set, antipattern 3, or a delimited list, antipattern 6. In the property export, a numbered set appears as properties whose labels differ only by a number, and a delimited list as one text property whose record export shows separators inside its values.
Two dashboards give different counts for one industry or segment: a company fact copied to contacts, antipattern 4, or two properties for one fact, antipattern 7. The property each report groups or filters on names the pair.
A cross-object report cannot reach the record holding a needed property: the relationship is held as text, antipattern 9, or the association lacks a label, antipattern 10. The View data join info panel shows how the report's sources are joined.
Custom Field Sprawl on a Sample Portal
On the sample portal built for this article, three report tests fail before correction and pass after it, and 123 properties in seven structural classes, 29.9 per cent of the 412 custom properties, carry every failure. The largest flagged class, 71 properties with no values and no usages, is 17.2 per cent and changes no figure when archived. The portal belongs to no client, and its proportions claim no prevalence for any antipattern. It runs Sales Hub and Marketing Hub at Professional, without custom objects, and holds 9,400 contacts, 2,150 companies, 1,320 deals and 412 custom properties: 168 on contacts, 121 on companies and 123 on deals.
| Classification | Before | After | Correction applied |
|---|---|---|---|
| ClassificationNumbered sets: Product 1 to 6 on deals, Contact 2 to 5 and Location 1 to 5 on companies, four fields per slot | Before60 | After0 | Correction appliedLine items, labelled contacts, labelled regional offices |
| ClassificationCompany facts copied to contacts | Before14 | After5 | Correction appliedNine archived; five kept as sync properties |
| ClassificationA second property for a fact already held | Before19 | After0 | Correction appliedValues copied to the survivor, then archived |
| ClassificationFree text holding a closed list | Before12 | After12 | Correction appliedConverted to dropdowns in place |
| ClassificationSeveral values in one text property | Before4 | After4 | Correction appliedReplaced by multiple checkboxes properties |
| ClassificationNumbers and dates held as text | Before9 | After9 | Correction appliedReplaced by number and date properties |
| ClassificationRelationships held as text | Before5 | After0 | Correction appliedReplaced by labelled associations |
| ClassificationNo values and no usages | Before71 | After0 | Correction appliedArchived |
| ClassificationNo antipattern found | Before218 | After218 | Correction appliedUnchanged |
| ClassificationTotal | Before412 | After248 | Correction applied164 removed |
The contact object uses 168 of the 1,000 custom properties the catalog allows per object, so the limit measures size, not placement.
The first test counts last year's product lines by product. The 600 deals closed won in the year fill Product 1 on 600 deals, Product 2 on 270, Product 3 on 105, Product 4 on 33, Product 5 on 9 and Product 6 on 3, so a grouping by Product 1 sees 600 of 1,020 product lines, 58.8 per cent. Payroll was first on 96 of its 312 deals, second on 141, third on 57, fourth on 15 and fifth on 3, so that report credits it with 30.8 per cent of its sales. As line items, the 1,020 lines carry the product in one Name property, which a single-object report on line items, on Professional and Enterprise, groups by: Payroll then shows all 312. Importing line items leaves each deal's amount unchanged.
The second test counts contacts at software companies. The sample's forms ask for the company's industry and write it to the contact's Industry property. Of the 7,900 contacts with a primary company, 3,020 work at a company whose Industry is Software; the contact's own Industry agrees on 2,050 of them, names another industry on 370 and is blank on 600. Another 300 contacts carry Software against a different industry on their company, and none of the 1,500 without a primary company carries it. The contact property therefore counts 2,350 against 3,020 through the company, a difference of 670 or 22.2 per cent, with 1,270 contacts in one answer and not the other.
The third test groups referred deals by partner tier, which no report can do while the partner is text: 240 deals name 18 partner companies in 61 distinct spellings. The Create associations action matches only the 18 spellings that equal a company name exactly, which cover 151 deals, or 62.9 per cent; the other 43 spellings, legal suffixes and lower-case variants among them, sit on 89 deals. Mapping all 61 spellings to record IDs and importing labelled associations covers all 240, so the 89 unmatched deals needed 43 decisions.
Placement Rules for Objects, Properties and Associations
Every correction above answers one question, asked before a property is created: where in the model the fact belongs. Six questions run in a fixed order, and the first answer of yes ends the decision.
The first question asks whether the thing a fact describes has an identity, properties or a lifecycle of its own, as the unit sold, installed and serviced in the illustrative serialised equipment case study does. The HubSpot Smart CRM article applies the narrower lifecycle test to custom objects. HubSpot-defined objects come before custom ones: under the object documentation, a Super Admin activates appointments, courses, listings, services and projects in the data model tool, with no Enterprise requirement stated. An association holds no value of its own: the association label documentation describes only a label, an internal name and limits. A referral fee therefore sits on the deal, or in an object between deal and partner where a deal has several partners.
The Data Model Audit in HubSpot
The audit reads the property export and the data model before changing anything, and ends when each report test returns one answer. It needs Super Admin access, export permission and a Professional or Enterprise account for labels, limits, sync properties and association workflows, and it is the data model part of a broader HubSpot audit.
- In Settings, open Properties and choose Export all properties for contacts, companies and deals; the file lists each property's internal name, type, group, options, usages and fill rate.
- Mark every numbered set, meaning properties whose labels differ only by a number, and count the properties in each set.
- Mark copies: contact properties that describe the company, and pairs that describe one fact, naming a survivor for each pair and preferring the default property.
- Export records for each single-line text property with few distinct values, and mark it as a closed list, a delimited list, a number or date, or a relationship whose values match existing record names.
- In the data model's table view, open each object's Associated objects and labels tab and list unlabelled pairs with several associated records, labels without limits, and parent and child pairs that record anything but ownership.
- Write the report test for each marked item: the question, the report that cannot answer it once, and the answer expected after correction.
- Correct relationships held as text and associations without roles first, since every report, sync property and workflow that needs the related record waits on them. For each item, create the target, load it by import or workflow, and repoint every asset in the old property's usages and each segment, workflow and filter that used a merged option. Then archive the old property.
- Verify: rebuild each report test and confirm one report returns the expected answer, open Actions, View association history on three converted records, and record the new property counts on the Limits tab.
The Business Case for Correcting the Data Model
Correction buys reports that answer a question once: products counted from one property, an industry read from one record, a partner reached through one association. It also lets workflows, sync properties and segments select the related record by label rather than by a typed name, and in the sample it removes 164 of the 412 custom properties.
The costs are licensing, labour and irreversibility. Labels, limits, sync properties, the custom report builder, the Create associations action and workflow copying need Professional or Enterprise. The catalog counts fields that sync data between records among calculated properties, 40 on Professional and 200 on Enterprise. Each conversion needs a mapping, an import and a pass through every asset using the old property, and a fact once read from one record may then need a second data source in a report. Internal names cannot be edited for properties, custom objects or association labels, and archived properties are deleted after 90 days.
The case is strongest where several teams report from one portal, where the count of products, partners or contacts per record varies, and where automation must reach the right associated record. It is weakest where reporting runs in a warehouse that can join on a cleaned text key, although HubSpot's workflows and segments cannot, and in a single-team portal whose owner knows which report each antipattern breaks. The firm is a HubSpot Solutions Partner and is paid for configuration of this kind; the report tests and placement rules cost no software and apply in any CRM.
Limits of the Evidence and of This Catalogue
The catalogue covers how facts are placed among objects, properties and associations. Pipelines and stages, lifecycle stages, duplicate records and permissions are outside it, and are set out in bid pipeline stages, lead status vs lifecycle stage, duplicate management and field-level permissions. HubSpot behaviour is as documented in October 2026, and the linked pages are authoritative as the platform changes.
The eleven are classified by where the defect sits, an analytical choice rather than a survey finding, and the sample demonstrates arithmetic, not magnitude. The report-test finding holds wherever reports run in HubSpot, and the entity-relationship model, written for databases, applies here by analogy. HubSpot does not document how its data quality tools detect a duplicate property, or which edits are blocked on properties in use, so a flagged pair is compared on sample records and a conversion is tried on one property first.
In Summary
CRM data model antipatterns in HubSpot are decisions about where a fact sits: in an object, a property or an association. Three documented reporting rules decide the result: a grouping reads one property, sums and averages read number fields, and a second object joins a report only through an association. Under them each of the eleven gives several reports, two answers or no answer, and no clean-up of values corrects them.
Correction costs Professional or Enterprise features and mapping work, and it creates internal names that cannot be edited later; its case is strongest where several teams report from one portal. On the sample portal the 123 structural properties carried every failed report test, and correction left each test with one report.
The partner conversion there was measured in spellings rather than deals, 43 mapping decisions for 89 unmatched deals, so the distinct values in each text property's record export size a conversion before it starts.