Skip to content

Menu design: the trade-off between options and abandonment

· Updated · ivrloom team

#five9 #ivr-design #routing

A main menu is a negotiation. Every option you add routes someone more precisely and makes everyone else wait longer to hear theirs.

Why long menus fail in a specific way

Callers do not weigh all your options and choose. They listen until something matches, then stop listening. Anything after the match is wasted, and anything before the match is friction.

That has two consequences worth designing around:

  • Order matters more than wording. The option that serves the most callers should be first, not the one that is most important to the business.
  • The tail is expensive. Option seven is heard by everyone who wanted options one through six, and chosen by almost nobody.

Structure beats brevity

The common advice is “keep it to four options”. That is a reasonable default, but the real constraint is depth of listening, not count. A menu of five short, distinct options is easier than three long overlapping ones.

Distinctness is the part people get wrong. “Billing” and “Account services” overlap in the caller’s head even if they are separate departments in yours. When two options sound like they might both be right, the caller either guesses or waits for a human — and a guess produces a misroute, which costs a transfer plus the caller’s patience.

Say the action, then the key

“For billing, press one” beats “Press one for billing”. Callers are listening for the thing they want; leading with the key number makes them hold a digit in memory while they wait to hear whether it applies.

What a Five9 menu actually stores

It helps to know what you are editing. In a .five9ivr export, a menu module carries its options in two separate places, and they are easy to confuse:

  • branches — one entry per option, keyed by the option’s name (“Sales”, “Support”, “Repeat”, “No Match”), each pointing at the module it routes to.
  • items — the keypad mapping. Each item pairs a digit (DTMF_1, DTMF_2, …) with the actionName of the branch it fires.

So “press 1 for Sales” is not one fact in the file. It is a branch called Sales, plus an item that says digit 1 means Sales. Reordering the keys is an edit to items; rerouting where Sales goes is an edit to branches. A tool that reads only one of the two will get half the menu wrong, which is exactly the bug we shipped and fixed when real exports first met our simulator.

Alongside those sit the retry settings. In the exports we have worked with, every menu had maxAttempts set to 3, noInputTimeout set to 5 or 10 seconds, and maxTimeToEnter matching it. The retry behaviour itself lives in two recoEvents blocks — one for NO_INPUT, one for NO_MATCH — each with an action. Across those exports the actions were overwhelmingly REPROMPT, with EXIT a distant second and CONTINUE rare. When the attempts run out, the call leaves through the module’s exceptionalDescendant: the menu’s error exit, which is a separate connection from any of the options.

Handle no input and wrong input differently

Those two recoEvents blocks exist because they are different problems:

  • No input usually means the caller is on speakerphone, driving, or did not realise a response was expected. Repeating the menu once is reasonable.
  • Wrong input means they pressed something you do not handle. Repeating the same menu unchanged tells them nothing new.

Two identical retries of an identical prompt is the pattern most likely to produce a hang-up. If the second attempt does not add information, it is just delay. A dedicated “No Match” branch — a real option in branches that plays a shorter “sorry, that is not a valid choice” and loops back — is how the better-built menus we have seen handle it, and it is also the branch that lets a simulator tell the two failures apart.

The zero-out question

Whether to offer an operator is a business decision, not a design one — but hiding it is rarely the win it appears to be. Callers who want a human and cannot find one press zero anyway, then press it repeatedly, then hang up and call back. The abandoned call still costs you; it just does not show up in the same report.

If you do offer zero, give it an item like any other digit. An unlisted zero lands in “No Match” and the caller hears the invalid-choice prompt for asking for a person.

Reviewing a menu you inherited

Open the flow and ask three questions of each option:

  1. How many callers does it actually serve?
  2. Could it be confused with another option?
  3. Where does it go — and is that still the right queue?

The third one catches the most problems. Menus are edited under deadline; destinations drift. A rewire is invisible in a prompt recording and obvious in a diff.

Then ask two questions of the menu as a whole:

  1. Where does the error exit go? Follow the exceptionalDescendant. In more than one production flow we have looked at it pointed at a bare hangup with no message — after three failed attempts the caller was simply disconnected.
  2. Do the items and the branches agree? An item whose actionName matches no branch is a key that does nothing, and two items on the same digit mean the second option can never be chosen — the caller’s key matches the first. The Issues panel’s “Unreachable duplicate option” warning catches a menu option defined twice under the same name; it does not compare digits, so both of these cases you still have to check by cross-referencing the two lists.

Corrected 2026-09-25: an earlier version said ivrloom flags two items on the same digit. The check compares option names, not digits.

Testing it without a phone

A menu is the easiest node in a flow to test structurally, because every outcome is determined by one digit. In ivrloom’s simulator you can walk it in step mode: at the menu, the debugger pauses and offers one button per keypad digit — “1 · Sales → ToSales”, “2 · Support → SupportHours” — plus “No input — caller stayed silent”. Press an unlisted digit on the keypad and you take the No Match branch; stay silent and you take the timeout path.

Save each of those as a scenario and the panel’s path coverage will tell you which menu exits no scenario has ever taken. For a main menu, the uncovered ones are almost always the error exit and No Match — the two paths real callers hit on a bad day and nobody dials on purpose. How the editor and simulator compare with the Five9 Script Designer is laid out in the side-by-side comparison.