Why is code so hard to understand?
Why does your brain just not understand some code? Working memory only processes four chunks at a time, and good code respects this limit.

Code comprehensibility depends on how well written code fits into human working memory. The working memory only processes about four so-called chunks at a time, i.e. chunks of information from the long-term memory. Good naming, short method signatures and the avoidance of side effects reduce the number of active chunks and make code readable for all team members.
Key Takeaways
- The working memory can only process about four so-called chunks at a time, which is why a method call with object, method and two arguments already exhausts this limit.
- Chunks in long-term memory are not uniformly small units: A single chunk can activate many sub-information simultaneously, which is what makes abstraction so effective.
- Good naming means that the chosen term activates the same chunk in as many readers as possible, i.e. triggers similar associations to the author.
- State transitions in code overwhelm the brain, because although it can perceive state changes, it can only simulate them internally with difficulty, which cognitively favors functional programming without side effects.
- Pair programming synchronizes the chunk formation of two developers: What the navigator does not understand is a reliable signal that the code will also be difficult for others to read.
Comprehensible code is a question of the brain, not of taste
Whether code is readable is determined by how well a human brain can process it. This is exactly where Stefan Mandel and Peter Guntermann come in. Both work as software developers and are intensively involved with clean code. Instead of simply accepting the rules from Robert C. Martin’s book, they looked for the reasoning behind them: Why do these recommendations work at all?
Everyone in the team is familiar with the problem that gave rise to the idea. A junior writes a method with four arguments, an experienced colleague says you don’t do that, and when asked why, the best you get is a reference to a book. That only helps to a limited extent. Nobody can know a thousand books by heart, and some even contradict each other.
The better answer lies one level deeper. If you understand how the brain absorbs code, you can develop good practices yourself and explain them to others. Instead of “you don’t do that”, you can then say: your brain is overloaded, so reduce the information.
How working memory processes code
When reading code, the brain only processes a limited amount of information at the same time. Stefan and Peter differentiate between working memory and long-term memory. Working memory is the part that actively computes when you go through a line of code, and it is this part that is strictly limited.
The central unit here is called a chunk. A chunk is a lump of information that is stored in long-term memory. Every word in the code, every variable, method or class name is mapped to such a chunk. Anyone who has learned a programming language carries chunks for its grammar with them and can simulate the code internally.
The working memory can only process about four chunks at a time. Psychology speaks of four plus minus one. It becomes really difficult from the fifth element onwards. The limit is reached at the fourth, everything below that is easy.
A typical line of code therefore remains easily manageable. An assignment consists of an object, a method and an argument. There are three chunks involved, the result only comes out at the end and does not take up any space beforehand. The working memory processes three chunks without difficulty.
Experience does not expand capacity, chunks do
More experience does not make the working memory bigger, it makes the individual chunks more powerful. The four-chunk limit applies to everyone. The difference is how much is behind a single chunk.
The size of a chunk is not uniform. In computer science, this comes closest to the concept of abstraction. Anyone who knows design patterns and hears the word “observer” immediately has an idea of the underlying concept without having to go through every detail individually.
The brain works differently to a computer. It doesn’t just calculate symbolically on the abstraction. The detail chunks under an abstraction fire simultaneously. Four pieces of information at the same time, but each one can contain a lot of sub-information. This allows significantly more information to be processed in one step.
Code is communication, not a monologue
Code is a form of communication, and the receiver needs the same chunks as the sender. You have a requirement, pour it into a feature and write code. Someone else reads it later, and that someone is often you, just weeks later.
A term like “observer” only helps if the other person knows it. If you use a chunk that the other person does not have, you are communicating into the void. Comprehensible code is created when the chunks on both sides are similarly networked and associated with the same things.
This has a practical consequence for teamwork. You are not writing for your own, perhaps abstruse idea, but for your team members. Computer science therefore involves a lot of communication work long before a line is compiled.
Why speaking names often miss the mark
Good naming means that as many people as possible understand the same thing by a term. Naming is considered one of the most difficult problems in computer science, and for good reason. A name has to hit the right chunk in the reader’s mind.
However, speaking names are often misunderstood. Some believe that they should no longer use short identifiers. This is not true. An ‘x’ for the x-coordinate is a convention, nobody has to write ‘x-coordinate’. You can assume a certain cleverness on the part of the reader.
The opposite mistake is just as damaging. If you don’t summarize a concept in one word, you sometimes put a whole sentence in the variable name. Each word component is processed as a chunk. If the name is too long, you’ll end up forgetting what you started with. Brevity and conciseness beat a detailed description.
Long comments do not solve the problem. A long comment before a variable strains the brain because you have to read it carefully in advance. A good comment is better than nothing. However, if the meaning can already be determined in the name, this is the better choice.
How many arguments a method can take
The widespread recommendation of around two arguments per method results directly from the four-chunk limit. When you call a method, you don’t just process the arguments. You also keep in mind which method is being called and on which object.
This means that with two arguments, there are already four chunks in play: the object, the method and the two arguments. A third argument makes five, and then you lose readers who can no longer cope with five.
There is a way out. An abstraction that combines two parameters in a meaningful way reduces the number of chunks again. The price for this is general validity. If you deliberately want to keep a method variable, you cannot invent a new abstraction for every call and must leave the arguments as equally valid chunks next to each other.
State and side effects overwhelm the brain
Side effects are difficult to understand because the brain has difficulty mapping state transitions internally. If a method counts up a counter in the background, you also have to keep this state in mind while you follow the actual process.
Functional programmers advise against side effects for precisely this reason. A chunk cannot be rewritten as quickly as you like. If you reassign a variable, it suddenly has a different value and the old association no longer applies.
The brain is very well designed to perceive changes of state, but not to reproduce them internally.
- Stefan Mandel
The same logic explains why high cyclomatic complexity is exhausting. You have to carry every condition that has led you to a code location in your head. At some point, your working memory is full of branches, you suppress information and the results become inaccurate.
Metrics filter the unimportant, but do not replace judgment
Software quality metrics are a useful but insufficient indicator of comprehensibility. They are neither sufficient nor necessary. Sometimes a metric can simply be tricked.
The common metrics are basically compatible with the chunk model. High cyclomatic complexity indicates a certain probability of unreadable code. However, there is complex code that is nevertheless easy to read, and there is unreadable code whose problem lies elsewhere.
Naming, for example, defies all metrics. No technology can assess whether the right thing is assumed behind a name. Metrics do the legwork for you and filter out the obviously unimportant. With naming, however, every check can be overridden.
How to synchronize chunks in the team
Shared chunks are created through shared experience, and the most important way to do this is to simply talk to each other. Chunks are created in the brain when you perceive events. People who share the same events develop similar ideas.
Several practices aim to do just that:
- Automate code formatting. A formatter ensures that the presentation doesn’t add to the reader’s workload.
- **Let variables live for a short time: A variable that exists for an unnecessarily long time has to be cached in your head the whole time. This overburdens you and others.
- **Avoid abbreviations Three-letter abbreviations are a classic. If they don’t contribute to understanding, leave them out.
- **Use pair programming **If a driver has a weird idea of what a good chunk is, the navigator will notice immediately. Both create the same chunk at the same time, and this synchronous consolidation ensures a shared understanding.
A pattern reveals the weak point. Anyone who can no longer read their own code after two weeks has only created a chunk once when writing it and never used it again. Stefan calls this ad hoc chunking: plausible at the time, but not solidified because it is worthless. If the navigator finds something difficult to understand, others will feel the same way. Then it’s worth sharpening up the code.
What AI assistants contribute to readability
AI assistants such as Copilot help with comprehension, but tend to overproduce. If you talk, you can also babble, and an assistant will quickly overwhelm you with suggestions. On the other hand, you can ask if you don’t understand something and get an explanation.
A self-experiment shows the current limits. When asked to make an example more readable, the tool reliably lengthened the names, inflated the method names to several words and always put four lines of documentation in front of them.
The real joke was in the details. A method called “difference of squares” was supposed to calculate x² - y², but the result was (x - y) * (x + y). Mathematically equivalent, but unreadable as a justification for the name. The direct notation would have been less performant, but easier to understand.
AI tools provide such explanations mechanically, not thoughtfully. However, they are immediately suitable for another task: explaining a regular expression where a human would like to get off.
Frequently Asked Questions
When writing clean code, clear names should be used for variables and functions. Avoid complex, nested structures that make the code difficult to read. Keep functions short and concise, and ensure that each function has a single task. Unnecessary comments can be misleading; write self-explanatory code instead. Finally, reduce the number of dependencies and use consistent formatting to create readable and maintainable structures.
To ensure that the code complies with the clean code principles, the following steps should be observed: Use meaningful names for variables and functions to make the code readable. Keep functions short and focused so that they fulfill a clear task. Comment only when necessary and avoid redundant information. Write automated tests to ensure functionality and maintainability. Carry out regular code reviews to check quality and compliance with clean code principles.
The best examples of clean code demonstrate clear structure, readability and maintainability. These include: well-named variables and functions that fulfill a precise task; the use of comments to explain complex logic; and the use of formatting and indentation to improve clarity. The code should also be modular to promote reusability. Clean code minimizes errors and facilitates future adaptations.
Clean code significantly improves software development by increasing the readability and maintainability of the code. This makes it easier for new team members to understand and reduces the susceptibility to errors. In addition, clean code promotes the reusability of components and accelerates development through clear structures. Teams can work together more efficiently and implement changes more quickly. Ultimately, clean code leads to higher software quality and less technical debt, which saves time and costs in the long term.
The most important clean code principles are: Readability, simplicity, modularity and testability. Write clearly named functions that fulfill a single task. Keep the code free of superfluous comments and use descriptive variable names instead. Divide the code into small, reusable components and ensure that each part is independently testable. Regular refactoring improves the structure. These principles make the code more maintainable and easier to understand, which increases the quality of the software and improves team collaboration.
Clean code focuses on the spelling and structure of the code to make it readable and maintainable. Clean architecture, on the other hand, is an architectural pattern that organizes the software in layers to ensure independence from frameworks, UI and databases. While clean code promotes good programming practices, clean architecture aims to optimize the structure of the entire application. Both concepts complement each other, but are different in their area of application.
Clean code refers to source code that is easy to read, maintain and efficiently structured. It follows clear rules and principles that make it easier for developers to make changes and extensions. Important features are understandable identifiers, a clear structure and comprehensive comments that make the code comprehensible. Clean code helps to minimize errors and improve team collaboration, as everyone involved can quickly understand the code. An investment in clean code pays off in the long term, as it increases productivity and improves software quality.
Related Posts

Richard Seidl
•Jun 2, 2026
Patient agility: Is agile working dying?

Richard Seidl
•May 26, 2026