[object Object]

You opened a ticket to add one more dropdown and Freshdesk said no. Welcome to the field cap. The Pro plan ships with a finite custom field budget per ticket form, and once you blow through it the only way out is renegotiation, consolidation, or a painful migration. This is the guide I wish I had before approving the seventh “just one more field” request.

What actually counts against the cap

Every custom ticket field counts. Default fields (subject, type, status, priority, group, agent, source) do not. Dependent fields count as separate fields per level — a country / state / city cascade is three fields, not one. Nested custom fields inside child tickets count against the same parent form pool if you share forms. Section-driven fields (the conditional ones that only appear when, say, Type = Bug) still count even when hidden — visibility is rendering logic, not schema.

Check the live count from admin, not memory. The API tells the truth faster:

curl -s -u "$FRESHDESK_KEY:X" \
  https://acme.freshdesk.com/api/v2/admin/ticket_fields \
  | jq '[.[] | select(.default == false)] | length'

If that number is within five of your plan limit, stop reading and start consolidating. You are one merger away from a crisis.

The “one field per question” trap

The natural admin instinct is to add a dedicated field for every business question: Customer Tier, Renewal Quarter, CSM Owner, Region, Product Line, Subscription SKU, Onboarding Stage. Six fields, six dropdowns, six places where data drifts. The fix is to ask which fields actually drive automation versus which are read-only context that could live on the contact or company record.

Anything purely descriptive about the requester belongs on the contact or company, not the ticket. Freshdesk surfaces contact fields in the ticket sidebar already. You free up ticket schema and stop synchronising the same value across thousands of rows.

Consolidation patterns that survive audits

Pattern one: encode multiple low-cardinality dimensions into a single composite dropdown. Instead of Region and Tier as two fields, build one Segment field with values EMEA-Enterprise, EMEA-SMB, APAC-Enterprise. You lose individual reporting axes — get them back with a custom report that splits on the delimiter.

Pattern two: replace mutable workflow state with tags. Onboarding Stage swings through seven values across a ticket lifetime. That is a state machine, not a category. Tags handle it fine, are unlimited, and the dispatcher already filters on them. See freshdesk-dispatcher-rules for how to keep tag-driven routing predictable.

Pattern three: store rarely-queried structured data in a single multi-line text field as JSON. Yes, really. If Custom Asset Specs is read by one report a quarter and never automated, a JSON blob is a perfectly reasonable shape. Reserve real fields for things that drive routing, SLA, or daily filtering.

Field-cap audit script

Run this monthly and post the output to the admin Slack channel. It catches creep before it becomes a fire.

import fetch from 'node-fetch';

const DOMAIN = process.env.FD_DOMAIN;
const KEY = process.env.FD_KEY;
const auth = 'Basic ' + Buffer.from(`${KEY}:X`).toString('base64');

const res = await fetch(`https://${DOMAIN}.freshdesk.com/api/v2/admin/ticket_fields`, {
  headers: { Authorization: auth }
});
const fields = await res.json();

const custom = fields.filter(f => !f.default);
const byType = custom.reduce((acc, f) => {
  acc[f.type] = (acc[f.type] || 0) + 1;
  return acc;
}, {});

console.log(`Total custom fields: ${custom.length}`);
console.log('By type:', byType);
console.log('Unused (no choices populated):',
  custom.filter(f => f.choices && Object.keys(f.choices).length === 0).map(f => f.label));

The “unused” check catches ghost fields — created during a discovery workshop, never populated, still consuming a slot.

Section-driven forms versus separate forms

Freshdesk lets you build either one mega-form with Type-driven sections or multiple forms (one per request type, available on higher plans). Mega-form keeps schema small but forces agents to scroll. Multi-form is cleaner UX but each form has its own field budget on some plans — check yours before splitting.

Rule of thumb: split forms when two request types share fewer than 40% of their fields. Below that threshold the shared schema is mostly accidental and a split form pays off in clarity and budget headroom. Above it, sections inside one form are saner.

Dependent fields: the silent budget killer

A three-level dependent cascade (Product → Module → Feature) looks like one logical field on the form. It is three fields against your quota. If you have several of these — common in ITSM-style support — you can burn half your budget on dropdowns that exist solely so the second box filters correctly.

Two escapes. First: collapse low-cardinality cascades. If Module only has three values per Product, just label them in a single flat dropdown (SalesCloud — Reports, SalesCloud — Forecasts). Second: move deep hierarchies into a custom object or external lookup field. The Freshworks Neo platform supports custom objects for exactly this, and they do not count against the ticket field budget.

Migration moves when you have already lost

If you are already at cap and the business wants three more fields, your options are:

  1. Upgrade the plan — fastest, but you pay annually for a problem that might be solvable.
  2. Retire fields by usage data. Pull last 90 days of tickets, count non-null occurrences per custom field, retire anything under 2%.
  3. Merge sibling fields into one composite, then run a one-time backfill script to copy the legacy values forward.

Option two is almost always available — admins systematically overestimate which fields matter. Retire with prejudice.

curl -s -u "$FRESHDESK_KEY:X" \
  "https://acme.freshdesk.com/api/v2/tickets?updated_since=2026-02-14&per_page=100" \
  | jq '[.[] | .custom_fields] | add | to_entries
        | map({field: .key, populated: (.value | if . == null then 0 else 1 end)})
        | group_by(.field)
        | map({field: .[0].field, count: ([.[].populated] | add)})'

Cross-reference that count against your total ticket volume and the dead fields are obvious.

What to do before the next acquisition

Acquisitions blow up Freshdesk schemas because the acquired team has their own custom field list and the merge always adds, never subtracts. Pre-empt it. Document which fields are load-bearing for automation, dispatcher, and SLA versus which are reporting-only. When the integration call happens, you have a defensible “these are the 12 we cannot lose” list and the rest are negotiable.

Also: build the audit script into a weekly cron with a Slack notification when count crosses 80% of cap. The pain of discovering the cap during an executive demand is much worse than the pain of a Tuesday morning Slack ping.

Bottom line

Ticket field budgets are real, hostile, and easier to defend before they bite. Audit monthly, retire ruthlessly, push descriptive data onto contacts and companies, and never let a “just one more field” request through without a kill-list of three older ones. The forms that survive five years of growth are the ones whose admins treat schema like a scarce resource from day one.

[object Object]
Share