Feature flags in Java: how to enable features without restarting the application

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Feature flags in Java: how to enable features without restarting the application

\n\n

Imagine: you spent a week working on a new feature — a feedback form with magical autocomplete. You merged it, deployed it to production. And then — a bug. Users can't send a message. You have to urgently revert the commit, rebuild the JAR, restart the server. Everyone hates this moment.

\n\n

But what if you could simply press a "disable" button right in the admin panel, without touching the code? Or enable the feature for only 10% of users to test the load? Or run an A/B test where half sees the new design and half sees the old one?

\n\n

All of this is the magic of feature flags (also known as feature toggles). In this article, we'll break down how to implement them in Java — from a primitive Enum to industrial solutions like Togglz and LaunchDarkly. Let's go!

\n\n

What is a feature flag and why do you need it?

\n\n

A feature flag (or feature toggle) is a conditional switch in the code that allows you to enable or disable functionality without changing the source code and redeploying the application.

\n\n

Sounds like a trivial if? But the power lies in management. You store the state of flags in a config, database, or external service. Change the value — the feature turns on or off instantly.

\n\n

Why is this needed in Java projects?

\n\n
    \n
  • Trunk-based development — merge unfinished features into main, hiding them behind a flag. Colleagues won't see the bugs, and you can finish them calmly.
  • \n
  • Canary releases — enable the feature for 5% of users, check metrics, then for 50%, then for everyone.
  • \n
  • Kill switch — if a feature fails in production, you simply turn it off with one button.
  • \n
  • A/B testing — compare user behavior with and without the feature.
  • \n
  • Personalization — enable premium features only for paying customers.
  • \n
\n\n

The main risk is technical debt. If you don't remove old flags, the code turns into a web of if-else statements. We'll talk about this too.

\n\n

The simplest way: Enum + Properties

\n\n

Let's start with a basic approach. We create an enumeration of flags and read them from application.properties.

\n\n
public enum FeatureFlag {\n    NEW_CHECKOUT_FLOW,\n    AI_RECOMMENDATIONS,\n    DARK_MODE\n}
\n\n

Load the flags into a service:

\n\n
@Component\npublic class FeatureFlagService {\n\n    private final Map<FeatureFlag, Boolean> flags = new HashMap<>();\n\n    public FeatureFlagService(@Value("${features.new-checkout-flow:false}") boolean newCheckout,\n                              @Value("${features.ai-recommendations:false}") boolean aiRec,\n                              @Value("${features.dark-mode:false}") boolean darkMode) {\n        flags.put(FeatureFlag.NEW_CHECKOUT_FLOW, newCheckout);\n        flags.put(FeatureFlag.AI_RECOMMENDATIONS, aiRec);\n        flags.put(FeatureFlag.DARK_MODE, darkMode);\n    }\n\n    public boolean isEnabled(FeatureFlag flag) {\n        return flags.getOrDefault(flag, false);\n    }\n}
\n\n

Usage in code:

\n\n
if (featureFlagService.isEnabled(FeatureFlag.NEW_CHECKOUT_FLOW)) {\n    // new checkout flow\n} else {\n    // old flow\n}
\n\n

Pros: simplicity, no extra dependencies. Cons: to change a value, you need to restart the application. This isn't exactly "without restarting," but for small projects it's fine.

\n\n

Dynamic flags: database or Redis

\n\n

If you want to change flags on the fly — store them in a database or Redis. Let's create a table:

\n\n
CREATE TABLE feature_flags (\n    name VARCHAR(100) PRIMARY KEY,\n    enabled BOOLEAN NOT NULL DEFAULT FALSE,\n    updated_at TIMESTAMP\n);
\n\n

A service with caching (to avoid hitting the database on every request):

\n\n
@Service\npublic class DynamicFeatureFlagService {\n\n    private final JdbcTem                

Blogs

Book Recommendations