[{"data":1,"prerenderedAt":631},["ShallowReactive",2],{"navigation_docs":3,"-monitoring-lifecycle":215,"-monitoring-lifecycle-surround":626},[4,41,63,200],{"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],{"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,"modifiedAt":43,"defaultOpen":44,"path":45,"stem":46,"children":47,"page":6},"Monitoring","2026-09-24T23:33:20.000Z",true,"\u002Fmonitoring","2.monitoring",[48,53,58],{"title":49,"path":50,"stem":51,"icon":52},"Activity","\u002Fmonitoring\u002Factivity","2.monitoring\u002F1.activity","i-lucide-activity",{"title":54,"path":55,"stem":56,"icon":57},"Lifecycle","\u002Fmonitoring\u002Flifecycle","2.monitoring\u002F2.lifecycle","i-lucide-recycle",{"title":59,"path":60,"stem":61,"icon":62},"Alerts","\u002Fmonitoring\u002Falerts","2.monitoring\u002F3.alerts","i-lucide-bell",{"title":64,"modifiedAt":43,"defaultOpen":44,"path":65,"stem":66,"children":67,"page":6},"SDKs","\u002Fsdks","3.sdks",[68,73,94,119,135,161],{"title":69,"path":70,"stem":71,"icon":72},"Available SDKs","\u002Fsdks\u002Favailable-sdks","3.sdks\u002F1.available-sdks","i-lucide-list",{"title":74,"modifiedAt":43,"icon":75,"defaultOpen":6,"path":76,"stem":77,"children":78,"page":6},"Browser SDKs","i-lucide-monitor","\u002Fsdks\u002Fbrowser","3.sdks\u002F2.browser",[79,84,89],{"title":80,"path":81,"stem":82,"icon":83},"Javascript","\u002Fsdks\u002Fbrowser\u002Fjavascript","3.sdks\u002F2.browser\u002F1.javascript","cd-logos-javascript",{"title":85,"path":86,"stem":87,"icon":88},"React","\u002Fsdks\u002Fbrowser\u002Freact","3.sdks\u002F2.browser\u002F2.react","cd-logos-react-light",{"title":90,"path":91,"stem":92,"icon":93},"Vue","\u002Fsdks\u002Fbrowser\u002Fvue","3.sdks\u002F2.browser\u002F3.vue","cd-logos-vue",{"title":95,"modifiedAt":43,"icon":96,"defaultOpen":6,"path":97,"stem":98,"children":99,"page":6},"Mobile SDKs","i-lucide-smartphone","\u002Fsdks\u002Fmobile","3.sdks\u002F3.mobile",[100,104,109,114],{"title":101,"path":102,"stem":103,"icon":88},"React Native","\u002Fsdks\u002Fmobile\u002Freact-native","3.sdks\u002F3.mobile\u002F1.react-native",{"title":105,"path":106,"stem":107,"icon":108},"Flutter","\u002Fsdks\u002Fmobile\u002Fflutter","3.sdks\u002F3.mobile\u002F2.flutter","cd-logos-flutter",{"title":110,"path":111,"stem":112,"icon":113},"Swift","\u002Fsdks\u002Fmobile\u002Fswift","3.sdks\u002F3.mobile\u002F3.swift","cd-logos-swift",{"title":115,"path":116,"stem":117,"icon":118},"Android","\u002Fsdks\u002Fmobile\u002Fandroid","3.sdks\u002F3.mobile\u002F4.android","cd-logos-android",{"title":120,"modifiedAt":43,"icon":121,"defaultOpen":6,"path":122,"stem":123,"children":124,"page":6},"Meta-framework SDKs","i-lucide-monitor-smartphone","\u002Fsdks\u002Fmeta","3.sdks\u002F4.meta",[125,130],{"title":126,"path":127,"stem":128,"icon":129},"Next.js","\u002Fsdks\u002Fmeta\u002Fnextjs","3.sdks\u002F4.meta\u002F1.nextjs","cd-logos-nextjs",{"title":131,"path":132,"stem":133,"icon":134},"Nuxt","\u002Fsdks\u002Fmeta\u002Fnuxt","3.sdks\u002F4.meta\u002F2.nuxt","cd-logos-nuxt",{"title":136,"modifiedAt":43,"icon":137,"defaultOpen":6,"path":138,"stem":139,"children":140,"page":6},"Server SDKs","i-lucide-server","\u002Fsdks\u002Fserver","3.sdks\u002F5.server",[141,146,151,156],{"title":142,"path":143,"stem":144,"icon":145},"Node.js","\u002Fsdks\u002Fserver\u002Fnode-js","3.sdks\u002F5.server\u002F1.node-js","cd-logos-nodejs",{"title":147,"path":148,"stem":149,"icon":150},"Python","\u002Fsdks\u002Fserver\u002Fpython","3.sdks\u002F5.server\u002F2.python","cd-logos-python",{"title":152,"path":153,"stem":154,"icon":155},"Java","\u002Fsdks\u002Fserver\u002Fjava","3.sdks\u002F5.server\u002F3.java","cd-logos-java",{"title":157,"path":158,"stem":159,"icon":160},".NET","\u002Fsdks\u002Fserver\u002Fdotnet","3.sdks\u002F5.server\u002F4.dotnet","cd-logos-dotnet",{"title":162,"modifiedAt":43,"icon":163,"defaultOpen":6,"path":164,"stem":165,"children":166,"page":6},"OpenFeature Providers","cd-logos-openfeature","\u002Fsdks\u002Fopenfeature","3.sdks\u002F6.openfeature",[167,172,176,180,184,188,192,196],{"title":168,"path":169,"stem":170,"icon":163,"icons":171},"Web","\u002Fsdks\u002Fopenfeature\u002Fweb","3.sdks\u002F6.openfeature\u002F1.web",[163,83],{"title":110,"path":173,"stem":174,"icon":163,"icons":175},"\u002Fsdks\u002Fopenfeature\u002Fswift","3.sdks\u002F6.openfeature\u002F2.swift",[163,113],{"title":115,"path":177,"stem":178,"icon":163,"icons":179},"\u002Fsdks\u002Fopenfeature\u002Fandroid","3.sdks\u002F6.openfeature\u002F3.android",[163,118],{"title":105,"path":181,"stem":182,"icon":163,"icons":183},"\u002Fsdks\u002Fopenfeature\u002Fflutter","3.sdks\u002F6.openfeature\u002F4.flutter",[163,108],{"title":142,"path":185,"stem":186,"icon":163,"icons":187},"\u002Fsdks\u002Fopenfeature\u002Fnode-js","3.sdks\u002F6.openfeature\u002F5.node-js",[163,145],{"title":147,"path":189,"stem":190,"icon":163,"icons":191},"\u002Fsdks\u002Fopenfeature\u002Fpython","3.sdks\u002F6.openfeature\u002F6.python",[163,150],{"title":152,"path":193,"stem":194,"icon":163,"icons":195},"\u002Fsdks\u002Fopenfeature\u002Fjava","3.sdks\u002F6.openfeature\u002F7.java",[163,155],{"title":157,"path":197,"stem":198,"icon":163,"icons":199},"\u002Fsdks\u002Fopenfeature\u002Fdotnet","3.sdks\u002F6.openfeature\u002F8.dotnet",[163,160],{"title":201,"modifiedAt":43,"defaultOpen":44,"path":202,"stem":203,"children":204,"page":6},"Integrations","\u002Fintegrations","4.integrations",[205,210],{"title":206,"path":207,"stem":208,"icon":209},"Terraform","\u002Fintegrations\u002Fterraform","4.integrations\u002F1.terraform","cd-logos-terraform",{"title":211,"path":212,"stem":213,"icon":214},"MCP","\u002Fintegrations\u002Fmcp","4.integrations\u002F2.mcp","cd-logos-mcp",{"id":216,"title":217,"body":218,"description":618,"extension":619,"links":620,"meta":621,"navigation":622,"path":55,"seo":623,"stem":56,"__hash__":625},"docs\u002F2.monitoring\u002F2.lifecycle.md","Config Lifecycle",{"type":219,"value":220,"toc":603},"minimark",[221,225,233,238,255,280,295,302,306,388,394,410,414,418,421,424,427,431,434,437,483,486,505,508,516,520,531,538,544,548,576,580,588,595],[222,223,224],"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.",[222,226,227,228,232],{},"The state is shown in the ",[229,230,231],"strong",{},"Status"," column of the configs list and on the config page. States are recalculated every 30 minutes.",[234,235,237],"h2",{"id":236},"the-lifetime-decides-the-lifecycle","The lifetime decides the lifecycle",[222,239,240,241,246,247,250,251,254],{},"Every config has a ",[242,243,245],"a",{"href":244},"\u002Fgetting-started\u002Fconfigs#lifetime","lifetime",": ",[229,248,249],{},"Temporary"," or ",[229,252,253],{},"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.",[256,257,258,274],"ul",{},[259,260,261,262,265,266,269,270,273],"li",{},"A ",[229,263,264],{},"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 ",[229,267,268],{},"settled"," and when they are ",[229,271,272],{},"ready to archive",", and raises the two lifecycle alerts.",[259,275,261,276,279],{},[229,277,278],{},"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.",[222,281,282,283,286,287,290,291,294],{},"Both lifetimes share the states that describe plain usage: ",[229,284,285],{},"New",", ",[229,288,289],{},"In Use",", and ",[229,292,293],{},"Stale",".",[222,296,297,298,301],{},"You can change the lifetime at any time from the config's ",[229,299,300],{},"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.",[234,303,305],{"id":304},"states","States",[307,308,309,325],"table",{},[310,311,312],"thead",{},[313,314,315,319,322],"tr",{},[316,317,318],"th",{},"State",[316,320,321],{},"Applies to",[316,323,324],{},"Meaning",[326,327,328,341,352,363,376],"tbody",{},[313,329,330,335,338],{},[331,332,333],"td",{},[229,334,285],{},[331,336,337],{},"All configs",[331,339,340],{},"The config was created and has not been evaluated in any environment yet.",[313,342,343,347,349],{},[331,344,345],{},[229,346,289],{},[331,348,337],{},[331,350,351],{},"The config was evaluated in at least one environment within the last 7 days.",[313,353,354,358,360],{},[331,355,356],{},[229,357,293],{},[331,359,337],{},[331,361,362],{},"The config was created more than 15 days ago and has never been evaluated.",[313,364,365,370,373],{},[331,366,367],{},[229,368,369],{},"Settled",[331,371,372],{},"Temporary only",[331,374,375],{},"The config has served a single value everywhere long enough that it can be hardcoded and removed.",[313,377,378,383,385],{},[331,379,380],{},[229,381,382],{},"Archive Ready",[331,384,372],{},[331,386,387],{},"The config was in use and has not been evaluated anywhere for 7 days.",[222,389,390,391,393],{},"A config in any of these states returns to ",[229,392,289],{}," as soon as an SDK evaluates it again. There is nothing to reset.",[222,395,396,397,286,399,401,402,404,405,250,407,409],{},"A permanent config therefore only ever shows ",[229,398,285],{},[229,400,289],{},", or ",[229,403,293],{},". If you expect to see ",[229,406,369],{},[229,408,382],{}," on a config and never do, check its lifetime first.",[234,411,413],{"id":412},"how-each-state-is-decided","How each state is decided",[415,416,289],"h3",{"id":417},"in-use",[222,419,420],{},"A config is in use when any environment has received an evaluation for it in the last 7 days. Evaluations that fell back to the in-code default value count too: the application is still asking for the config.",[415,422,293],{"id":423},"stale",[222,425,426],{},"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.",[415,428,430],{"id":429},"settled-temporary-configs","Settled (temporary configs)",[222,432,433],{},"A settled config is one whose job is done. 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.",[222,435,436],{},"The horizon depends on the role:",[307,438,439,449],{},[310,440,441],{},[313,442,443,446],{},[316,444,445],{},"Role",[316,447,448],{},"Horizon",[326,450,451,459,467,475],{},[313,452,453,456],{},[331,454,455],{},"Feature flag",[331,457,458],{},"7 days",[313,460,461,464],{},[331,462,463],{},"Experiment",[331,465,466],{},"14 days",[313,468,469,472],{},[331,470,471],{},"Config",[331,473,474],{},"30 days",[313,476,477,480],{},[331,478,479],{},"Kill switch",[331,481,482],{},"Never settles",[222,484,485],{},"A temporary config settles when, over the whole horizon and in every environment that has recent activity:",[256,487,488,491,494,497],{},[259,489,490],{},"Every evaluation served the same value. Evaluations that fell back to the in-code default value are tolerated as long as they are under 20% of the total.",[259,492,493],{},"Every one of those environments has evaluations across the full horizon, including the last day.",[259,495,496],{},"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.",[259,498,499,500,504],{},"For feature flags and boolean configs, the value is ",[501,502,503],"code",{},"true",". A flag that has been off everywhere for a week has not shipped, it has been abandoned, and that is a cleanup decision for you rather than a settled verdict.",[222,506,507],{},"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.",[222,509,510,511,515],{},"When a config settles, the config page shows the value to hardcode with a copy button, and a ",[242,512,514],{"href":513},"\u002Fmonitoring\u002Falerts#config-settled","Config settled alert"," is raised.",[415,517,519],{"id":518},"archive-ready-temporary-configs","Archive Ready (temporary configs)",[222,521,522,523,250,525,527,528,530],{},"A temporary config that was ",[229,524,289],{},[229,526,369],{}," and then receives no evaluations in any environment for 7 days becomes ",[229,529,382],{},". 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.",[222,532,261,533,537],{},[242,534,536],{"href":535},"\u002Fmonitoring\u002Falerts#config-ready-to-archive","Config ready to archive alert"," is raised when a config enters this state.",[222,539,540,541,543],{},"A permanent config that stops being evaluated simply stays ",[229,542,289],{}," until the 7 days pass and then shows no evaluations in the configs list; it is never marked for archival. If you want cleanup tracking for it, change its lifetime to temporary.",[234,545,547],{"id":546},"what-to-do-in-each-state","What to do in each state",[256,549,550,558,566,571],{},[259,551,552,554,555,557],{},[229,553,369],{},": hardcode the settled value in your applications, deploy, wait for the state to move to ",[229,556,382],{},", then archive. If the flag is going to be turned back off again, it is not temporary: convert it to a kill switch, or change its lifetime to permanent.",[259,559,560,562,563,565],{},[229,561,382],{},": archive the config from the ",[229,564,300],{}," tab of the config page. The confirmation dialog shows when it was last evaluated in each environment.",[259,567,568,570],{},[229,569,293],{},": either wire it into the application or archive it.",[259,572,573,575],{},[229,574,289],{}," 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.",[234,577,579],{"id":578},"archiving","Archiving",[222,581,582,583,587],{},"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 ",[242,584,586],{"href":585},"\u002Fmonitoring\u002Falerts#config-not-found","Config not found alert",", which is how you find out if the cleanup ran ahead of a deployment.",[222,589,590,591,594],{},"Archived configs are listed under ",[229,592,593],{},"View Archived Configs"," for 30 days and can be restored from there with their targeting rules intact. After 30 days they are purged.",[596,597,598,599,294],"note",{},"Renaming a config key follows the same principle as the lifecycle: both the old and the new key keep working until the old key has not been evaluated for 7 days, and only then is it removed. See ",[242,600,602],{"href":601},"\u002Fgetting-started\u002Fconfigs#key","Key",{"title":604,"searchDepth":605,"depth":605,"links":606},"",2,[607,608,609,616,617],{"id":236,"depth":605,"text":237},{"id":304,"depth":605,"text":305},{"id":412,"depth":605,"text":413,"children":610},[611,613,614,615],{"id":417,"depth":612,"text":289},3,{"id":423,"depth":612,"text":293},{"id":429,"depth":612,"text":430},{"id":518,"depth":612,"text":519},{"id":546,"depth":605,"text":547},{"id":578,"depth":605,"text":579},"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":43},{"title":54,"icon":57},{"title":217,"description":624},"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.","GQfBZQ-XWMaDcRyiJjeFn7PAdJfaiOKZ3PmeLTuCr08",[627,629],{"title":49,"path":50,"stem":51,"description":628,"icon":52,"children":-1},"See how often each config is evaluated, which values are served, and which SDKs are asking",{"title":59,"path":60,"stem":61,"description":630,"icon":62,"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",1790316316545]