How should an enterprise software startup design custom fields for enterprise customers?
Enterprise customers ask to add their own fields. A good design decides when to say yes, caps how many, covers every surface and retires a field before deleting it.
Illustrative situation: a startup sells vendor-onboarding software to a food manufacturer with 3,000 employees. In the last procurement call, the customer’s operations lead asks, “Can we add our own fields? We track a cost center, a contract tier and an audit date.” The startup says yes to close the deal and ships five free-text boxes named “Custom 1” to “Custom 5” within a week. Six months later three admins have named the same thing “Cost center,” “CC” and “Cost centre.” Imports put dates in three formats, the table cannot sort the audit date, the nightly export has a column called custom_3, and nobody dares delete anything. The scene is invented. It shows the mistake this guide helps avoid: custom fields treated as a checkbox on a feature list instead of a small data model.
Humbleteam, a digital product design agency, publishes this guide. It covers when to say yes, field types and validation, who may create a field, limits and names, where a field has to appear, how to change or delete one safely and what it costs your product. A decision table and an invented worked example come with it. Product behavior is described as of November 10, 2026 and can change. This is not engineering or legal advice: your engineers and your customers’ data teams decide what your data model can carry.
When should you say yes to a custom field?
Say yes when the customer wants to record something in their own vocabulary and your product only has to store it, show it and filter by it. Stripe’s metadata is extra information you store on an object for your own use and, apart from Radar rules, Stripe does not use it to authorize or decline a charge.
Our suggestion, three questions per request:
- Is the value the customer’s own label, such as a cost center, a region code or an internal owner?
- Will your product ignore it when it decides things like billing, permissions or approvals?
- Can you cap how many of them one customer may add?
Three yeses mean a custom field. A no on question 2 means the customer needs a real feature. A field named “Approval limit” that your approval rules secretly read is a bug waiting for someone to rename it.
Which field types and validation should you offer?
Start with fewer types than the big tools. Jira’s admin documentation lists many types, from checkboxes and select lists to formulas, and short text there is limited to 255 characters. HubSpot’s field type reference shows what each type drags along: single-line text up to 65,536 characters in the CRM, a dropdown capped at 5,000 options, and a URL type that refuses values that are not valid URLs. The same page notes that some types, such as calculations and rich text, cannot be used in forms.
Our starting set: short text, long text, number, date, single select, multi-select, checkbox and person. Add a type only when two customers ask for it. Validation is the other half. Decide per type whether it is required, its length limit, a number range, a date format and, for selects, who can add options.
Each field also becomes a label on a form. WCAG success criterion 3.3.2 (Level A) says labels or instructions are provided when content requires user input. So the create form should ask for a label, an optional help line and a length limit on the label. Forty characters is our suggestion.
Who should be allowed to create one?
The big tools restrict it. In Airtable, only collaborators with Owner or Creator access can add, delete, rename or customize fields. In Zendesk, only administrators or agents with a custom role permission can update ticket fields. HubSpot requires permission to edit property settings.
Our suggestion: a separate “manage fields” permission, not tied to full admin. Regular users fill fields and can send a “request a field” note to someone who holds that permission. Our guide to roles and permissions covers how to build that split.
How should you cap and name fields?
Each tool has a ceiling. Jira allows 700 fields per space, a value Atlassian defines and admins cannot change. At the limit, Jira blocks adding more and leaves existing configuration working. HubSpot says the number of custom properties per object depends on the subscription and gives admins a Limits tab to see usage. Stripe allows 50 key-value pairs, with keys up to 40 characters and values up to 500.
Our rules: show the cap on the screen (“4 of 25 used”), count retired fields until they are deleted, and warn at 80%. Keep two names per field. HubSpot lets you rename a label but not a property’s internal name. That is the right split, because the API name must stay stable while the label changes. Check duplicates case-insensitively and suggest the existing field before an admin creates a second “Cost center.”
Where does a field have to show up?
A field is not finished when the form saves it. Every surface needs its own decision, and every field becomes a possible column and filter, so see our guide to data tables, filters and saved views for what a saved view stores.
| Surface | Decide | Failure if skipped |
|---|---|---|
| Create and edit forms | Which roles see it, required or optional | A required field blocks people who cannot fill it |
| Record page | Position, group, help text | Fields appear in creation order, so nobody finds anything |
| Table and filters | Which types can be a column or a filter | A text field cannot sort a date; a filter lists every raw value |
| Import | Mapping and format check before the run | Jira’s CSV import can hide limited-context custom fields at the mapping step, so admins need a workaround |
| Export | Label or API name in the header | A column called custom_3 |
| API and webhooks | Stable key, type, visibility | Stripe includes metadata in webhook events but returns it only for secret-key requests, not client-side ones |
| Related records | Does the value copy to a child record? | Stripe’s metadata does not automatically copy to related objects apart from a few listed cases, so a value can be missing downstream |
| Reports | Group by it, or not | A report quietly ignores a field nobody told it about |
The import, API and related-record rows come from the sources. The other rows are our reading.
How do you change or delete a field without breaking data?
Changing a type is where fields lose data. In Jira, once a field exists you cannot change its type. HubSpot warns that a type change can invalidate current values. Airtable converts what it can, and converting a text field to an attachment field clears the text. The same page says deleting a field breaks every dependency that referenced it, while a type change keeps them.
Deleting needs a step before it. Zendesk makes you deactivate a field first, and a deleted field and its data cannot be recovered. Jira tags a deleted field for deletion in 60 days, removes it from automations and apps that use it, and returns the data on restore.
Our suggestions: lock the type once a record holds a value, and offer a “retire” state that hides the field everywhere but keeps its data. Delete only after a retire period of 30 days, and show what depends on the field (views, filters, API clients, automations) with a count. Offer an export of the field’s values first.
What does it cost the product?
It costs more than the form. Atlassian warns that too many custom fields can compromise the performance of Jira. It names narrowing each field’s context to where it is needed as the ideal fix, and notes that new fields are added to all field configurations automatically. Our reading: default a new field to the one record type it was created on.
Every type also multiplies work in the table, import, export, API, reports and support. That is why the type list should stay short.
Illustrative worked example: Fennimore and Brindlecross Foods
Everything here is invented. Fennimore is a fictional startup that sells vendor-onboarding software. Brindlecross Foods is a fictional customer with 3,000 employees.
The operations lead asks for three fields, and two more requests arrive in the following weeks. Fennimore applies its three questions to each:
- Cost center: yes. A single select fed from a list of 120 cost centers, filterable.
- Contract tier: yes. A single select with four options.
- Audit date: yes. A date field, required for suppliers marked “regulated.”
- Internal notes: yes, as long text. It is not filterable or exportable by default.
- Risk score calculated from other fields: no. The product would have to run logic on it. Fennimore puts it on the roadmap as a real feature.
That is 4 of 25 allowed fields used. The admin imports 1,800 supplier records. The preview checks the audit date before the run and flags 60 rows with unreadable dates. The import loads the other 1,740 and offers the 60 as a downloadable fix list.
Later, finance retires 8 cost centers. Those 8 options become “retired.” Of the records, 41 still hold one, so the options stay visible with a “retired” label until someone reassigns those records. Fennimore deletes an option only when it holds zero records.
Where do these defaults stop working?
The numbers above are ours: 25 fields, a warning at 80%, a 30-day retire period, a 40-character label and the starting type set. No source we read gives a right number, and vendors differ widely. Limits also change: Atlassian says it began enforcing its limits in March 2026. We read vendor documentation and tested no product. We could not open Salesforce’s pages, so it is not covered. If a customer needs hundreds of fields per record or values calculated from other fields, custom fields are the wrong tool, and a separate data feature or a data export is the better answer.
What can you produce now?
Five outputs, before the next customer asks for their own fields:
- A yes-or-no rule: three questions and who answers them.
- A type list with a validation row for each type.
- A permission and cap spec: who creates, how many, what the screen shows.
- The surface table above, filled in for your product.
- A retire-and-delete flow with the dependency list.
