← All posts

Why Bugspot Has No Custom Fields

Why we declined custom fields, the recurring pain they cause in trackers like Jira, and the adjacent pitfall — labels — we avoid for the same reason.

cover · hero-why-bugspot-has-no-custom-fields

The feature we’re choosing not to build

If you’ve used Jira for any length of time, you’ve seen what custom fields look like at scale. A fresh install starts with a handful of sensible fields — title, description, priority, assignee. A year later the same instance has forty-seven of them. “Customer Impact.” “Sprint Commitment Date.” “Release Train.” “Risk Tier.” “Validated By.” “Original Estimate (Adjusted).” Half of them are empty on most tickets. A quarter of them duplicate each other with slightly different names. The field picker in the UI has its own scrollbar.

Custom fields are the single most common feature request for issue trackers, and they’re the single most common vector for trackers turning into platforms. Bugspot doesn’t support them and isn’t planning to. This post explains why, and explains the one adjacent decision — how labels work — that determines whether the commitment actually holds.

The reasoning that usually gets given

The usual argument against custom fields is that they invite users to repurpose the tool. A team adds “Story Points (Adjusted)” because the original estimate stopped meaning anything. Then “T-Shirt Size” for the PM who doesn’t trust points. Then “RICE Score” and “ICE Score” because someone read a blog post. Then “Definition of Ready Checklist”, “Architecture Review Status”, “Stakeholder Sign-Off”, “Confidence Level (1–5)”, “Tech Debt Category”, “Quarterly OKR Alignment”. Each one sounded reasonable in the meeting where it got added. Most are empty on most tickets a year later, and the ones that aren’t empty contradict each other across teams in the same company.

This is true, but it’s incomplete. If the only problem were teams adding too many fields over time, the fix would be discipline — internal guardrails, periodic audits, an “are you sure?” dialog when an admin reaches for the forty-seventh one. You could enforce it through process rather than architecture. That’s not actually what goes wrong.

What custom fields actually cost users

It’s worth being specific about the texture of this, because the complaints that show up in every Jira-experienced engineer’s vent thread are remarkably consistent. They aren’t about abstract drift; they’re about a concrete set of recurring pains that compound the longer an instance has been customized.

  • Filing a ticket becomes a chore. You came to report something broken. The “create issue” dialog has thirty fields, ten of them required, most with names that mean nothing to you — Customer Impact Tier, Risk Class, Sprint Commitment Date, Validated By. You pick the first option in every dropdown to make the form go away. The ticket now exists with garbage data in ten fields, which becomes someone else’s problem later.
  • Every project is its own dialect. Two teams inside the same company end up with wildly different field sets, status workflows, and required-field rules. Crossing a team boundary inside your own company means relearning the tracker. Helping out on a sibling team’s ticket means asking what each unfamiliar field is for.
  • Reports are built on noise. The “tickets by severity” chart averages a column that’s mostly populated by people dismissing the form as fast as possible. Leadership reads it anyway, and decisions get made on top of it.
  • Search becomes a specialty. Writing a query that touches custom fields means knowing each project’s exact configuration. Within a year every team has The Person Who Writes The Queries, and “ask them” becomes the recommended path. The search UI exists; it just isn’t usable by anyone who hasn’t memorized the schema.
  • Onboarding is a tax. A new hire’s first weeks include learning which fields actually matter, which are vestigial, which are required-but-meaningless, and which silently break dashboards if you fill them in wrong. None of this is documented, because it changes every quarter.
  • Everything feels slower as fields accumulate. Open a ticket, wait. Run a search, wait. Save an edit, wait. Each field loads on every issue page, indexes on every search, and grows the database. Long-running instances develop a constant low-grade latency on routine actions, and it gets worse the longer the instance has been in use.
  • Nothing ever gets removed. Deprecating a field breaks saved filters, automations, and dashboards that depend on it, so fields accumulate. Most established instances have fields from initiatives that ended years ago, and nobody is brave enough to delete them.

Atlassian acknowledges this directly. Jira Cloud caps custom fields at roughly 700 per field configuration, because beyond that admin screens get sluggish and reindexing stretches into hours. The vendor’s own performance documentation flags too many fields with broad or global contexts as the leading cause of slow issue creation, search, and reindexing, and recommends scoping fields tightly to specific projects to mitigate it. There’s a recurring stream of vendor-published cleanup playbooks for long-running instances — and a whole category of consultants whose business is un-customizing Jira instances that have been customized into unusability.

None of this is a Jira-specific failure mode. It’s what happens to any product where the schema is open-ended and the cost of adding one more field is always lower than the cost of saying “no”.

The real reason: the direction of product design

The deeper problem with custom fields is that they invert the direction of product design.

Without custom fields, we decide what an Entry is. We ship a bounded universe of attributes — title, description, type, status, priority, severity, resolution, assignee, reporter, dates, labels, linked commits, linked pull requests — and each Entry type uses the subset that makes sense for it. An epic doesn’t carry a severity; a bug does. But every field that exists in any tenant’s instance is one we defined, not one a tenant added. Users adapt their process to this model — they figure out how to express their work using the attributes we’ve defined, and if something doesn’t fit, that’s a signal to rethink how they’re using the tool or what tool they use.

With custom fields, users decide what an Entry is. Every tenant ends up with a slightly different data model. One team’s Entries have a “Customer Impact” field, another’s have a “Security Severity” field, a third has twelve custom fields tracking obscure release-management details. The product can no longer assume anything about the shape of an Entry beyond a small core.

This inversion changes what it’s possible to build on top of the data model:

  • Reports. Every report has to account for fields that might or might not exist in a given tenant. “Top 10 bugs by severity” means one thing in one tenant and something different in another. Cross-tenant insights — benchmarks, usage patterns, industry comparisons — become impossible because the underlying schema isn’t comparable.
  • Filters and search. The filter UI has to dynamically surface whatever fields a tenant has configured. Search indexing has to handle unknown types. Saved filters break when fields get renamed or removed.
  • Integrations. Every integration — Slack notifications, CI hooks, webhooks, the CLI, AI agents — has to either ignore custom fields entirely (making the integration less useful) or handle them generically (making every integration more complex to build and more fragile to run).
  • The API contract. What does an Entry look like in the API? “It depends on the tenant” is a much worse answer than “here’s the schema.” The former makes every API consumer a per-tenant custom integration. The latter lets ecosystem tools work across instances.
  • Support. Every bug report starts with “well, in our instance we have these 47 custom fields…” The support team can’t reproduce issues without first understanding the tenant’s configuration. Root-cause analysis takes longer on every ticket.

None of these costs show up when you’re building the custom field feature itself. They compound over years, as the surface area of the product grows and every surface has to account for an unbounded schema.

The tradeoff we’re accepting

Some fraction of potential users will bounce off Bugspot because they need a field we don’t support. A team that genuinely needs to track “Customer Impact” per bug, or “Sprint Commitment Date” per story, or “Deployment Risk Tier” per release, will find Bugspot insufficient and go elsewhere.

That’s fine. It’s a feature of the product, not a bug.

Those users are the leading edge of the drift we’re specifically trying to avoid. The team that needs one custom field today needs three next quarter, and ten the quarter after that, and eventually needs a product that can model their process exactly — which is Jira, and Jira already exists. We’re not trying to compete with Jira on configurability. We’re offering something different: a tool with opinions about what an Entry is, so that everything we build on top of those Entries can be good.

The users we want are the ones who look at our fixed schema and think “that’s actually everything I need.” Software teams working on software, tracking work in terms of types, statuses, priorities, severities, resolutions, and links to the code that implements them. That’s the audience. Everyone else is someone else’s customer.

The trap: labels are soft custom fields

Here’s the thing that almost breaks this commitment, and the thing we’re being careful about.

If custom fields are off the table but labels are free-form, we’ve reintroduced custom fields through the back door.

Free-form labels — where any user can add any string as a label on any Entry — end up being used as custom fields. Teams encode structured data as label conventions. priority:customer-impact-high. team:platform. sprint:2024-Q2-3. risk:regulated. Within six months of adoption, a team using free-form labels has an unofficial schema expressed as label prefixes, and the benefits of a fixed schema are gone — except now the schema isn’t even visible in the data model, it’s hidden in a convention that’s only documented in Slack messages.

This is how good products drift in ways the designers didn’t intend. The feature (labels) seems small and harmless. The emergent use (labels-as-custom-fields) undoes a much bigger architectural commitment.

Our answer is that labels in Bugspot are admin-defined enums, not free-form strings. An admin configures the set of labels available in an instance. Users pick from that set. Labels can be added or deprecated over time, but the vocabulary is bounded and visible in the schema.

This is a small decision with outsized impact. It means:

  • The label set is discoverable. A new team member can see all available labels in one place.
  • Labels can have meaning. An admin-defined label means the same thing across every Entry it’s attached to — no ambiguity between bug and bugs and Bug.
  • The schema stays coherent. A fixed-schema product means something if the soft edges of the schema are also bounded.

Some teams will want free-form labels. They’ll argue that the admin-defined model is too rigid. They’re welcome to that opinion, and welcome to a different product. The commitment we’re making is that the schema stays coherent end-to-end, not just in the fields we’ve formally defined.

The broader pattern

This post is about custom fields specifically, but the pattern shows up everywhere in product design. Every feature has an obvious version and a subtle version. The obvious version is the feature you ship. The subtle version is the emergent behavior that shows up after users have been using the feature for a while.

For custom fields, the obvious version is “let users add fields.” The subtle version is “the schema becomes whatever tenants configure, and every downstream feature has to accommodate that.”

For labels, the obvious version is “let users tag Entries.” The subtle version is “teams encode custom schemas as label conventions, and the schema you thought was fixed is actually not.”

The discipline of building a focused product is recognizing the subtle version before shipping the obvious one. Custom fields and free-form labels are close cousins — they’re both “let users add arbitrary metadata.” Declining one and allowing the other would be incoherent. We decline both.

Fixed schema, configurable process. That’s the line, and it holds only if we hold it all the way through.

#product-design#issue-tracking#schema-design#jira#opinionated-software