Netflix Archaius with Spring Cloud: Dynamic Config Management
Master Netflix Archaius with Spring Cloud for dynamic configuration management.
20+ years shipping production Java in banking & fintech. Everything here is grounded in real deployments.
- ✓Java 17+
- ✓Spring Boot 3.x
- ✓Spring Cloud 2023.x
- ✓Basic understanding of Spring Cloud Config and microservices architecture
- Archaius provides dynamic, real-time configuration changes without restarting your application.
- Integrates seamlessly with Spring Cloud's @RefreshScope and ConfigurationProperties for hot reloads.
- Supports cascading configurations from multiple sources (files, databases, cloud) with priority ordering.
- Use Archaius's concurrent polling and callback mechanisms to react to config changes instantly.
- Avoid common pitfalls like thread safety issues and stale caches by leveraging Archaius's built-in listeners.
Imagine your application is like a car's dashboard. Normally, changing a setting like the speed limit would require pulling over and restarting the engine. Archaius is like a mechanic who can swap out the speedometer dial while you're still driving—no stops, no restarts. It lets you change configuration values on the fly, and your app instantly adapts.
I've been building microservices since the early Netflix stack days, and let me tell you: dynamic configuration management is one of those things that separates a resilient production system from a house of cards. You can't afford to restart your services every time you need to tweak a rate limit, toggle a feature, or adjust a database connection pool. That's where Netflix Archaius comes in.
Archaius is the configuration library behind Netflix's own microservices. It's battle-tested at massive scale, handling millions of configuration changes per day without a hiccup. When combined with Spring Cloud, you get a powerful dynamic configuration system that supports cascading property sources, real-time updates, and fine-grained control over your application's behavior.
But here's the hard truth: most teams misuse Archaius. They treat it like a static properties file reader, missing out on its dynamic capabilities. They don't configure polling intervals properly, ignore thread safety, or fail to handle configuration change events. I've seen production outages caused by stale configurations that should have been updated dynamically.
In this guide, I'll show you how to properly integrate Netflix Archaius with Spring Cloud, share war stories from real production systems, and point out the gotchas that the official documentation glosses over. By the end, you'll be able to build services that adapt to configuration changes in real time, without restarts.
Why Archaius? The Case for Dynamic Configuration
Let's face it: static configuration files are a relic. In a world of microservices, where you might have hundreds of instances running, restarting each one to change a single property is not just inefficient—it's dangerous. I've seen teams deploy a new version just to change a database connection pool size, only to introduce a regression that took down their entire stack.
Archaius solves this by providing a dynamic configuration framework that can poll multiple sources (files, URLs, databases, cloud stores) and update properties at runtime. It's built on top of Apache Commons Configuration but adds Netflix's production-hardened features like cascading property sources, callbacks, and metrics.
When you combine Archaius with Spring Cloud, you get the best of both worlds: Spring's familiar @ConfigurationProperties and @Value annotations, plus Archaius's dynamic polling and event-driven updates. But—and this is a big but—you need to use Archaius correctly. The default Spring Cloud integration uses Archaius as a property source, but it doesn't automatically make all @Value fields dynamic. You have to opt in.
Here's the rule of thumb: if a configuration value can change without a code deploy, it should be a DynamicProperty. Don't use static @Value for anything that might need to change in production. Trust me, you'll thank me later when you're toggling feature flags at 3 AM without a deployment.
Setting Up Archaius with Spring Cloud
Adding Archaius to your Spring Cloud project is straightforward—just add the dependency. But the devil is in the details. Here's the minimal setup you need.
First, add the Spring Cloud Netflix Archaius starter to your pom.xml:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-archaius</artifactId> </dependency>
This pulls in Archaius and automatically configures it as a property source for Spring's Environment. Now you can use @Value or @ConfigurationProperties, and they will resolve from Archaius's dynamic configuration.
But here's the catch: Archaius initializes its configuration from the default configuration sources (like config.properties on the classpath) during startup. If you want to use a custom source—like a URL or a database—you need to configure that before Spring's context loads. I recommend using a Spring Factories or a custom ApplicationContextInitializer to set up your configuration sources early.
Another critical aspect is the polling interval. By default, Archaius polls file-based sources every 60 seconds. That's fine for most cases, but if you need faster updates, you can set archaius.configurationSource.defaultPollingInterval in your bootstrap.properties. I usually set it to 5 seconds for critical properties.
Finally, remember that Archaius's dynamic properties are not automatically injected into Spring beans. You have to explicitly use DynamicPropertyFactory or inject the Archaius Configuration object. But you can also use Spring's @RefreshScope to make beans refresh when properties change—though this only works if the property is accessed via Spring's Environment, not directly via Archaius.
Dynamic Properties in Practice: Callbacks and Listeners
The real power of Archaius lies in its callback mechanism. When a property changes, you can trigger arbitrary code—like resizing a thread pool, invalidating a cache, or re-establishing a connection. This is what makes your application truly adaptive.
To register a callback, use the addCallback method on any DynamicProperty. You can also use the @ArchaiusPropertyChangeListener annotation if you're using Spring, but I prefer explicit callbacks for clarity.
One pattern I've used in production is a configuration-driven circuit breaker. Instead of hardcoding thresholds, we used DynamicIntProperty for the failure count and timeout. When those values changed, a callback would reconfigure the circuit breaker without any downtime.
Another common use case is feature toggles. You can have a DynamicBooleanProperty that controls whether a new feature is enabled. When you flip the toggle, the callback can start routing traffic to the new code path.
But beware: callbacks run on the polling thread. If your callback does something slow (like a database call), it will block the polling and delay other property updates. Keep callbacks fast and asynchronous if needed.
Also, note that callbacks are not triggered for the initial value—only for changes. So if you need to initialize something based on the property, do that separately.
Cascading Configuration Sources: Priority and Overrides
One of Archaius's killer features is its ability to cascade configuration from multiple sources with a well-defined priority order. This allows you to have a base configuration (e.g., from a JAR file), environment-specific overrides (e.g., from a local file), and dynamic overrides (e.g., from a database or cloud).
By default, Archaius uses the following order (highest priority first): 1. Properties set via System properties 2. Properties from the command line 3. Properties from the application's configuration file (config.properties) 4. Properties from default configuration files (default.properties)
But you can add custom sources with any priority. For example, you might have a source that reads from a database table, and you want it to override everything except system properties. You can set the priority when adding the source.
Here's the trick: Spring Cloud's property sources (like application.yml) are added as a separate source with a default priority. If you want your Archaius dynamic properties to override Spring's static ones, you need to ensure Archaius sources have higher priority. This is controlled by the order in which they are added.
In practice, I always add my dynamic sources last (so they have the highest priority) after Spring's property sources have been loaded. This ensures that runtime overrides take precedence.
Another gotcha: Archaius caches the resolved value of a property. If you have multiple sources with the same key, the first one that defines it wins (based on priority). Changing the value in a lower-priority source will not override a higher-priority source until the higher-priority source is removed or updated.
What the Official Docs Won't Tell You
After years of using Archaius in production, here are the gotchas that the official documentation glosses over.
- Archaius and Spring Cloud Config Server interaction: When you use both, Archaius can conflict with Spring Cloud Config's property sources. The typical symptom is that changes made on the Config Server are not reflected in your application. The fix is to ensure that Archaius's polling is configured to use the Config Server's endpoint as a source, and that the polling interval is set appropriately. Also, disable Spring Cloud Config's automatic refresh if you're relying on Archaius for dynamic updates.
- Thread safety of DynamicProperty: While DynamicProperty itself is thread-safe, the values it returns are snapshots. If you call
get()multiple times, you may get different values if the property changed between calls. This can lead to subtle bugs if you're not careful. For example, if you read a property, then use it in a condition, the value might change mid-execution. I recommend reading the property once and storing it in a local variable if you need consistency within a block. - DynamicProperty vs @Value in Spring: If you annotate a field with @Value and the property is dynamic, Spring will inject the value at startup, but it won't update automatically. To get updates, you need to use @RefreshScope on the bean. However, @RefreshScope destroys and recreates the bean, which can be expensive. For high-frequency changes, use DynamicProperty directly.
- Polling interval and performance: Setting a very low polling interval (e.g., 1 second) can cause high CPU usage if you have many properties. Archaius polls all sources on each cycle, so if you have multiple sources, each poll is a separate operation. Use a reasonable interval (5-10 seconds) and consider push-based sources like ZooKeeper for sub-second updates.
- ConfigurationManager.install() is global: If you call
ConfigurationManager.install()in multiple places, the last call wins. This can cause issues in modular applications where different modules try to install their own configurations. Use ConcurrentCompositeConfiguration to merge sources instead.
Integration with Spring Cloud Config Server
Many teams use Spring Cloud Config Server as their central configuration store. Can you use Archaius with it? Yes, but it's not plug-and-play. The official Spring Cloud integration already makes Config Server properties available via Spring's Environment, so you might wonder why you need Archaius. The answer: Archaius gives you dynamic polling and callbacks that are more robust than Spring's @RefreshScope.
To integrate, you need to configure Archaius to poll the Config Server's endpoint. You can do this by setting up a URLConfigurationSource that points to the Config Server's REST API. But there's a catch: the Config Server returns properties in a JSON format that Archaius doesn't understand natively. You'll need to write a custom source that parses the JSON response.
Alternatively, you can use Spring Cloud Bus to broadcast configuration changes, and have Archaius listen for those events. This is more complex but avoids polling.
My recommendation: if you're already using Spring Cloud Config, don't add Archaius on top unless you have a specific need for its cascading sources or callback mechanism. The two can coexist, but you'll have to manage the overlap carefully.
One pattern I've used is to have Archaius as the primary configuration layer, with Config Server as one of its sources. This gives you the best of both worlds: centralized management via Config Server, and dynamic updates via Archaius.
The Stale Rate Limit That Brought Down Our Payment Gateway
- Always use Archaius's dynamic property types (DynamicStringProperty, DynamicIntProperty, etc.) for values that need to change at runtime.
- Verify that your configuration source is being polled correctly by checking Archaius's logs and metrics.
- Don't rely solely on @RefreshScope; it only works for Spring-managed beans, not static or eagerly initialized fields.
- Implement property change listeners to trigger side effects like cache invalidation or connection pool resizing.
- Test dynamic configuration changes in a staging environment with realistic traffic patterns before deploying to production.
curl -X POST http://localhost:8080/actuator/refreshtail -f /var/log/app/archaius.log | grep -i poll| File | Command / Code | Purpose |
|---|---|---|
| DynamicConfigExample.java | public class DynamicConfigExample { | Why Archaius? The Case for Dynamic Configuration |
| ArchaiusConfig.java | @Configuration | Setting Up Archaius with Spring Cloud |
| CallbackExample.java | public class ConnectionPoolManager { | Dynamic Properties in Practice |
| CascadingSourcesExample.java | public class CascadingSourcesExample { | Cascading Configuration Sources |
| ThreadSafetyExample.java | public class ThreadSafetyExample { | What the Official Docs Won't Tell You |
| ConfigServerSource.java | public class ConfigServerSource implements PolledConfigurationSource { | Integration with Spring Cloud Config Server |
Key takeaways
get() calls in the same method.Interview Questions on This Topic
Explain how Archaius handles configuration priority when multiple sources are configured.
Frequently Asked Questions
20+ years shipping production Java in banking & fintech. Everything here is grounded in real deployments.
That's Spring Cloud. Mark it forged?
6 min read · try the examples if you haven't