[{"data":1,"prerenderedAt":718},["ShallowReactive",2],{"navigation_docs":3,"-monitoring-lifecycle":244,"-monitoring-lifecycle-surround":713},[4,51,78,229],{"title":5,"icon":6,"modifiedAt":7,"path":8,"stem":9,"children":10,"page":6},"Getting Started",false,"2026-04-30T19:15:33.000Z","\u002Fgetting-started","1.getting-started",[11,16,21,26,31,36,41,46],{"title":12,"path":13,"stem":14,"icon":15},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F1.quickstart","i-lucide-fast-forward",{"title":17,"path":18,"stem":19,"icon":20},"Core Concepts","\u002Fgetting-started\u002Fcore-concepts","1.getting-started\u002F2.core-concepts","i-lucide-workflow",{"title":22,"path":23,"stem":24,"icon":25},"Configs Anatomy","\u002Fgetting-started\u002Fconfigs","1.getting-started\u002F3.configs","i-lucide-file-cog",{"title":27,"path":28,"stem":29,"icon":30},"Architecture","\u002Fgetting-started\u002Farchitecture","1.getting-started\u002F4.architecture","i-lucide-layers",{"title":32,"path":33,"stem":34,"icon":35},"JSON Schema Validation","\u002Fgetting-started\u002Fjson-schema-validation","1.getting-started\u002F5.json-schema-validation","i-lucide-braces",{"title":37,"path":38,"stem":39,"icon":40},"Testing Rules","\u002Fgetting-started\u002Ftesting-targeting-rules","1.getting-started\u002F6.testing-targeting-rules","i-lucide-flask-conical",{"title":42,"path":43,"stem":44,"icon":45},"Segments","\u002Fgetting-started\u002Fsegments","1.getting-started\u002F7.segments","i-lucide-squares-intersect",{"title":47,"path":48,"stem":49,"icon":50},"Pricing & Billing","\u002Fgetting-started\u002Fpricing-and-billing","1.getting-started\u002F8.pricing-and-billing","i-lucide-credit-card",{"title":52,"modifiedAt":53,"defaultOpen":54,"path":55,"stem":56,"children":57,"page":6},"Monitoring","2026-09-24T23:33:20.000Z",true,"\u002Fmonitoring","2.monitoring",[58,63,68,73],{"title":59,"path":60,"stem":61,"icon":62},"Activity","\u002Fmonitoring\u002Factivity","2.monitoring\u002F1.activity","i-lucide-activity",{"title":64,"path":65,"stem":66,"icon":67},"Lifecycle","\u002Fmonitoring\u002Flifecycle","2.monitoring\u002F2.lifecycle","i-lucide-recycle",{"title":69,"path":70,"stem":71,"icon":72},"Alerts","\u002Fmonitoring\u002Falerts","2.monitoring\u002F3.alerts","i-lucide-bell",{"title":74,"path":75,"stem":76,"icon":77},"Dynamic Detection","\u002Fmonitoring\u002Fdynamic-detection","2.monitoring\u002F4.dynamic-detection","i-lucide-hat-glasses",{"title":79,"modifiedAt":53,"defaultOpen":54,"path":80,"stem":81,"children":82,"page":6},"SDKs","\u002Fsdks","3.sdks",[83,88,109,134,150,181,224],{"title":84,"path":85,"stem":86,"icon":87},"Available SDKs","\u002Fsdks\u002Favailable-sdks","3.sdks\u002F1.available-sdks","i-lucide-list",{"title":89,"modifiedAt":53,"icon":90,"defaultOpen":6,"path":91,"stem":92,"children":93,"page":6},"Browser SDKs","i-lucide-monitor","\u002Fsdks\u002Fbrowser","3.sdks\u002F2.browser",[94,99,104],{"title":95,"path":96,"stem":97,"icon":98},"Javascript","\u002Fsdks\u002Fbrowser\u002Fjavascript","3.sdks\u002F2.browser\u002F1.javascript","cd-logos-javascript",{"title":100,"path":101,"stem":102,"icon":103},"React","\u002Fsdks\u002Fbrowser\u002Freact","3.sdks\u002F2.browser\u002F2.react","cd-logos-react-light",{"title":105,"path":106,"stem":107,"icon":108},"Vue","\u002Fsdks\u002Fbrowser\u002Fvue","3.sdks\u002F2.browser\u002F3.vue","cd-logos-vue",{"title":110,"modifiedAt":53,"icon":111,"defaultOpen":6,"path":112,"stem":113,"children":114,"page":6},"Mobile SDKs","i-lucide-smartphone","\u002Fsdks\u002Fmobile","3.sdks\u002F3.mobile",[115,119,124,129],{"title":116,"path":117,"stem":118,"icon":103},"React Native","\u002Fsdks\u002Fmobile\u002Freact-native","3.sdks\u002F3.mobile\u002F1.react-native",{"title":120,"path":121,"stem":122,"icon":123},"Flutter","\u002Fsdks\u002Fmobile\u002Fflutter","3.sdks\u002F3.mobile\u002F2.flutter","cd-logos-flutter",{"title":125,"path":126,"stem":127,"icon":128},"Swift","\u002Fsdks\u002Fmobile\u002Fswift","3.sdks\u002F3.mobile\u002F3.swift","cd-logos-swift",{"title":130,"path":131,"stem":132,"icon":133},"Android","\u002Fsdks\u002Fmobile\u002Fandroid","3.sdks\u002F3.mobile\u002F4.android","cd-logos-android",{"title":135,"modifiedAt":53,"icon":136,"defaultOpen":6,"path":137,"stem":138,"children":139,"page":6},"Meta-framework SDKs","i-lucide-monitor-smartphone","\u002Fsdks\u002Fmeta","3.sdks\u002F4.meta",[140,145],{"title":141,"path":142,"stem":143,"icon":144},"Next.js","\u002Fsdks\u002Fmeta\u002Fnextjs","3.sdks\u002F4.meta\u002F1.nextjs","cd-logos-nextjs",{"title":146,"path":147,"stem":148,"icon":149},"Nuxt","\u002Fsdks\u002Fmeta\u002Fnuxt","3.sdks\u002F4.meta\u002F2.nuxt","cd-logos-nuxt",{"title":151,"modifiedAt":53,"icon":152,"defaultOpen":6,"path":153,"stem":154,"children":155,"page":6},"Server SDKs","i-lucide-server","\u002Fsdks\u002Fserver","3.sdks\u002F5.server",[156,161,166,171,176],{"title":157,"path":158,"stem":159,"icon":160},"Node.js","\u002Fsdks\u002Fserver\u002Fnode-js","3.sdks\u002F5.server\u002F1.node-js","cd-logos-nodejs",{"title":162,"path":163,"stem":164,"icon":165},"Python","\u002Fsdks\u002Fserver\u002Fpython","3.sdks\u002F5.server\u002F2.python","cd-logos-python",{"title":167,"path":168,"stem":169,"icon":170},"Java","\u002Fsdks\u002Fserver\u002Fjava","3.sdks\u002F5.server\u002F3.java","cd-logos-java",{"title":172,"path":173,"stem":174,"icon":175},".NET","\u002Fsdks\u002Fserver\u002Fdotnet","3.sdks\u002F5.server\u002F4.dotnet","cd-logos-dotnet",{"title":177,"path":178,"stem":179,"icon":180},"Go","\u002Fsdks\u002Fserver\u002Fgo","3.sdks\u002F5.server\u002F5.go","cd-logos-go",{"title":182,"modifiedAt":53,"icon":183,"defaultOpen":6,"path":184,"stem":185,"children":186,"page":6},"OpenFeature Providers","cd-logos-openfeature","\u002Fsdks\u002Fopenfeature","3.sdks\u002F6.openfeature",[187,192,196,200,204,208,212,216,220],{"title":188,"path":189,"stem":190,"icon":183,"icons":191},"Web","\u002Fsdks\u002Fopenfeature\u002Fweb","3.sdks\u002F6.openfeature\u002F1.web",[183,98],{"title":125,"path":193,"stem":194,"icon":183,"icons":195},"\u002Fsdks\u002Fopenfeature\u002Fswift","3.sdks\u002F6.openfeature\u002F2.swift",[183,128],{"title":130,"path":197,"stem":198,"icon":183,"icons":199},"\u002Fsdks\u002Fopenfeature\u002Fandroid","3.sdks\u002F6.openfeature\u002F3.android",[183,133],{"title":120,"path":201,"stem":202,"icon":183,"icons":203},"\u002Fsdks\u002Fopenfeature\u002Fflutter","3.sdks\u002F6.openfeature\u002F4.flutter",[183,123],{"title":157,"path":205,"stem":206,"icon":183,"icons":207},"\u002Fsdks\u002Fopenfeature\u002Fnode-js","3.sdks\u002F6.openfeature\u002F5.node-js",[183,160],{"title":162,"path":209,"stem":210,"icon":183,"icons":211},"\u002Fsdks\u002Fopenfeature\u002Fpython","3.sdks\u002F6.openfeature\u002F6.python",[183,165],{"title":167,"path":213,"stem":214,"icon":183,"icons":215},"\u002Fsdks\u002Fopenfeature\u002Fjava","3.sdks\u002F6.openfeature\u002F7.java",[183,170],{"title":172,"path":217,"stem":218,"icon":183,"icons":219},"\u002Fsdks\u002Fopenfeature\u002Fdotnet","3.sdks\u002F6.openfeature\u002F8.dotnet",[183,175],{"title":177,"path":221,"stem":222,"icon":183,"icons":223},"\u002Fsdks\u002Fopenfeature\u002Fgo","3.sdks\u002F6.openfeature\u002F9.go",[183,180],{"title":225,"path":226,"stem":227,"icon":228},"Maven Repository","\u002Fsdks\u002Fmaven-repository","3.sdks\u002F7.maven-repository","i-lucide-package",{"title":230,"modifiedAt":53,"defaultOpen":54,"path":231,"stem":232,"children":233,"page":6},"Integrations","\u002Fintegrations","4.integrations",[234,239],{"title":235,"path":236,"stem":237,"icon":238},"Terraform","\u002Fintegrations\u002Fterraform","4.integrations\u002F1.terraform","cd-logos-terraform",{"title":240,"path":241,"stem":242,"icon":243},"MCP","\u002Fintegrations\u002Fmcp","4.integrations\u002F2.mcp","cd-logos-mcp",{"id":245,"title":246,"body":247,"description":704,"extension":705,"links":706,"meta":707,"navigation":709,"path":65,"seo":710,"stem":66,"__hash__":712},"docs\u002F2.monitoring\u002F2.lifecycle.md","Config Lifecycle",{"type":248,"value":249,"toc":689},"minimark",[250,254,262,267,284,309,324,331,335,417,448,464,468,473,476,479,482,486,489,492,538,541,563,570,573,581,585,596,606,617,624,630,634,662,666,674,681],[251,252,253],"p",{},"Feature flags are meant to be removed once the feature has shipped, and configs that nothing reads anymore are clutter that eventually misleads someone. ConfigDirector tracks a lifecycle state for every config from the evaluations your applications report, and tells you when a config has served its purpose.",[251,255,256,257,261],{},"The state is shown in the ",[258,259,260],"strong",{},"Status"," column of the configs list and on the config page. States are recalculated every 30 minutes.",[263,264,266],"h2",{"id":265},"the-lifetime-decides-the-lifecycle","The lifetime decides the lifecycle",[251,268,269,270,275,276,279,280,283],{},"Every config has a ",[271,272,274],"a",{"href":273},"\u002Fgetting-started\u002Fconfigs#lifetime","lifetime",": ",[258,277,278],{},"Temporary"," or ",[258,281,282],{},"Permanent",". The lifetime is the single most important input to the lifecycle, because it tells ConfigDirector whether \"this config is no longer needed\" is a conclusion it is allowed to draw.",[285,286,287,303],"ul",{},[288,289,290,291,294,295,298,299,302],"li",{},"A ",[258,292,293],{},"temporary"," config is expected to be removed one day. Feature flags and experiments default to temporary. ConfigDirector tracks temporary configs for cleanup: it detects when they have ",[258,296,297],{},"settled"," and when they are ",[258,300,301],{},"ready to archive",", and raises the two lifecycle alerts.",[288,304,290,305,308],{},[258,306,307],{},"permanent"," config is expected to stay. Kill switches and plain configs default to permanent. A permanent config that has not been read for a while is not unused, it is waiting, so ConfigDirector never marks it settled or ready to archive, and never suggests removing it.",[251,310,311,312,315,316,319,320,323],{},"Both lifetimes share the states that describe plain usage: ",[258,313,314],{},"New",", ",[258,317,318],{},"In use",", and ",[258,321,322],{},"Stale",".",[251,325,326,327,330],{},"You can change the lifetime at any time from the config's ",[258,328,329],{},"Settings"," tab. Switching a flag that has become a long-term toggle to permanent takes it out of cleanup tracking; switching a config to temporary puts it in.",[263,332,334],{"id":333},"states","States",[336,337,338,354],"table",{},[339,340,341],"thead",{},[342,343,344,348,351],"tr",{},[345,346,347],"th",{},"State",[345,349,350],{},"Applies to",[345,352,353],{},"Meaning",[355,356,357,370,381,392,405],"tbody",{},[342,358,359,364,367],{},[360,361,362],"td",{},[258,363,314],{},[360,365,366],{},"All configs",[360,368,369],{},"The config was created and has not been evaluated in any environment yet.",[342,371,372,376,378],{},[360,373,374],{},[258,375,318],{},[360,377,366],{},[360,379,380],{},"The config has been evaluated in at least one environment and has not gone quiet.",[342,382,383,387,389],{},[360,384,385],{},[258,386,322],{},[360,388,366],{},[360,390,391],{},"The config was created more than 15 days ago and has never been evaluated.",[342,393,394,399,402],{},[360,395,396],{},[258,397,398],{},"Settled",[360,400,401],{},"Temporary only",[360,403,404],{},"The config has served a single value in every live environment long enough that it can be hardcoded and removed.",[342,406,407,412,414],{},[360,408,409],{},[258,410,411],{},"Archive Ready",[360,413,401],{},[360,415,416],{},"The config was in use and its live environments have not evaluated it for its quiet window, which is sized from how often it is usually evaluated.",[251,418,419,420,279,422,424,425,427,428,430,431,435,436,438,439,442,443,424,445,447],{},"States transition on their own, and there is no manual reset. A ",[258,421,314],{},[258,423,322],{}," config returns to ",[258,426,318],{}," as soon as an SDK evaluates it again, and so does an ",[258,429,411],{}," config evaluated in a ",[271,432,434],{"href":433},"\u002Fgetting-started\u002Fcore-concepts#environments","live environment",". An evaluation in another environment brings an ",[258,437,411],{}," config back only when it has no recent real use to judge by, or when an application in that environment is clearly still evaluating it regularly (see ",[271,440,411],{"href":441},"#archive-ready-temporary-configs","). A ",[258,444,398],{},[258,446,318],{}," at the next check once it no longer meets the conditions below.",[251,449,450,451,315,453,455,456,458,459,279,461,463],{},"A permanent config therefore only ever shows ",[258,452,314],{},[258,454,318],{},", or ",[258,457,322],{},". If you expect to see ",[258,460,398],{},[258,462,411],{}," on a config and never do, check its lifetime first.",[263,465,467],{"id":466},"how-each-state-is-decided","How each state is decided",[469,470,472],"h3",{"id":471},"in-use","In Use",[251,474,475],{},"A config is in use from the moment any environment receives an evaluation for it. Evaluations that fell back to the in-code default value count too: the application is still asking for the config. A temporary config leaves this state when it settles or becomes ready to archive; a permanent config stays in use.",[469,477,322],{"id":478},"stale",[251,480,481],{},"A config that is more than 15 days old and has never been evaluated is stale, whatever its lifetime. It was created and then never wired into an application, or the application that was going to use it never shipped. The state exists so these configs do not blend in with the ones that are simply new.",[469,483,485],{"id":484},"settled-temporary-configs","Settled (temporary configs)",[251,487,488],{},"A settled config is one whose job is done: in your live environments, the feature flag has been on for everyone for a while, or the config has returned the same value to every application for long enough that it might as well live in the code.",[251,490,491],{},"The horizon depends on the role:",[336,493,494,504],{},[339,495,496],{},[342,497,498,501],{},[345,499,500],{},"Role",[345,502,503],{},"Horizon",[355,505,506,514,522,530],{},[342,507,508,511],{},[360,509,510],{},"Feature flag",[360,512,513],{},"7 days",[342,515,516,519],{},[360,517,518],{},"Experiment",[360,520,521],{},"14 days",[342,523,524,527],{},[360,525,526],{},"Config",[360,528,529],{},"30 days",[342,531,532,535],{},[360,533,534],{},"Kill switch",[360,536,537],{},"Never settles",[251,539,540],{},"A temporary config settles when, over the whole horizon and in every live environment that has recent activity:",[285,542,543,546,552,555],{},[288,544,545],{},"Every evaluation served the same value. Evaluations that fell back to the in-code default value are tolerated as long as they are no more than 20% of the total.",[288,547,548,549,551],{},"The config was already being evaluated in at least one of those environments when the horizon began, and it is still being evaluated: its latest evaluation is more recent than the config's quiet window (see ",[271,550,411],{"href":441},"), or than the horizon when that is shorter.",[288,553,554],{},"The current targeting rules in every one of those environments can only serve that value. A rule or percentage split that could still return a different value to someone, even if nobody matched it during the horizon, means the config is not done yet.",[288,556,557,558,562],{},"For feature flags and boolean configs, the value is ",[559,560,561],"code",{},"true",". A flag that has been off in every live environment for a week has not shipped, it has been abandoned, and that is a cleanup decision for you rather than a settled verdict.",[251,564,565,566,569],{},"Only live environments count: those with ",[258,567,568],{},"Live environment"," turned on in their settings. A staging environment without it that still serves the old value does not hold the config back, and a config in a project without a live environment never settles.",[251,571,572],{},"Kill switches are excluded even when they are temporary, because serving the same value for a long time is exactly what a kill switch is supposed to do.",[251,574,575,576,580],{},"When a config settles, the config page shows the value to hardcode with a copy button, and a ",[271,577,579],{"href":578},"\u002Fmonitoring\u002Falerts#config-settled","Config settled alert"," is raised.",[469,582,584],{"id":583},"archive-ready-temporary-configs","Archive Ready (temporary configs)",[251,586,587,588,279,590,592,593,595],{},"A temporary config that was ",[258,589,318],{},[258,591,398],{}," and then receives no evaluations in its live environments for its quiet window becomes ",[258,594,411],{},". This is the usual end of a feature flag: the code that read it was removed, the SDKs stopped asking, and the config can go.",[251,597,598,599,602,603,605],{},"The question is whether real traffic still reads the config, so the decision looks at the ",[271,600,601],{"href":433},"live environments",", the same ones that decide ",[258,604,398],{},". A developer trying the flag now and then in a test environment neither keeps it in use nor stretches its quiet window. A config with no recent live use at all, because it was never released or its project has no live environment, is judged on whichever environments do evaluate it, so it is not marked ready to archive just for never having gone live. And an application in any environment that still evaluates the config every working day, such as a nightly job in staging, keeps it in use: the code that reads the flag is clearly still there.",[251,607,608,609,611,612,614,615,323],{},"Each config has its own quiet window, sized from how often it is usually evaluated in the environments that count, so a config that applications read all day goes quiet within a few days, while one read by a weekly job is given longer. Once a temporary config has been evaluated, hover its status in the configs list to see how long its quiet window is. ",[271,610,74],{"href":75}," explains how the window is sized and how long it can be. The check runs every 30 minutes, and an ",[258,613,411],{}," config whose evaluations turn out to be more recent than its quiet window, or that an application evaluates every working day, returns to ",[258,616,318],{},[251,618,290,619,623],{},[271,620,622],{"href":621},"\u002Fmonitoring\u002Falerts#config-ready-to-archive","Config ready to archive alert"," is raised when a config enters this state.",[251,625,626,627,629],{},"A permanent config that stops being evaluated simply stays ",[258,628,318],{}," and shows no recent evaluations in the configs list; it is never marked for archival. If you want cleanup tracking for it, change its lifetime to temporary.",[263,631,633],{"id":632},"what-to-do-in-each-state","What to do in each state",[285,635,636,644,652,657],{},[288,637,638,640,641,643],{},[258,639,398],{},": hardcode the settled value in your applications, deploy, wait for the state to move to ",[258,642,411],{},", then archive. If the flag is going to be turned back off again, it is not temporary: change its lifetime to permanent.",[288,645,646,648,649,651],{},[258,647,411],{},": archive the config from the ",[258,650,329],{}," tab of the config page. The confirmation dialog shows the config's quiet window and when it was last evaluated in each environment.",[288,653,654,656],{},[258,655,322],{},": either wire it into the application or archive it.",[288,658,659,661],{},[258,660,318],{}," for a long time with a temporary lifetime: consider whether the flag has become permanent in practice, and if so change its lifetime so it stops being tracked for cleanup.",[263,663,665],{"id":664},"archiving","Archiving",[251,667,668,669,673],{},"Archiving removes the config from the project and from the SDK payloads. An SDK that still asks for an archived config receives its in-code default value and raises a ",[271,670,672],{"href":671},"\u002Fmonitoring\u002Falerts#config-not-found","Config not found alert",", which is how you find out if the cleanup ran ahead of a deployment.",[251,675,676,677,680],{},"Archived configs are listed under ",[258,678,679],{},"View archived configs"," for 30 days and can be restored from there with their targeting rules intact. After 30 days they are purged.",[682,683,684,685,323],"note",{},"Renaming a config key follows the same principle as the lifecycle: each old key keeps working alongside the new one for at least 35 days and until it is no longer used, and only then is it removed. See ",[271,686,688],{"href":687},"\u002Fgetting-started\u002Fconfigs#key","Key",{"title":690,"searchDepth":691,"depth":691,"links":692},"",2,[693,694,695,702,703],{"id":265,"depth":691,"text":266},{"id":333,"depth":691,"text":334},{"id":466,"depth":691,"text":467,"children":696},[697,699,700,701],{"id":471,"depth":698,"text":472},3,{"id":478,"depth":698,"text":322},{"id":484,"depth":698,"text":485},{"id":583,"depth":698,"text":584},{"id":632,"depth":691,"text":633},{"id":664,"depth":691,"text":665},"The states a config moves through from creation to cleanup, how the lifetime decides which of them apply, and what to do in each one","md",null,{"modifiedAt":708},"2026-10-12T01:05:35.000Z",{"title":64,"icon":67},{"title":246,"description":711},"How ConfigDirector uses evaluation activity to tell you when a temporary feature flag has settled, when it is ready to archive, and when any config was never used.","aVyOsI4rMvg8qo61J1Kus2b0GtGTwBXb3BsTHadYC8g",[714,716],{"title":59,"path":60,"stem":61,"description":715,"icon":62,"children":-1},"See how often each config is evaluated, which values are served, and which SDKs are asking",{"title":69,"path":70,"stem":71,"description":717,"icon":72,"children":-1},"What ConfigDirector watches for in your applications' use of configs, how alerts are prioritized and delivered, and what to do about each one",1791783863851]