Qodana
The code quality platform for teams
What Developers Really Mean by “Bad Code”

The phrase “bad code” gets thrown around in reviews and online forums all the time. But what does it actually mean? It’s a good example of the vague terms that occasionally make the rounds in developer circles without much to qualify them.
We’ve collected opinions on the subject, metrics, and code risks that you can use to discuss what “bad” quality is for your team and how to improve it.
What is bad code?
Bad code is a general term that developers, project managers, and other stakeholders use as a catch-all for a range of coding problems – bugs, smells, security issues – that contribute to low readability, maintainability, and scalability. It doesn’t just refer to codebases that have issues or don’t work like they’re supposed to.
In different cases, bad code refers to anything not optimized for performance and maintenance, from confusing variable names to functions that loop using too much memory.
Your code could be described as bad if it’s:
- Difficult for other people to understand during code reviews.
- Hard to maintain or scale over time.
- Not written with correct styling and formatting.
- Not well documented.
- Prone to bugs and breaking.
- Insecure or vulnerable to breaches.
We’ll get into each of these points in more depth, but it’s important to acknowledge that no codebase is perfect. There will be times when license incompatibilities take priority over style changes or security vulnerabilities trump other issues. The definition of bad code is contextual and changes depending on its surroundings. That said, there are some general red flags that can signal bad code. Let’s look at some of the most important ones.
Hard to read or understand
Whether someone is peer reviewing your code or making changes, they have to know what everything means. Using variable names like x1, yz, or data can make your codebase hard to decipher. Likewise, a file called xyzService, which uses mixed indentation styles and has all of its work inside a 500-line function called doStuff, is hard to read and challenging to work with.
Difficult to maintain
When code is hard to understand, it’s also hard to maintain. For example, if you have one function that handles web requests, database logic, and data formatting, any tiny change to the code risks breaking it. Additionally, poorly written legacy codebases can lead to high technical debt when code needs to be refactored as a direct result of shortcuts in the original work.
Hard to scale
Good code should be adaptable and able to grow functionally, handling more traffic or data without impacting performance. Hard-to-scale code can be bad code, as it leads to performance issues over time and can cause longer maintenance processes.
Insecure or vulnerable
Simple errors and issues with your code can lead to vulnerabilities and create the potential for breaches. Insecure code can be caused by issues such as inserting user input directly into an SQL query without sanitizing it. In this case, a malicious user could expose all user data with a simple input. At Qodana, we strongly emphasize security alongside code quality because unsafe code is bad code, especially in the context of the AI boom.
Prone to bugs and breaking
If your code doesn’t consider potential issues, it may be bad code. Any codebase that doesn’t account for invalid user inputs, loops, arrays, or other possible issues could cause problems when it inevitably breaks, especially if it does so after “hiding” for some time.
Low performance or inefficiency
Performance problems make code bad, like a for loop that makes a database call for every single item in it. This can increase the time it takes a page to load or even cause timeouts. A study from the University of Washington showed the impact of inefficient database queries. The study found that fixing these types of issues led to a 98% decrease in webpage response time.
Not aligned with ways of working
When code doesn’t follow accepted workflows and style regulations, it forces your teammates to slow down, unpack differences, and guess the intent, even if it works. This can lead to significant technical debt. Examples include choosing to use horizontal or vertical indents, having defined line lengths, or figuring out early what your approach will be for using variables.

Defining bad code is good practice
Defining bad code vs. good code drives quality and efficiency in your output. It makes sure code is fit-for-purpose, helps teams collaborate more easily, lowers technical debt, and leads to the development of performance-led code designed for longevity and scalability.
It’s important that everyone working on a project knows what bad code looks like in their specific case. What might be considered bad code in one project could be considered fine in another. Being able to draw the line between the two makes expectations clearer and allows developers to better understand what bad code is. Our Leadership Series features an interview with Vlad Minaev, WebStorm Team Lead, that explores this topic.
Having defined parameters for bad code also helps developers understand what to avoid when they have to be more agile. For example, if there are time constraints to consider, what should they be sure to steer clear of to keep code quality high?
The impact of bad code
We spoke a little bit about how bad code can affect your ability to scale your products, maintain your codebase and preserve your team’s sanity. But let’s look at how bad code can have significant implications for your business in more detail:
- Lowering scalability: Unoptimized loops or blocking calls that seem okay during testing can crash your system when user traffic increases. What worked before launch suddenly doesn’t when you need it the most.
- Technical debt: Bad code makes it difficult and more expensive to correct issues or make future changes to the codebase. One study carried out in 2022 found that fixing technical debt issues consumes as much as 25% of development time.
- Breaching user trust: Bad code directly affects users. For example, a bug that exposes personal data or crashes during checkout can undo months of good customer acquisition work. Users remember bad experiences much more than good ones.
- Losing talent: Retaining good developer talent can also relate directly to the quality of your codebase. Top engineers don’t want to work on codebases filled with issues, where every file reveals a new layer of problems.
- Damaging productivity: Bad code wastes valuable time and impacts productivity, whether it’s causing developers to spend longer deciphering code or spending more time updating and maintaining trickier code. QA cycles may also get longer due to complexity, while fixes get more complex and time-consuming in the long run.
How to reduce bad code
There are plenty of ways to reduce bad code in your codebase, including:
- Understand the task: Don’t start coding straight away. Step back, ask questions, and ensure you fully understand the brief. Writing a problem summary will also help lay out expected inputs, outputs, and constraints and turn abstract concepts into real targets.
- Choose the simple option: A clever algorithm that saves time today could cost time tomorrow. If you can’t explain your code in under a minute, rewrite it with collaboration in mind.
- Don’t repeat yourself (DRY): Avoid duplicate code. When you duplicate lines of code, you duplicate bugs and other problems, which can lead to time-consuming fixes required in multiple areas. Follow the rule of three – if you have to write similar code more than twice, turn it into a reusable function.
- Write small, focused functions: Ensure your functions do what’s intended and don’t creep too much. Small sections of code are easier to understand and test. Keep functions under 30 lines, each doing one job.
- Use meaningful names: Names in your codebase need to be usable. As they’re what people read most often, you should always ensure names for things like variables, functions, and any other identifiers make it clear what they are and what their purpose is to anyone reading your code.
- Test regularly: Implement tests that check overall behaviour and targeted tests for critical algorithms. Regular testing allows you to refactor without fear because you know that when you break something, you can go back to the previous version.
- Use static code analysis tools and peer reviews: Static code analysis tools check for issues in your code, like unused variables, unreachable branches, or security risks. Combine these checks with peer reviews for a tighter review system where everyone shares responsibility for code quality.
- Style guides and governance: Agree on an internal style guide for your code and stick to it. Consistency allows developers to focus on what the code can do instead of how it looks.
- Prioritize security: Validate inputs, encode outputs, and handle secrets like API keys and passwords correctly by storing them securely using environment variables or secret-management tools. When reviewing code, look for injection attacks and race conditions.
- Document decisions: Grey areas cause bad code. Document the rationale behind approaches. Why did you choose optimistic locking over pessimistic? Why does the service process events asynchronously instead of synchronously?
- Refactor incrementally: Rebuilding from scratch can introduce new bugs, delaying production. Incremental refactoring processes like code cleanups, replacing legacy patterns, and optimizing slow database queries are often less disruptive, while also making it easier to spot coding problems along the way.

Bad code is a problem that can lead to costly problems for development teams, projects, and wider businesses. Removing the vagueness from the terminology and knowing what bad code looks like can help you catch problems earlier, make it easier to fix issues, and lower the impact of bad code on your bottom line.
Spot bad code issues in your codebase with the Qodana code quality tool.