How Long Should a Function Be? Practical Limits and How to Split Long Methods

Ask ten developers how long a function should be and you get ten numbers. The number matters less than the reason behind it: a function should do one thing that you can name, read in one sitting, and test on its own. Here are practical limits, the warning signs, and a safe way to split long methods.

Video explainer (1:41) · Watch with transcript

Practical limits

  • Most functions in healthy codebases are short: often under 20 lines
  • Around 50 to 70 lines is where most teams and tools start warning
  • Past 100 lines, a function almost always does several jobs
  • Treat the limit as a prompt to look, not a hard rule; a long switch over a fixed set of cases can be fine

Signs a function does too much

  • You need comments like "// step 2: validate" to explain sections
  • The name has "and" in it, or is vague (Process, Handle, DoWork)
  • It has several levels of nesting
  • Changing one behaviour risks breaking another in the same function
  • Tests need a lot of setup because the function touches many dependencies

Before: one function, four jobs

async function placeOrder(cart, user) {
  if (!cart.items.length) throw new Error('Cart is empty');
  for (const item of cart.items) {
    if (item.qty <= 0) throw new Error('Bad quantity');
  }
  let total = 0;
  for (const item of cart.items) total += item.price * item.qty;
  if (user.isMember) total *= 0.9;
  const order = await db.orders.insert({ userId: user.id, items: cart.items, total });
  await mailer.send(user.email, 'Order confirmed', `Total: ${total}`);
  return order;
}

After: named steps

async function placeOrder(cart, user) {
  validateCart(cart);
  const total = priceCart(cart, user);
  const order = await saveOrder(cart, user, total);
  await sendConfirmation(user, total);
  return order;
}

How to split safely

  1. Make sure tests cover the current behaviour (add a few if they do not)
  2. Pick a block that does one thing and extract it into a function with a clear name
  3. Pass in only what the block needs and return its result
  4. Run the tests, commit, and repeat with the next block
  5. Use your IDE's Extract Method refactoring so variables are wired up for you

Find long functions across a repository

CodeInspector flags long methods in C# (CI0007) and long functions in JavaScript, TypeScript, Java, and C++, with the length and location of each. Scan a repository at https://codeinspector.app with 100 free credits.

Related