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.
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
- Make sure tests cover the current behaviour (add a few if they do not)
- Pick a block that does one thing and extract it into a function with a clear name
- Pass in only what the block needs and return its result
- Run the tests, commit, and repeat with the next block
- 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.