Skip to content
Ironflow is pre-1.0: APIs can change between releases. Pin a version. What is ready →

Config Patterns

While both use NATS JetStream under the hood, they solve different problems.

FeatureConfig ManagementKV Store
ModelJSON Documents (Objects).Individual Keys (Raw).
ScopingAutomatic per Environment.Manual per Bucket.
UpdatesFull set or shallow patch.put, create, or update.
Best ForFeature flags, App settings.Caching, sessions, counters.

Store all your flags in a single JSON document. This allows your frontend or workers to load all active flags in a single network request.

import { createClient } from "@ironflow/node";
const ironflow = createClient({ apiKey: process.env.IRONFLOW_API_KEY });
const config = ironflow.config();
// 1. Define the flags
await config.set("flags", {
"new-onboarding": true,
"promo-banner": false,
"max-items": 10
});
// 2. Patch one flag without affecting others
await config.patch("flags", { "promo-banner": true });

Centralize your server-side constants (timeouts, URLs, thresholds). Your workers can fetch these at startup or watch for changes to update their behavior without a restart.

const settings = await config.get("worker-settings");
if (settings.data.maintenanceMode) {
process.exit(0); // Graceful pause
}
settings = client.config_get("worker-settings")
if settings["data"].get("maintenanceMode"):
sys.exit(0) # Graceful pause

Subscribe to a document and react to every change without a restart. Watch is available in the Node, Browser, Go and Python SDKs and is delivered over WebSocket.

const watcher = config.watch("worker-settings", {
onUpdate: (event) => {
applyRuntimeConfig(event.data);
},
onError: (err) => console.error("config watch error:", err),
});
// Later — stop watching during graceful shutdown
watcher.stop();
watcher, err := client.Config().Watch(ctx, "worker-settings", ironflow.ConfigWatchCallbacks{
OnUpdate: func(event ironflow.ConfigWatchEvent) {
applyRuntimeConfig(event.Data) // nil after the config is deleted
},
OnError: func(err error) { log.Println("config watch error:", err) },
})
if err != nil {
log.Fatal(err)
}
// Later — stop watching during graceful shutdown
defer watcher.Stop()
# Needs the watch extra: pip install 'ironflow-py[watch]'
from contextlib import aclosing
async with aclosing(client.watch_config("worker-settings")) as events:
async for event in events:
apply_runtime_config(event.data)
# Leaving the block stops watching. A watch error raises IronflowError.

Use list() to enumerate every config document in the current environment, and delete() to remove a stale one.

const docs = await config.list();
for (const doc of docs) {
console.log(doc.name);
}
await config.delete("legacy-flags");
for doc in client.config_list()["configs"]:
print(doc["name"])
client.config_delete("legacy-flags")

  1. Environment Scoping is Automatic: The server derives the environment from the API Key on the request. An X-Ironflow-Environment-ID header (the Go ClientConfig.Environment option sends one) that names another environment returns 403. Use a different API Key per environment to target dev / staging / production.
  2. Shallow Merge: Prefer patch() over set() for runtime updates to prevent accidentally overwriting keys set by other team members or processes. patch() also creates the document if it does not yet exist.
  3. Validation: Perform schema validation in your application logic after calling get(), as the Config Store accepts any valid JSON.