Why You Should Never Use Magic Numbers — Create Constants for Better Readability
How Replacing Hardcoded Values with Meaningful Constants Leads to Cleaner, Maintainable, and Less Error-Prone Code"
Hello guys, as a senior engineer and tech lead, one of the most common code smells I see during code reviews is the presence of magic numbers—hardcoded numeric values that appear in code without context or explanation.
They might seem harmless in small scripts or POCs, but in production-grade systems—especially low-latency or mission-critical software—they become a liability.
Let’s dive into why magic numbers are problematic, how replacing them with named constants improves your code, and the best practices you should follow.
Btw, this is the 6th article in my writing better code series and if you haven’t read the earlier article, I highly recommend you to read them all to learn small, tried and tested coding tips which can create big impact when applied regularly.
Here is list of all the tips I have shared before:
The feedback has been awesome so far and many of you replied me back that you love these kind of practical tips. I will try to find more and share with you guys, if you haven’t subscribed yet, consider subscribing so that you can get them right in your email box.
What Are Magic Numbers?
A magic number is a literal value used directly in code without explanation. For example:
What does 0.07
represent?
Why is it 7%
?
Is it configurable?
Is it a default?
Who maintains it?
This makes the code unclear to new developers and even to your future self.
😱 Problems With Magic Numbers
Lack of context
You don’t know what the number represents unless you check documentation or comments.Duplication and inconsistency
If the same number is used in multiple places, updating it becomes risky if not centralized.Hard to debug or test
You can't easily change or mock values for testing if they are hardcoded.Reduced readability and maintainability
Magic numbers obscure the intent of the code and slow down code reviews.
Better: Use Named Constants
Let’s refactor the earlier example using constants (public static final variables in Java):
Now, the intent is clear. DEFAULT_INTEREST_RATE
explains what 0.07
means and makes it easy to change in one place.
This is better but still its not a good practice to keep data in code because if you keep your data in code then every time data changes like default interest rate changes you need to build and do a new release which won’t be easy.
Instead, you can keep your data outside like in a file or a database where you can easily change them without any code change or release.
Before vs After Example
Now, let’s see one more example in before and after style to understand how bad magic number can be and how using constant can make your code more readable and maintainable.
Before (Magic Numbers)
In this example, we're using magic numbers like 30
, 100
, and 0
directly in the code. This reduces readability, makes maintenance harder, and increases the risk of inconsistent behavior across the codebase.
After (Named Constants)
Much clearer, right? This way, constants also serve as self-documenting code.
Best Practices for Using Constants
Use
private static final
for constants in JavaScope it as narrowly as possible.
Keep it immutable.
Group related constants together
Either as inner classes, enums, or utility classes like
Constants.java
.
Use meaningful names
Prefer
SECONDS_IN_A_DAY
overSECONDS_PER_DAY
orS_DAY
.
Don't overdo it
You don’t need to extract every single number like
1
or0
unless they have business meaning.
Document business logic
Especially when constants come from external sources (e.g., config, compliance rules).
For Low Latency Systems
In high-performance systems, magic numbers can hurt more than readability:
If a numeric constant is tied to tuning (e.g., batch size, timeout, buffer size), it needs to be tweakable and traceable.
Constants can be annotated or tied to config to dynamically update without redeploy.
Profiling and benchmarking become easier when constants are centrally defined. It’s actually a known practice to keep your constant in a single file and access it everywhere.
🤖 How CodeRabbit Helps Catch Magic Numbers
CodeRabbit, an AI code review tool integrated with GitHub PRs, is excellent at detecting magic numbers and other anti-patterns automatically.
Here's how it helps:
✅ Static analysis with context: CodeRabbit flags hardcoded numbers and suggests converting them into named constants, especially when the same number appears in multiple places.
✅ Inline PR comments: As soon as someone pushes a PR with magic numbers, CodeRabbit drops a comment suggesting improvements.
✅ Custom rules support: You can configure CodeRabbit to be stricter in certain modules, like critical systems or domain logic.
✅ Promotes consistency: If your team uses constants in some places and magic numbers in others, CodeRabbit can enforce consistent coding style across the board.
Example CodeRabbit Suggestion:
"Consider replacing '1000' with a named constant like
MAX_TIMEOUT_MS
to improve readability and maintainability."
Conclusion
That’s all in this article about why developer should not use magic numbers in code. Using constants instead of magic numbers is a small habit with big long-term payoffs. It makes your code more readable, testable, and maintainable—and it’s a low-effort win for code quality.
As a tech lead, I always recommend enforcing this via code reviews or static analysis tools like SonarQube or Checkstyle and nowadays using PR review tools like CodeRabbi.
Your future teammates—and your future self—will thank you.
Other tech articles you may like
I claim to my students they don't use magical numbers even with the switch statements:
```java
switch(aVariable) {
case A_CONSTANT: ...
// more cases
}
```
The body of the setVolume method can be simplified with this one-line expression:
return Math.max(MIN_VOLUME, Math.min(level, MAX_VOLUME));
Nevertheless, sometimes it is preferable to write several lines (by including if , else if and else as you did) when the inline expression becomes a bit confused.
This is an opinionated refactoring.
Nice post! Thanks again, @JavinPaul and Soma!