[{"data":1,"prerenderedAt":3223},["ShallowReactive",2],{"navigation":3,"docs-path-index":340,"-docs-core-features-health":446,"-docs-core-features-health-surround":3218},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":64},"Docs","i-lucide-book-marked","\u002Fdocs","docs",[10,30,65,293,318],{"title":11,"path":12,"stem":13,"children":14,"icon":29},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002F1.index",[15,17,21,25],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation",{"title":22,"path":23,"stem":24},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F1.getting-started\u002F3.examples",{"title":26,"path":27,"stem":28},"Project Generator","\u002Fdocs\u002Fgetting-started\u002Fproject-generator","docs\u002F1.getting-started\u002F4.project-generator","i-lucide-rocket",{"title":31,"icon":32,"path":33,"stem":34,"children":35,"page":64},"Core features","i-lucide-square-function","\u002Fdocs\u002Fcore-features","docs\u002F2.core-features",[36,40,44,48,52,56,60],{"title":37,"path":38,"stem":39},"Configuration","\u002Fdocs\u002Fcore-features\u002Fconfiguration","docs\u002F2.core-features\u002F0.configuration",{"title":41,"path":42,"stem":43},"Dependency Injection","\u002Fdocs\u002Fcore-features\u002Fcontainer","docs\u002F2.core-features\u002F1.container",{"title":45,"path":46,"stem":47},"Controllers","\u002Fdocs\u002Fcore-features\u002Fcontrollers","docs\u002F2.core-features\u002F2.controllers",{"title":49,"path":50,"stem":51},"Middlewares","\u002Fdocs\u002Fcore-features\u002Fmiddlewares","docs\u002F2.core-features\u002F3.middlewares",{"title":53,"path":54,"stem":55},"Validation","\u002Fdocs\u002Fcore-features\u002Fvalidation","docs\u002F2.core-features\u002F4.validation",{"title":57,"path":58,"stem":59},"Introspection","\u002Fdocs\u002Fcore-features\u002Fintrospection","docs\u002F2.core-features\u002F5.introspection",{"title":61,"path":62,"stem":63},"Health Checks","\u002Fdocs\u002Fcore-features\u002Fhealth","docs\u002F2.core-features\u002F6.health",false,{"title":66,"icon":67,"defaultOpen":68,"path":69,"stem":70,"children":71,"page":64},"Modules","i-lucide-boxes",true,"\u002Fdocs\u002Fmodules","docs\u002F3.modules",[72,89,100,116,135,154,177,191,206,214,229,240,255,274,282],{"title":73,"icon":64,"defaultOpen":64,"path":74,"stem":75,"children":76,"page":64},"Auth","\u002Fdocs\u002Fmodules\u002Fauth","docs\u002F3.modules\u002F1.auth",[77,81,85],{"title":78,"path":79,"stem":80},"Overview","\u002Fdocs\u002Fmodules\u002Fauth\u002Foverview","docs\u002F3.modules\u002F1.auth\u002F0.overview",{"title":82,"path":83,"stem":84},"Decorators","\u002Fdocs\u002Fmodules\u002Fauth\u002Fdecorators","docs\u002F3.modules\u002F1.auth\u002F1.decorators",{"title":86,"path":87,"stem":88},"API Reference","\u002Fdocs\u002Fmodules\u002Fauth\u002Fapi","docs\u002F3.modules\u002F1.auth\u002F2.api",{"title":90,"icon":64,"defaultOpen":64,"path":91,"stem":92,"children":93,"page":64},"Devtools","\u002Fdocs\u002Fmodules\u002Fdevtools","docs\u002F3.modules\u002F10.devtools",[94,97],{"title":78,"path":95,"stem":96},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Foverview","docs\u002F3.modules\u002F10.devtools\u002F0.overview",{"title":37,"path":98,"stem":99},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Fconfiguration","docs\u002F3.modules\u002F10.devtools\u002F1.configuration",{"title":101,"icon":64,"defaultOpen":64,"path":102,"stem":103,"children":104,"page":64},"Telemetry","\u002Fdocs\u002Fmodules\u002Ftelemetry","docs\u002F3.modules\u002F11.telemetry",[105,108,112],{"title":78,"path":106,"stem":107},"\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Foverview","docs\u002F3.modules\u002F11.telemetry\u002F0.overview",{"title":109,"path":110,"stem":111},"API","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Fapi","docs\u002F3.modules\u002F11.telemetry\u002F1.api",{"title":113,"path":114,"stem":115},"Instrumentation","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Finstrumentation","docs\u002F3.modules\u002F11.telemetry\u002F2.instrumentation",{"title":117,"icon":64,"defaultOpen":64,"path":118,"stem":119,"children":120,"page":64},"Queue","\u002Fdocs\u002Fmodules\u002Fqueue","docs\u002F3.modules\u002F12.queue",[121,124,128,132],{"title":78,"path":122,"stem":123},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Foverview","docs\u002F3.modules\u002F12.queue\u002F0.overview",{"title":125,"path":126,"stem":127},"Consumers","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fconsumers","docs\u002F3.modules\u002F12.queue\u002F1.consumers",{"title":129,"path":130,"stem":131},"Strategies","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fstrategies","docs\u002F3.modules\u002F12.queue\u002F2.strategies",{"title":109,"path":133,"stem":134},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Fapi","docs\u002F3.modules\u002F12.queue\u002F3.api",{"title":136,"icon":64,"defaultOpen":64,"path":137,"stem":138,"children":139,"page":64},"Scheduler","\u002Fdocs\u002Fmodules\u002Fscheduler","docs\u002F3.modules\u002F13.scheduler",[140,143,147,151],{"title":78,"path":141,"stem":142},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002Foverview","docs\u002F3.modules\u002F13.scheduler\u002F0.overview",{"title":144,"path":145,"stem":146},"Jobs","\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fjobs","docs\u002F3.modules\u002F13.scheduler\u002F1.jobs",{"title":148,"path":149,"stem":150},"Clustering","\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fclustering","docs\u002F3.modules\u002F13.scheduler\u002F2.clustering",{"title":109,"path":152,"stem":153},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fapi","docs\u002F3.modules\u002F13.scheduler\u002F3.api",{"title":155,"icon":64,"defaultOpen":64,"path":156,"stem":157,"children":158,"page":64},"Testing","\u002Fdocs\u002Fmodules\u002Ftesting","docs\u002F3.modules\u002F14.testing",[159,162,166,170,174],{"title":78,"path":160,"stem":161},"\u002Fdocs\u002Fmodules\u002Ftesting\u002Foverview","docs\u002F3.modules\u002F14.testing\u002F0.overview",{"title":163,"path":164,"stem":165},"Requests","\u002Fdocs\u002Fmodules\u002Ftesting\u002Frequests","docs\u002F3.modules\u002F14.testing\u002F1.requests",{"title":167,"path":168,"stem":169},"Dependencies","\u002Fdocs\u002Fmodules\u002Ftesting\u002Fdependencies","docs\u002F3.modules\u002F14.testing\u002F2.dependencies",{"title":171,"path":172,"stem":173},"Extensions","\u002Fdocs\u002Fmodules\u002Ftesting\u002Fextensions","docs\u002F3.modules\u002F14.testing\u002F3.extensions",{"title":109,"path":175,"stem":176},"\u002Fdocs\u002Fmodules\u002Ftesting\u002Fapi","docs\u002F3.modules\u002F14.testing\u002F4.api",{"title":178,"icon":64,"defaultOpen":64,"path":179,"stem":180,"children":181,"page":64},"Client","\u002Fdocs\u002Fmodules\u002Fclient","docs\u002F3.modules\u002F15.client",[182,185,188],{"title":78,"path":183,"stem":184},"\u002Fdocs\u002Fmodules\u002Fclient\u002Foverview","docs\u002F3.modules\u002F15.client\u002F0.overview",{"title":163,"path":186,"stem":187},"\u002Fdocs\u002Fmodules\u002Fclient\u002Frequests","docs\u002F3.modules\u002F15.client\u002F1.requests",{"title":109,"path":189,"stem":190},"\u002Fdocs\u002Fmodules\u002Fclient\u002Fapi","docs\u002F3.modules\u002F15.client\u002F2.api",{"title":192,"icon":64,"defaultOpen":64,"path":193,"stem":194,"children":195,"page":64},"Logger","\u002Fdocs\u002Fmodules\u002Flogger","docs\u002F3.modules\u002F2.logger",[196,199,203],{"title":78,"path":197,"stem":198},"\u002Fdocs\u002Fmodules\u002Flogger\u002Foverview","docs\u002F3.modules\u002F2.logger\u002F0.overview",{"title":200,"path":201,"stem":202},"Drains & Adapters","\u002Fdocs\u002Fmodules\u002Flogger\u002Fdrivers","docs\u002F3.modules\u002F2.logger\u002F1.drivers",{"title":109,"path":204,"stem":205},"\u002Fdocs\u002Fmodules\u002Flogger\u002Fapi","docs\u002F3.modules\u002F2.logger\u002F2.api",{"title":207,"icon":64,"defaultOpen":64,"path":208,"stem":209,"children":210,"page":64},"Serverless","\u002Fdocs\u002Fmodules\u002Fserverless","docs\u002F3.modules\u002F3.serverless",[211],{"title":78,"path":212,"stem":213},"\u002Fdocs\u002Fmodules\u002Fserverless\u002Foverview","docs\u002F3.modules\u002F3.serverless\u002F0.overview",{"title":215,"icon":64,"defaultOpen":64,"path":216,"stem":217,"children":218,"page":64},"Storage","\u002Fdocs\u002Fmodules\u002Fstorage","docs\u002F3.modules\u002F4.storage",[219,222,226],{"title":78,"path":220,"stem":221},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Foverview","docs\u002F3.modules\u002F4.storage\u002F0.overview",{"title":223,"path":224,"stem":225},"Drivers","\u002Fdocs\u002Fmodules\u002Fstorage\u002Fdrivers","docs\u002F3.modules\u002F4.storage\u002F1.drivers",{"title":109,"path":227,"stem":228},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fapi","docs\u002F3.modules\u002F4.storage\u002F2.api",{"title":230,"icon":64,"defaultOpen":64,"path":231,"stem":232,"children":233,"page":64},"Web Sockets","\u002Fdocs\u002Fmodules\u002Fweb-sockets","docs\u002F3.modules\u002F5.web-sockets",[234,237],{"title":78,"path":235,"stem":236},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Foverview","docs\u002F3.modules\u002F5.web-sockets\u002F0.overview",{"title":109,"path":238,"stem":239},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Fapi","docs\u002F3.modules\u002F5.web-sockets\u002F1.api",{"title":241,"icon":64,"defaultOpen":64,"path":242,"stem":243,"children":244,"page":64},"Schema","\u002Fdocs\u002Fmodules\u002Fschema","docs\u002F3.modules\u002F6.schema",[245,248,251],{"title":78,"path":246,"stem":247},"\u002Fdocs\u002Fmodules\u002Fschema\u002Foverview","docs\u002F3.modules\u002F6.schema\u002F0.overview",{"title":82,"path":249,"stem":250},"\u002Fdocs\u002Fmodules\u002Fschema\u002Fdecorators","docs\u002F3.modules\u002F6.schema\u002F1.decorators",{"title":252,"path":253,"stem":254},"Scalar","\u002Fdocs\u002Fmodules\u002Fschema\u002Fscalar","docs\u002F3.modules\u002F6.schema\u002F2.scalar",{"title":256,"icon":64,"defaultOpen":64,"path":257,"stem":258,"children":259,"page":64},"Nitro","\u002Fdocs\u002Fmodules\u002Fnitro","docs\u002F3.modules\u002F7.nitro",[260,263,266,270],{"title":78,"path":261,"stem":262},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Foverview","docs\u002F3.modules\u002F7.nitro\u002F0.overview",{"title":215,"path":264,"stem":265},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Fstorage","docs\u002F3.modules\u002F7.nitro\u002F1.storage",{"title":267,"path":268,"stem":269},"File-Based Routes","\u002Fdocs\u002Fmodules\u002Fnitro\u002Ffile-based-routes","docs\u002F3.modules\u002F7.nitro\u002F2.file-based-routes",{"title":271,"path":272,"stem":273},"Middleware","\u002Fdocs\u002Fmodules\u002Fnitro\u002Fmiddleware","docs\u002F3.modules\u002F7.nitro\u002F3.middleware",{"title":275,"icon":64,"defaultOpen":64,"path":276,"stem":277,"children":278,"page":64},"Vite","\u002Fdocs\u002Fmodules\u002Fvite","docs\u002F3.modules\u002F8.vite",[279],{"title":78,"path":280,"stem":281},"\u002Fdocs\u002Fmodules\u002Fvite\u002Foverview","docs\u002F3.modules\u002F8.vite\u002F0.overview",{"title":283,"icon":64,"defaultOpen":64,"path":284,"stem":285,"children":286,"page":64},"Cache","\u002Fdocs\u002Fmodules\u002Fcache","docs\u002F3.modules\u002F9.cache",[287,290],{"title":78,"path":288,"stem":289},"\u002Fdocs\u002Fmodules\u002Fcache\u002Foverview","docs\u002F3.modules\u002F9.cache\u002F0.overview",{"title":109,"path":291,"stem":292},"\u002Fdocs\u002Fmodules\u002Fcache\u002Fapi","docs\u002F3.modules\u002F9.cache\u002F1.api",{"title":294,"icon":295,"path":296,"stem":297,"children":298,"page":64},"Deployment","i-lucide-cloud-upload","\u002Fdocs\u002Fdeployment","docs\u002F4.deployment",[299,302,306,310,314],{"title":78,"path":300,"stem":301},"\u002Fdocs\u002Fdeployment\u002Foverview","docs\u002F4.deployment\u002F0.overview",{"title":303,"path":304,"stem":305},"Vercel","\u002Fdocs\u002Fdeployment\u002Fvercel","docs\u002F4.deployment\u002F1.vercel",{"title":307,"path":308,"stem":309},"AWS Lambda","\u002Fdocs\u002Fdeployment\u002Faws-lambda","docs\u002F4.deployment\u002F2.aws-lambda",{"title":311,"path":312,"stem":313},"Azure Functions","\u002Fdocs\u002Fdeployment\u002Fazure-functions","docs\u002F4.deployment\u002F3.azure-functions",{"title":315,"path":316,"stem":317},"Node.js Server","\u002Fdocs\u002Fdeployment\u002Fnode-server","docs\u002F4.deployment\u002F4.node-server",{"title":319,"icon":320,"path":321,"stem":322,"children":323,"page":64},"Advanced","i-lucide-brain","\u002Fdocs\u002Fadvanced","docs\u002F99.advanced",[324,328,332,336],{"title":325,"path":326,"stem":327},"Custom Decorator","\u002Fdocs\u002Fadvanced\u002Fcustom-decorator","docs\u002F99.advanced\u002F1.custom-decorator",{"title":329,"path":330,"stem":331},"Plugins","\u002Fdocs\u002Fadvanced\u002Fcustom-plugin","docs\u002F99.advanced\u002F2.custom-plugin",{"title":333,"path":334,"stem":335},"Custom CLI Command","\u002Fdocs\u002Fadvanced\u002Fcustom-cli-command","docs\u002F99.advanced\u002F3.custom-cli-command",{"title":337,"path":338,"stem":339},"Writing a Recipe","\u002Fdocs\u002Fadvanced\u002Fwriting-a-recipe","docs\u002F99.advanced\u002F4.writing-a-recipe",[341,343,345,346,347,348,349,351,352,353,354,355,356,357,358,360,362,363,364,365,367,368,369,371,372,373,374,376,377,378,379,380,382,383,384,385,386,388,389,390,391,392,393,395,396,397,398,400,401,402,403,405,406,408,409,410,411,413,414,415,417,418,419,420,422,423,424,425,426,428,429,431,432,433,435,436,437,438,439,440,442,443,444,445],{"path":342},"\u002Fdocs\u002F.navigation",{"path":344},"\u002Fdocs\u002Fgetting-started\u002F.navigation",{"path":12},{"path":19},{"path":23},{"path":27},{"path":350},"\u002Fdocs\u002Fcore-features\u002F.navigation",{"path":38},{"path":42},{"path":46},{"path":50},{"path":54},{"path":58},{"path":62},{"path":359},"\u002Fdocs\u002Fmodules\u002F.navigation",{"path":361},"\u002Fdocs\u002Fmodules\u002Fauth\u002F.navigation",{"path":79},{"path":83},{"path":87},{"path":366},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002F.navigation",{"path":95},{"path":98},{"path":370},"\u002Fdocs\u002Fmodules\u002Ftelemetry\u002F.navigation",{"path":106},{"path":110},{"path":114},{"path":375},"\u002Fdocs\u002Fmodules\u002Fqueue\u002F.navigation",{"path":122},{"path":126},{"path":130},{"path":133},{"path":381},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002F.navigation",{"path":141},{"path":145},{"path":149},{"path":152},{"path":387},"\u002Fdocs\u002Fmodules\u002Ftesting\u002F.navigation",{"path":160},{"path":164},{"path":168},{"path":172},{"path":175},{"path":394},"\u002Fdocs\u002Fmodules\u002Fclient\u002F.navigation",{"path":183},{"path":186},{"path":189},{"path":399},"\u002Fdocs\u002Fmodules\u002Flogger\u002F.navigation",{"path":197},{"path":201},{"path":204},{"path":404},"\u002Fdocs\u002Fmodules\u002Fserverless\u002F.navigation",{"path":212},{"path":407},"\u002Fdocs\u002Fmodules\u002Fstorage\u002F.navigation",{"path":220},{"path":224},{"path":227},{"path":412},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002F.navigation",{"path":235},{"path":238},{"path":416},"\u002Fdocs\u002Fmodules\u002Fschema\u002F.navigation",{"path":246},{"path":249},{"path":253},{"path":421},"\u002Fdocs\u002Fmodules\u002Fnitro\u002F.navigation",{"path":261},{"path":264},{"path":268},{"path":272},{"path":427},"\u002Fdocs\u002Fmodules\u002Fvite\u002F.navigation",{"path":280},{"path":430},"\u002Fdocs\u002Fmodules\u002Fcache\u002F.navigation",{"path":288},{"path":291},{"path":434},"\u002Fdocs\u002Fdeployment\u002F.navigation",{"path":300},{"path":304},{"path":308},{"path":312},{"path":316},{"path":441},"\u002Fdocs\u002Fadvanced\u002F.navigation",{"path":326},{"path":330},{"path":334},{"path":338},{"id":447,"title":61,"body":448,"description":3212,"extension":3213,"links":3214,"meta":3215,"navigation":68,"path":62,"seo":3216,"stem":63,"__hash__":3217},"docs\u002Fdocs\u002F2.core-features\u002F6.health.md",{"type":449,"value":450,"toc":3199},"minimark",[451,455,554,617,624,629,695,698,709,713,720,880,894,897,1117,1122,1125,1204,1211,1229,1401,1480,1484,1504,1880,1905,1909,1920,1927,1980,2015,2235,2241,2245,2257,2350,2353,2360,2364,2371,2384,2419,2435,2513,2532,2536,2926,2955,2972,2976,3037,3040,3195],[452,453,454],"p",{},"One option gives a Vercube application the probes Kubernetes, a load balancer or any orchestrator expects, and a shutdown that does not drop requests during a rolling deploy:",[456,457,463],"pre",{"className":458,"code":459,"filename":460,"language":461,"meta":462,"style":462},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineConfig } from '@vercube\u002Fcore';\n\nexport default defineConfig({\n  health: true,\n});\n","vercube.config.ts","ts","",[464,465,466,502,508,526,543],"code",{"__ignoreMap":462},[467,468,471,475,479,483,486,489,492,496,499],"span",{"class":469,"line":470},"line",1,[467,472,474],{"class":473},"s7zQu","import",[467,476,478],{"class":477},"sMK4o"," {",[467,480,482],{"class":481},"sTEyZ"," defineConfig",[467,484,485],{"class":477}," }",[467,487,488],{"class":473}," from",[467,490,491],{"class":477}," '",[467,493,495],{"class":494},"sfazB","@vercube\u002Fcore",[467,497,498],{"class":477},"'",[467,500,501],{"class":477},";\n",[467,503,505],{"class":469,"line":504},2,[467,506,507],{"emptyLinePlaceholder":68},"\n",[467,509,511,514,517,520,523],{"class":469,"line":510},3,[467,512,513],{"class":473},"export",[467,515,516],{"class":473}," default",[467,518,482],{"class":519},"s2Zo4",[467,521,522],{"class":481},"(",[467,524,525],{"class":477},"{\n",[467,527,529,533,536,540],{"class":469,"line":528},4,[467,530,532],{"class":531},"swJcz","  health",[467,534,535],{"class":477},":",[467,537,539],{"class":538},"sfNiH"," true",[467,541,542],{"class":477},",\n",[467,544,546,549,552],{"class":469,"line":545},5,[467,547,548],{"class":477},"}",[467,550,551],{"class":481},")",[467,553,501],{"class":477},[456,555,559],{"className":556,"code":557,"language":558,"meta":462,"style":462},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -s localhost:3000\u002F_health\u002Flive\n# {\"status\":\"ok\"}\n\ncurl -s localhost:3000\u002F_health\u002Fready\n# {\"status\":\"ok\",\"checks\":{\"queue:default\":{\"status\":\"ok\"}}}\n\ncurl -s localhost:3000\u002F_health\u002Fstartup\n# {\"status\":\"ok\"}\n","bash",[464,560,561,573,579,583,592,597,602,612],{"__ignoreMap":462},[467,562,563,567,570],{"class":469,"line":470},[467,564,566],{"class":565},"sBMFI","curl",[467,568,569],{"class":494}," -s",[467,571,572],{"class":494}," localhost:3000\u002F_health\u002Flive\n",[467,574,575],{"class":469,"line":504},[467,576,578],{"class":577},"sHwdD","# {\"status\":\"ok\"}\n",[467,580,581],{"class":469,"line":510},[467,582,507],{"emptyLinePlaceholder":68},[467,584,585,587,589],{"class":469,"line":528},[467,586,566],{"class":565},[467,588,569],{"class":494},[467,590,591],{"class":494}," localhost:3000\u002F_health\u002Fready\n",[467,593,594],{"class":469,"line":545},[467,595,596],{"class":577},"# {\"status\":\"ok\",\"checks\":{\"queue:default\":{\"status\":\"ok\"}}}\n",[467,598,600],{"class":469,"line":599},6,[467,601,507],{"emptyLinePlaceholder":68},[467,603,605,607,609],{"class":469,"line":604},7,[467,606,566],{"class":565},[467,608,569],{"class":494},[467,610,611],{"class":494}," localhost:3000\u002F_health\u002Fstartup\n",[467,613,615],{"class":469,"line":614},8,[467,616,578],{"class":577},[452,618,619,620,623],{},"Health is off by default: an application that does not set ",[464,621,622],{},"health"," gets no routes and no overhead.",[625,626,628],"h2",{"id":627},"the-three-probes","The three probes",[630,631,632,648],"table",{},[633,634,635],"thead",{},[636,637,638,642,645],"tr",{},[639,640,641],"th",{},"Endpoint",[639,643,644],{},"200 when",[639,646,647],{},"503 when",[649,650,651,665,678],"tbody",{},[636,652,653,659,662],{},[654,655,656],"td",{},[464,657,658],{},"\u002F_health\u002Flive",[654,660,661],{},"the process serves requests",[654,663,664],{},"never; nothing is checked",[636,666,667,672,675],{},[654,668,669],{},[464,670,671],{},"\u002F_health\u002Fready",[654,673,674],{},"started, not shutting down, every critical check passes",[654,676,677],{},"starting, draining, or a critical check fails",[636,679,680,685,692],{},[654,681,682],{},[464,683,684],{},"\u002F_health\u002Fstartup",[654,686,687,688,691],{},"the ",[464,689,690],{},"app.onStart()"," hooks have finished",[654,693,694],{},"they are still running",[452,696,697],{},"Liveness checks nothing on purpose. A database outage should take the pod out of the load balancer (readiness), not make Kubernetes restart a healthy process in a loop (liveness).",[452,699,700,701,704,705,708],{},"Every response is JSON with ",[464,702,703],{},"cache-control: no-store",", and the probes answer ",[464,706,707],{},"HEAD"," too. They skip application-wide middlewares, so a global authentication or tenancy middleware never locks the orchestrator out, and request logging does not write a line per probe.",[625,710,712],{"id":711},"checks","Checks",[452,714,715,716,719],{},"Readiness runs every registered check in parallel. A check passes when it resolves and fails when it throws, rejects, returns ",[464,717,718],{},"{ status: 'down' }",", or runs past its timeout:",[456,721,723],{"className":458,"code":722,"language":461,"meta":462,"style":462},"const app = await createApp();\n\napp.health.register({\n  name: 'db',\n  critical: true, \u002F\u002F false: reported, but readiness stays 200 (\"degraded\")\n  timeout: 1000,\n  check: () => pool.query('SELECT 1'),\n});\n\nawait app.listen();\n",[464,724,725,748,752,771,787,802,815,849,857,862],{"__ignoreMap":462},[467,726,727,731,734,737,740,743,746],{"class":469,"line":470},[467,728,730],{"class":729},"spNyl","const",[467,732,733],{"class":481}," app ",[467,735,736],{"class":477},"=",[467,738,739],{"class":473}," await",[467,741,742],{"class":519}," createApp",[467,744,745],{"class":481},"()",[467,747,501],{"class":477},[467,749,750],{"class":469,"line":504},[467,751,507],{"emptyLinePlaceholder":68},[467,753,754,757,760,762,764,767,769],{"class":469,"line":510},[467,755,756],{"class":481},"app",[467,758,759],{"class":477},".",[467,761,622],{"class":481},[467,763,759],{"class":477},[467,765,766],{"class":519},"register",[467,768,522],{"class":481},[467,770,525],{"class":477},[467,772,773,776,778,780,783,785],{"class":469,"line":528},[467,774,775],{"class":531},"  name",[467,777,535],{"class":477},[467,779,491],{"class":477},[467,781,782],{"class":494},"db",[467,784,498],{"class":477},[467,786,542],{"class":477},[467,788,789,792,794,796,799],{"class":469,"line":545},[467,790,791],{"class":531},"  critical",[467,793,535],{"class":477},[467,795,539],{"class":538},[467,797,798],{"class":477},",",[467,800,801],{"class":577}," \u002F\u002F false: reported, but readiness stays 200 (\"degraded\")\n",[467,803,804,807,809,813],{"class":469,"line":599},[467,805,806],{"class":531},"  timeout",[467,808,535],{"class":477},[467,810,812],{"class":811},"sbssI"," 1000",[467,814,542],{"class":477},[467,816,817,820,822,825,828,831,833,836,838,840,843,845,847],{"class":469,"line":604},[467,818,819],{"class":519},"  check",[467,821,535],{"class":477},[467,823,824],{"class":477}," ()",[467,826,827],{"class":729}," =>",[467,829,830],{"class":481}," pool",[467,832,759],{"class":477},[467,834,835],{"class":519},"query",[467,837,522],{"class":481},[467,839,498],{"class":477},[467,841,842],{"class":494},"SELECT 1",[467,844,498],{"class":477},[467,846,551],{"class":481},[467,848,542],{"class":477},[467,850,851,853,855],{"class":469,"line":614},[467,852,548],{"class":477},[467,854,551],{"class":481},[467,856,501],{"class":477},[467,858,860],{"class":469,"line":859},9,[467,861,507],{"emptyLinePlaceholder":68},[467,863,865,868,871,873,876,878],{"class":469,"line":864},10,[467,866,867],{"class":473},"await",[467,869,870],{"class":481}," app",[467,872,759],{"class":477},[467,874,875],{"class":519},"listen",[467,877,745],{"class":481},[467,879,501],{"class":477},[452,881,882,883,886,887,890,891,893],{},"Checks only run when something asks for readiness, and the report is reused for ",[464,884,885],{},"cacheTtl"," milliseconds (1000 by default), so many replicas probing every few seconds still cost one round trip per backend per second. Registering a name again replaces the earlier check. ",[464,888,889],{},"app.health"," exists whether or not ",[464,892,622],{}," is set, so modules register their checks either way; the option only adds the routes.",[452,895,896],{},"Checks for one application can also live in the config:",[456,898,900],{"className":458,"code":899,"filename":460,"language":461,"meta":462,"style":462},"export default defineConfig({\n  health: {\n    checks: [\n      {\n        name: 'payments-api',\n        critical: false,\n        check: async () => {\n          const response = await fetch('https:\u002F\u002Fpayments.internal\u002Fping');\n\n          if (!response.ok) {\n            throw new Error(`payments-api answered ${response.status}`);\n          }\n        },\n      },\n    ],\n  },\n});\n",[464,901,902,914,923,933,938,954,966,982,1011,1015,1039,1076,1082,1088,1094,1102,1108],{"__ignoreMap":462},[467,903,904,906,908,910,912],{"class":469,"line":470},[467,905,513],{"class":473},[467,907,516],{"class":473},[467,909,482],{"class":519},[467,911,522],{"class":481},[467,913,525],{"class":477},[467,915,916,918,920],{"class":469,"line":504},[467,917,532],{"class":531},[467,919,535],{"class":477},[467,921,922],{"class":477}," {\n",[467,924,925,928,930],{"class":469,"line":510},[467,926,927],{"class":531},"    checks",[467,929,535],{"class":477},[467,931,932],{"class":481}," [\n",[467,934,935],{"class":469,"line":528},[467,936,937],{"class":477},"      {\n",[467,939,940,943,945,947,950,952],{"class":469,"line":545},[467,941,942],{"class":531},"        name",[467,944,535],{"class":477},[467,946,491],{"class":477},[467,948,949],{"class":494},"payments-api",[467,951,498],{"class":477},[467,953,542],{"class":477},[467,955,956,959,961,964],{"class":469,"line":599},[467,957,958],{"class":531},"        critical",[467,960,535],{"class":477},[467,962,963],{"class":538}," false",[467,965,542],{"class":477},[467,967,968,971,973,976,978,980],{"class":469,"line":604},[467,969,970],{"class":519},"        check",[467,972,535],{"class":477},[467,974,975],{"class":729}," async",[467,977,824],{"class":477},[467,979,827],{"class":729},[467,981,922],{"class":477},[467,983,984,987,990,993,995,998,1000,1002,1005,1007,1009],{"class":469,"line":614},[467,985,986],{"class":729},"          const",[467,988,989],{"class":481}," response",[467,991,992],{"class":477}," =",[467,994,739],{"class":473},[467,996,997],{"class":519}," fetch",[467,999,522],{"class":531},[467,1001,498],{"class":477},[467,1003,1004],{"class":494},"https:\u002F\u002Fpayments.internal\u002Fping",[467,1006,498],{"class":477},[467,1008,551],{"class":531},[467,1010,501],{"class":477},[467,1012,1013],{"class":469,"line":859},[467,1014,507],{"emptyLinePlaceholder":68},[467,1016,1017,1020,1023,1026,1029,1031,1034,1037],{"class":469,"line":864},[467,1018,1019],{"class":473},"          if",[467,1021,1022],{"class":531}," (",[467,1024,1025],{"class":477},"!",[467,1027,1028],{"class":481},"response",[467,1030,759],{"class":477},[467,1032,1033],{"class":481},"ok",[467,1035,1036],{"class":531},") ",[467,1038,525],{"class":477},[467,1040,1042,1045,1048,1051,1053,1056,1059,1062,1064,1066,1069,1072,1074],{"class":469,"line":1041},11,[467,1043,1044],{"class":473},"            throw",[467,1046,1047],{"class":477}," new",[467,1049,1050],{"class":519}," Error",[467,1052,522],{"class":531},[467,1054,1055],{"class":477},"`",[467,1057,1058],{"class":494},"payments-api answered ",[467,1060,1061],{"class":477},"${",[467,1063,1028],{"class":481},[467,1065,759],{"class":477},[467,1067,1068],{"class":481},"status",[467,1070,1071],{"class":477},"}`",[467,1073,551],{"class":531},[467,1075,501],{"class":477},[467,1077,1079],{"class":469,"line":1078},12,[467,1080,1081],{"class":477},"          }\n",[467,1083,1085],{"class":469,"line":1084},13,[467,1086,1087],{"class":477},"        },\n",[467,1089,1091],{"class":469,"line":1090},14,[467,1092,1093],{"class":477},"      },\n",[467,1095,1097,1100],{"class":469,"line":1096},15,[467,1098,1099],{"class":481},"    ]",[467,1101,542],{"class":477},[467,1103,1105],{"class":469,"line":1104},16,[467,1106,1107],{"class":477},"  },\n",[467,1109,1111,1113,1115],{"class":469,"line":1110},17,[467,1112,548],{"class":477},[467,1114,551],{"class":481},[467,1116,501],{"class":477},[1118,1119,1121],"h3",{"id":1120},"checks-from-modules","Checks from modules",[452,1123,1124],{},"The modules register their own checks, there is nothing to write for them:",[630,1126,1127,1140],{},[633,1128,1129],{},[636,1130,1131,1134,1137],{},[639,1132,1133],{},"Check",[639,1135,1136],{},"Registered by",[639,1138,1139],{},"What it does",[649,1141,1142,1161,1182],{},[636,1143,1144,1149,1155],{},[654,1145,1146],{},[464,1147,1148],{},"queue:\u003Cmount>",[654,1150,1151,1154],{},[464,1152,1153],{},"QueuePlugin",", for BullMQ, RabbitMQ and Kafka mounts",[654,1156,1157,1158],{},"a Redis read, opening a channel, ",[464,1159,1160],{},"describeCluster",[636,1162,1163,1168,1174],{},[654,1164,1165],{},[464,1166,1167],{},"scheduler:store",[654,1169,1170,1173],{},[464,1171,1172],{},"SchedulerPlugin",", for the Redis and Postgres stores",[654,1175,1176,1179,1180],{},[464,1177,1178],{},"PING",", ",[464,1181,842],{},[636,1183,1184,1189,1195],{},[654,1185,1186],{},[464,1187,1188],{},"storage:\u003Cmount>",[654,1190,1191,1194],{},[464,1192,1193],{},"StorageManager",", for S3 mounts",[654,1196,1197,1200,1201],{},[464,1198,1199],{},"HeadObject",", or ",[464,1202,1203],{},"HeadBucket",[452,1205,1206,1207,1210],{},"In-memory drivers (the memory queue, the memory store, ",[464,1208,1209],{},"MemoryStorage",") have no backend that can be down and get no check. The cache keeps its entries in a storage mount, so the check of that mount covers it.",[452,1212,1213,1214,1216,1217,1220,1221,1224,1225,1228],{},"Each one takes a ",[464,1215,622],{}," option: ",[464,1218,1219],{},"false"," registers nothing, ",[464,1222,1223],{},"{ critical: false }"," keeps it in the report without failing readiness, and ",[464,1226,1227],{},"timeout"," overrides the default:",[456,1230,1232],{"className":458,"code":1231,"filename":460,"language":461,"meta":462,"style":462},"export default defineConfig({\n  health: true,\n  plugins: [\n    [QueuePlugin, {\n      strategies: [{ strategy: BullMQStrategy, initOptions }],\n      health: { critical: false },\n    }],\n    [SchedulerPlugin, {\n      store: { store: RedisStore, initOptions },\n      health: false,\n    }],\n  ],\n});\n",[464,1233,1234,1246,1256,1265,1274,1307,1326,1335,1344,1368,1378,1386,1393],{"__ignoreMap":462},[467,1235,1236,1238,1240,1242,1244],{"class":469,"line":470},[467,1237,513],{"class":473},[467,1239,516],{"class":473},[467,1241,482],{"class":519},[467,1243,522],{"class":481},[467,1245,525],{"class":477},[467,1247,1248,1250,1252,1254],{"class":469,"line":504},[467,1249,532],{"class":531},[467,1251,535],{"class":477},[467,1253,539],{"class":538},[467,1255,542],{"class":477},[467,1257,1258,1261,1263],{"class":469,"line":510},[467,1259,1260],{"class":531},"  plugins",[467,1262,535],{"class":477},[467,1264,932],{"class":481},[467,1266,1267,1270,1272],{"class":469,"line":528},[467,1268,1269],{"class":481},"    [QueuePlugin",[467,1271,798],{"class":477},[467,1273,922],{"class":477},[467,1275,1276,1279,1281,1284,1287,1290,1292,1295,1297,1300,1302,1305],{"class":469,"line":545},[467,1277,1278],{"class":531},"      strategies",[467,1280,535],{"class":477},[467,1282,1283],{"class":481}," [",[467,1285,1286],{"class":477},"{",[467,1288,1289],{"class":531}," strategy",[467,1291,535],{"class":477},[467,1293,1294],{"class":481}," BullMQStrategy",[467,1296,798],{"class":477},[467,1298,1299],{"class":481}," initOptions ",[467,1301,548],{"class":477},[467,1303,1304],{"class":481},"]",[467,1306,542],{"class":477},[467,1308,1309,1312,1314,1316,1319,1321,1323],{"class":469,"line":599},[467,1310,1311],{"class":531},"      health",[467,1313,535],{"class":477},[467,1315,478],{"class":477},[467,1317,1318],{"class":531}," critical",[467,1320,535],{"class":477},[467,1322,963],{"class":538},[467,1324,1325],{"class":477}," },\n",[467,1327,1328,1331,1333],{"class":469,"line":604},[467,1329,1330],{"class":477},"    }",[467,1332,1304],{"class":481},[467,1334,542],{"class":477},[467,1336,1337,1340,1342],{"class":469,"line":614},[467,1338,1339],{"class":481},"    [SchedulerPlugin",[467,1341,798],{"class":477},[467,1343,922],{"class":477},[467,1345,1346,1349,1351,1353,1356,1358,1361,1363,1365],{"class":469,"line":859},[467,1347,1348],{"class":531},"      store",[467,1350,535],{"class":477},[467,1352,478],{"class":477},[467,1354,1355],{"class":531}," store",[467,1357,535],{"class":477},[467,1359,1360],{"class":481}," RedisStore",[467,1362,798],{"class":477},[467,1364,1299],{"class":481},[467,1366,1367],{"class":477},"},\n",[467,1369,1370,1372,1374,1376],{"class":469,"line":864},[467,1371,1311],{"class":531},[467,1373,535],{"class":477},[467,1375,963],{"class":538},[467,1377,542],{"class":477},[467,1379,1380,1382,1384],{"class":469,"line":1041},[467,1381,1330],{"class":477},[467,1383,1304],{"class":481},[467,1385,542],{"class":477},[467,1387,1388,1391],{"class":469,"line":1078},[467,1389,1390],{"class":481},"  ]",[467,1392,542],{"class":477},[467,1394,1395,1397,1399],{"class":469,"line":1084},[467,1396,548],{"class":477},[467,1398,551],{"class":481},[467,1400,501],{"class":477},[456,1402,1404],{"className":458,"code":1403,"language":461,"meta":462,"style":462},"await storage.mount({\n  name: 'cache',\n  storage: S3Storage,\n  initOptions,\n  health: { critical: false },\n});\n",[464,1405,1406,1422,1437,1449,1456,1472],{"__ignoreMap":462},[467,1407,1408,1410,1413,1415,1418,1420],{"class":469,"line":470},[467,1409,867],{"class":473},[467,1411,1412],{"class":481}," storage",[467,1414,759],{"class":477},[467,1416,1417],{"class":519},"mount",[467,1419,522],{"class":481},[467,1421,525],{"class":477},[467,1423,1424,1426,1428,1430,1433,1435],{"class":469,"line":504},[467,1425,775],{"class":531},[467,1427,535],{"class":477},[467,1429,491],{"class":477},[467,1431,1432],{"class":494},"cache",[467,1434,498],{"class":477},[467,1436,542],{"class":477},[467,1438,1439,1442,1444,1447],{"class":469,"line":510},[467,1440,1441],{"class":531},"  storage",[467,1443,535],{"class":477},[467,1445,1446],{"class":481}," S3Storage",[467,1448,542],{"class":477},[467,1450,1451,1454],{"class":469,"line":528},[467,1452,1453],{"class":481},"  initOptions",[467,1455,542],{"class":477},[467,1457,1458,1460,1462,1464,1466,1468,1470],{"class":469,"line":545},[467,1459,532],{"class":531},[467,1461,535],{"class":477},[467,1463,478],{"class":477},[467,1465,1318],{"class":531},[467,1467,535],{"class":477},[467,1469,963],{"class":538},[467,1471,1325],{"class":477},[467,1473,1474,1476,1478],{"class":469,"line":599},[467,1475,548],{"class":477},[467,1477,551],{"class":481},[467,1479,501],{"class":477},[1118,1481,1483],{"id":1482},"writing-a-check-for-your-own-module","Writing a check for your own module",[452,1485,1486,1487,1489,1490,1493,1494,1179,1496,1499,1500,1503],{},"A module registers its check where it sets itself up, usually in its plugin. Accept the same ",[464,1488,622],{}," option the built-in modules take, and read it with ",[464,1491,1492],{},"resolveModuleHealth()"," so ",[464,1495,1219],{},[464,1497,1498],{},"true"," and ",[464,1501,1502],{},"{ critical, timeout }"," behave the same everywhere:",[456,1505,1507],{"className":458,"code":1506,"language":461,"meta":462,"style":462},"import { BasePlugin, resolveModuleHealth } from '@vercube\u002Fcore';\nimport type { App, HealthTypes } from '@vercube\u002Fcore';\n\ninterface SearchOptions {\n  url: string;\n  health?: HealthTypes.ModuleOption;\n}\n\nexport class SearchPlugin extends BasePlugin\u003CSearchOptions> {\n  public override async use(app: App, options: SearchOptions): Promise\u003Cvoid> {\n    app.container.bindInstance(SearchClient, new SearchClient(options.url));\n\n    const health = resolveModuleHealth(options.health);\n\n    if (health) {\n      app.health.register({\n        name: 'search',\n        ...health,\n        check: () => app.container.get(SearchClient).ping(),\n      });\n    }\n  }\n}\n",[464,1508,1509,1535,1564,1568,1578,1590,1606,1611,1615,1641,1687,1729,1733,1757,1761,1774,1791,1806,1816,1853,1863,1869,1875],{"__ignoreMap":462},[467,1510,1511,1513,1515,1518,1520,1523,1525,1527,1529,1531,1533],{"class":469,"line":470},[467,1512,474],{"class":473},[467,1514,478],{"class":477},[467,1516,1517],{"class":481}," BasePlugin",[467,1519,798],{"class":477},[467,1521,1522],{"class":481}," resolveModuleHealth",[467,1524,485],{"class":477},[467,1526,488],{"class":473},[467,1528,491],{"class":477},[467,1530,495],{"class":494},[467,1532,498],{"class":477},[467,1534,501],{"class":477},[467,1536,1537,1539,1542,1544,1547,1549,1552,1554,1556,1558,1560,1562],{"class":469,"line":504},[467,1538,474],{"class":473},[467,1540,1541],{"class":473}," type",[467,1543,478],{"class":477},[467,1545,1546],{"class":481}," App",[467,1548,798],{"class":477},[467,1550,1551],{"class":481}," HealthTypes",[467,1553,485],{"class":477},[467,1555,488],{"class":473},[467,1557,491],{"class":477},[467,1559,495],{"class":494},[467,1561,498],{"class":477},[467,1563,501],{"class":477},[467,1565,1566],{"class":469,"line":510},[467,1567,507],{"emptyLinePlaceholder":68},[467,1569,1570,1573,1576],{"class":469,"line":528},[467,1571,1572],{"class":729},"interface",[467,1574,1575],{"class":565}," SearchOptions",[467,1577,922],{"class":477},[467,1579,1580,1583,1585,1588],{"class":469,"line":545},[467,1581,1582],{"class":531},"  url",[467,1584,535],{"class":477},[467,1586,1587],{"class":565}," string",[467,1589,501],{"class":477},[467,1591,1592,1594,1597,1599,1601,1604],{"class":469,"line":599},[467,1593,532],{"class":531},[467,1595,1596],{"class":477},"?:",[467,1598,1551],{"class":565},[467,1600,759],{"class":477},[467,1602,1603],{"class":565},"ModuleOption",[467,1605,501],{"class":477},[467,1607,1608],{"class":469,"line":604},[467,1609,1610],{"class":477},"}\n",[467,1612,1613],{"class":469,"line":614},[467,1614,507],{"emptyLinePlaceholder":68},[467,1616,1617,1619,1622,1625,1628,1630,1633,1636,1639],{"class":469,"line":859},[467,1618,513],{"class":473},[467,1620,1621],{"class":729}," class",[467,1623,1624],{"class":565}," SearchPlugin",[467,1626,1627],{"class":729}," extends",[467,1629,1517],{"class":565},[467,1631,1632],{"class":477},"\u003C",[467,1634,1635],{"class":565},"SearchOptions",[467,1637,1638],{"class":477},">",[467,1640,922],{"class":477},[467,1642,1643,1646,1649,1651,1654,1656,1659,1661,1663,1665,1668,1670,1672,1675,1678,1680,1683,1685],{"class":469,"line":864},[467,1644,1645],{"class":729},"  public",[467,1647,1648],{"class":729}," override",[467,1650,975],{"class":729},[467,1652,1653],{"class":531}," use",[467,1655,522],{"class":477},[467,1657,756],{"class":1658},"sHdIc",[467,1660,535],{"class":477},[467,1662,1546],{"class":565},[467,1664,798],{"class":477},[467,1666,1667],{"class":1658}," options",[467,1669,535],{"class":477},[467,1671,1575],{"class":565},[467,1673,1674],{"class":477},"):",[467,1676,1677],{"class":565}," Promise",[467,1679,1632],{"class":477},[467,1681,1682],{"class":565},"void",[467,1684,1638],{"class":477},[467,1686,922],{"class":477},[467,1688,1689,1692,1694,1697,1699,1702,1704,1707,1709,1711,1714,1716,1719,1721,1724,1727],{"class":469,"line":1041},[467,1690,1691],{"class":481},"    app",[467,1693,759],{"class":477},[467,1695,1696],{"class":481},"container",[467,1698,759],{"class":477},[467,1700,1701],{"class":519},"bindInstance",[467,1703,522],{"class":531},[467,1705,1706],{"class":481},"SearchClient",[467,1708,798],{"class":477},[467,1710,1047],{"class":477},[467,1712,1713],{"class":519}," SearchClient",[467,1715,522],{"class":531},[467,1717,1718],{"class":481},"options",[467,1720,759],{"class":477},[467,1722,1723],{"class":481},"url",[467,1725,1726],{"class":531},"))",[467,1728,501],{"class":477},[467,1730,1731],{"class":469,"line":1078},[467,1732,507],{"emptyLinePlaceholder":68},[467,1734,1735,1738,1741,1743,1745,1747,1749,1751,1753,1755],{"class":469,"line":1084},[467,1736,1737],{"class":729},"    const",[467,1739,1740],{"class":481}," health",[467,1742,992],{"class":477},[467,1744,1522],{"class":519},[467,1746,522],{"class":531},[467,1748,1718],{"class":481},[467,1750,759],{"class":477},[467,1752,622],{"class":481},[467,1754,551],{"class":531},[467,1756,501],{"class":477},[467,1758,1759],{"class":469,"line":1090},[467,1760,507],{"emptyLinePlaceholder":68},[467,1762,1763,1766,1768,1770,1772],{"class":469,"line":1096},[467,1764,1765],{"class":473},"    if",[467,1767,1022],{"class":531},[467,1769,622],{"class":481},[467,1771,1036],{"class":531},[467,1773,525],{"class":477},[467,1775,1776,1779,1781,1783,1785,1787,1789],{"class":469,"line":1104},[467,1777,1778],{"class":481},"      app",[467,1780,759],{"class":477},[467,1782,622],{"class":481},[467,1784,759],{"class":477},[467,1786,766],{"class":519},[467,1788,522],{"class":531},[467,1790,525],{"class":477},[467,1792,1793,1795,1797,1799,1802,1804],{"class":469,"line":1110},[467,1794,942],{"class":531},[467,1796,535],{"class":477},[467,1798,491],{"class":477},[467,1800,1801],{"class":494},"search",[467,1803,498],{"class":477},[467,1805,542],{"class":477},[467,1807,1809,1812,1814],{"class":469,"line":1808},18,[467,1810,1811],{"class":477},"        ...",[467,1813,622],{"class":481},[467,1815,542],{"class":477},[467,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1838,1840,1842,1844,1846,1849,1851],{"class":469,"line":1818},19,[467,1820,970],{"class":519},[467,1822,535],{"class":477},[467,1824,824],{"class":477},[467,1826,827],{"class":729},[467,1828,870],{"class":481},[467,1830,759],{"class":477},[467,1832,1696],{"class":481},[467,1834,759],{"class":477},[467,1836,1837],{"class":519},"get",[467,1839,522],{"class":531},[467,1841,1706],{"class":481},[467,1843,551],{"class":531},[467,1845,759],{"class":477},[467,1847,1848],{"class":519},"ping",[467,1850,745],{"class":531},[467,1852,542],{"class":477},[467,1854,1856,1859,1861],{"class":469,"line":1855},20,[467,1857,1858],{"class":477},"      }",[467,1860,551],{"class":531},[467,1862,501],{"class":477},[467,1864,1866],{"class":469,"line":1865},21,[467,1867,1868],{"class":477},"    }\n",[467,1870,1872],{"class":469,"line":1871},22,[467,1873,1874],{"class":477},"  }\n",[467,1876,1878],{"class":469,"line":1877},23,[467,1879,1610],{"class":477},[452,1881,1882,1883,1885,1886,1885,1888,1890,1891,1893,1894,1896,1897,1900,1901,1904],{},"Make the check a real round trip (a ",[464,1884,1178],{},", a ",[464,1887,842],{},[464,1889,707],{},") rather than a flag the client last saw, and keep it cheap: it runs at most once per ",[464,1892,885],{},", on every replica. A module that must not depend on ",[464,1895,495],{}," at runtime can inject the registry by the string key ",[464,1898,1899],{},"'vercube:health'",", the way ",[464,1902,1903],{},"@vercube\u002Fstorage"," does.",[625,1906,1908],{"id":1907},"details-and-the-token","Details and the token",[452,1910,1911,1912,1915,1916,1919],{},"By default (",[464,1913,1914],{},"details: 'summary'",") the readiness response names each check and its status, never an error message, which could reveal a host name or a credential problem. ",[464,1917,1918],{},"details: 'none'"," returns only the overall status.",[452,1921,1922,1923,1926],{},"The full report, with durations, error messages and whatever a check returned as ",[464,1924,1925],{},"details",", goes to requests carrying the token:",[456,1928,1930],{"className":458,"code":1929,"filename":460,"language":461,"meta":462,"style":462},"export default defineConfig({\n  health: { token: process.env.HEALTH_TOKEN },\n});\n",[464,1931,1932,1944,1972],{"__ignoreMap":462},[467,1933,1934,1936,1938,1940,1942],{"class":469,"line":470},[467,1935,513],{"class":473},[467,1937,516],{"class":473},[467,1939,482],{"class":519},[467,1941,522],{"class":481},[467,1943,525],{"class":477},[467,1945,1946,1948,1950,1952,1955,1957,1960,1962,1965,1967,1970],{"class":469,"line":504},[467,1947,532],{"class":531},[467,1949,535],{"class":477},[467,1951,478],{"class":477},[467,1953,1954],{"class":531}," token",[467,1956,535],{"class":477},[467,1958,1959],{"class":481}," process",[467,1961,759],{"class":477},[467,1963,1964],{"class":481},"env",[467,1966,759],{"class":477},[467,1968,1969],{"class":481},"HEALTH_TOKEN ",[467,1971,1367],{"class":477},[467,1973,1974,1976,1978],{"class":469,"line":510},[467,1975,548],{"class":477},[467,1977,551],{"class":481},[467,1979,501],{"class":477},[456,1981,1983],{"className":556,"code":1982,"language":558,"meta":462,"style":462},"curl -s -H \"Authorization: Bearer $HEALTH_TOKEN\" localhost:3000\u002F_health\u002Fready | jq\n",[464,1984,1985],{"__ignoreMap":462},[467,1986,1987,1989,1991,1994,1997,2000,2003,2006,2009,2012],{"class":469,"line":470},[467,1988,566],{"class":565},[467,1990,569],{"class":494},[467,1992,1993],{"class":494}," -H",[467,1995,1996],{"class":477}," \"",[467,1998,1999],{"class":494},"Authorization: Bearer ",[467,2001,2002],{"class":481},"$HEALTH_TOKEN",[467,2004,2005],{"class":477},"\"",[467,2007,2008],{"class":494}," localhost:3000\u002F_health\u002Fready",[467,2010,2011],{"class":477}," |",[467,2013,2014],{"class":565}," jq\n",[456,2016,2020],{"className":2017,"code":2018,"language":2019,"meta":462,"style":462},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"status\": \"degraded\",\n  \"timestamp\": \"2026-11-07T10:00:00.000Z\",\n  \"checks\": {\n    \"queue:default\": {\n      \"status\": \"ok\",\n      \"critical\": true,\n      \"duration\": 1.8\n    },\n    \"storage:cache\": {\n      \"status\": \"down\",\n      \"critical\": false,\n      \"duration\": 1000.4,\n      \"error\": \"Timed out after 1000ms\"\n    }\n  }\n}\n","json",[464,2021,2022,2026,2046,2066,2078,2092,2111,2125,2139,2144,2157,2176,2189,2204,2223,2227,2231],{"__ignoreMap":462},[467,2023,2024],{"class":469,"line":470},[467,2025,525],{"class":477},[467,2027,2028,2031,2033,2035,2037,2039,2042,2044],{"class":469,"line":504},[467,2029,2030],{"class":477},"  \"",[467,2032,1068],{"class":729},[467,2034,2005],{"class":477},[467,2036,535],{"class":477},[467,2038,1996],{"class":477},[467,2040,2041],{"class":494},"degraded",[467,2043,2005],{"class":477},[467,2045,542],{"class":477},[467,2047,2048,2050,2053,2055,2057,2059,2062,2064],{"class":469,"line":510},[467,2049,2030],{"class":477},[467,2051,2052],{"class":729},"timestamp",[467,2054,2005],{"class":477},[467,2056,535],{"class":477},[467,2058,1996],{"class":477},[467,2060,2061],{"class":494},"2026-11-07T10:00:00.000Z",[467,2063,2005],{"class":477},[467,2065,542],{"class":477},[467,2067,2068,2070,2072,2074,2076],{"class":469,"line":528},[467,2069,2030],{"class":477},[467,2071,711],{"class":729},[467,2073,2005],{"class":477},[467,2075,535],{"class":477},[467,2077,922],{"class":477},[467,2079,2080,2083,2086,2088,2090],{"class":469,"line":545},[467,2081,2082],{"class":477},"    \"",[467,2084,2085],{"class":565},"queue:default",[467,2087,2005],{"class":477},[467,2089,535],{"class":477},[467,2091,922],{"class":477},[467,2093,2094,2097,2099,2101,2103,2105,2107,2109],{"class":469,"line":599},[467,2095,2096],{"class":477},"      \"",[467,2098,1068],{"class":811},[467,2100,2005],{"class":477},[467,2102,535],{"class":477},[467,2104,1996],{"class":477},[467,2106,1033],{"class":494},[467,2108,2005],{"class":477},[467,2110,542],{"class":477},[467,2112,2113,2115,2118,2120,2122],{"class":469,"line":604},[467,2114,2096],{"class":477},[467,2116,2117],{"class":811},"critical",[467,2119,2005],{"class":477},[467,2121,535],{"class":477},[467,2123,2124],{"class":477}," true,\n",[467,2126,2127,2129,2132,2134,2136],{"class":469,"line":614},[467,2128,2096],{"class":477},[467,2130,2131],{"class":811},"duration",[467,2133,2005],{"class":477},[467,2135,535],{"class":477},[467,2137,2138],{"class":811}," 1.8\n",[467,2140,2141],{"class":469,"line":859},[467,2142,2143],{"class":477},"    },\n",[467,2145,2146,2148,2151,2153,2155],{"class":469,"line":864},[467,2147,2082],{"class":477},[467,2149,2150],{"class":565},"storage:cache",[467,2152,2005],{"class":477},[467,2154,535],{"class":477},[467,2156,922],{"class":477},[467,2158,2159,2161,2163,2165,2167,2169,2172,2174],{"class":469,"line":1041},[467,2160,2096],{"class":477},[467,2162,1068],{"class":811},[467,2164,2005],{"class":477},[467,2166,535],{"class":477},[467,2168,1996],{"class":477},[467,2170,2171],{"class":494},"down",[467,2173,2005],{"class":477},[467,2175,542],{"class":477},[467,2177,2178,2180,2182,2184,2186],{"class":469,"line":1078},[467,2179,2096],{"class":477},[467,2181,2117],{"class":811},[467,2183,2005],{"class":477},[467,2185,535],{"class":477},[467,2187,2188],{"class":477}," false,\n",[467,2190,2191,2193,2195,2197,2199,2202],{"class":469,"line":1084},[467,2192,2096],{"class":477},[467,2194,2131],{"class":811},[467,2196,2005],{"class":477},[467,2198,535],{"class":477},[467,2200,2201],{"class":811}," 1000.4",[467,2203,542],{"class":477},[467,2205,2206,2208,2211,2213,2215,2217,2220],{"class":469,"line":1090},[467,2207,2096],{"class":477},[467,2209,2210],{"class":811},"error",[467,2212,2005],{"class":477},[467,2214,535],{"class":477},[467,2216,1996],{"class":477},[467,2218,2219],{"class":494},"Timed out after 1000ms",[467,2221,2222],{"class":477},"\"\n",[467,2224,2225],{"class":469,"line":1096},[467,2226,1868],{"class":477},[467,2228,2229],{"class":469,"line":1104},[467,2230,1874],{"class":477},[467,2232,2233],{"class":469,"line":1110},[467,2234,1610],{"class":477},[452,2236,2237,2240],{},[464,2238,2239],{},"details: 'full'"," without a token fails the boot. With a token it changes nothing: requests without the token still get the summary.",[625,2242,2244],{"id":2243},"paths","Paths",[452,2246,2247,2250,2251,2254,2255,535],{},[464,2248,2249],{},"path"," moves all three endpoints, ",[464,2252,2253],{},"endpoints"," moves or removes each one on its own. An override is a full path and ignores ",[464,2256,2249],{},[456,2258,2260],{"className":458,"code":2259,"filename":460,"language":461,"meta":462,"style":462},"export default defineConfig({\n  health: {\n    endpoints: {\n      live: '\u002Flivez',\n      ready: '\u002Finternal\u002Fk8s\u002Fready',\n      startup: false,\n    },\n  },\n});\n",[464,2261,2262,2274,2282,2291,2307,2323,2334,2338,2342],{"__ignoreMap":462},[467,2263,2264,2266,2268,2270,2272],{"class":469,"line":470},[467,2265,513],{"class":473},[467,2267,516],{"class":473},[467,2269,482],{"class":519},[467,2271,522],{"class":481},[467,2273,525],{"class":477},[467,2275,2276,2278,2280],{"class":469,"line":504},[467,2277,532],{"class":531},[467,2279,535],{"class":477},[467,2281,922],{"class":477},[467,2283,2284,2287,2289],{"class":469,"line":510},[467,2285,2286],{"class":531},"    endpoints",[467,2288,535],{"class":477},[467,2290,922],{"class":477},[467,2292,2293,2296,2298,2300,2303,2305],{"class":469,"line":528},[467,2294,2295],{"class":531},"      live",[467,2297,535],{"class":477},[467,2299,491],{"class":477},[467,2301,2302],{"class":494},"\u002Flivez",[467,2304,498],{"class":477},[467,2306,542],{"class":477},[467,2308,2309,2312,2314,2316,2319,2321],{"class":469,"line":545},[467,2310,2311],{"class":531},"      ready",[467,2313,535],{"class":477},[467,2315,491],{"class":477},[467,2317,2318],{"class":494},"\u002Finternal\u002Fk8s\u002Fready",[467,2320,498],{"class":477},[467,2322,542],{"class":477},[467,2324,2325,2328,2330,2332],{"class":469,"line":599},[467,2326,2327],{"class":531},"      startup",[467,2329,535],{"class":477},[467,2331,963],{"class":538},[467,2333,542],{"class":477},[467,2335,2336],{"class":469,"line":604},[467,2337,2143],{"class":477},[467,2339,2340],{"class":469,"line":614},[467,2341,1107],{"class":477},[467,2343,2344,2346,2348],{"class":469,"line":859},[467,2345,548],{"class":477},[467,2347,551],{"class":481},[467,2349,501],{"class":477},[452,2351,2352],{},"The paths are checked when the application starts. An empty or relative path, two endpoints on one path, or an application route registered on a probe path fails the boot with a message naming both, rather than one of them silently shadowing the other.",[452,2354,2355,2356,2359],{},"The probes are left out of telemetry, so traces and the devtools Requests panel are not buried under one request per probe per replica. Set ",[464,2357,2358],{},"telemetry: true"," to keep them. Only the probe paths themselves are excluded, an application route below one still produces traces.",[625,2361,2363],{"id":2362},"shutting-down-without-dropping-requests","Shutting down without dropping requests",[452,2365,2366,2367,2370],{},"During a rolling update Kubernetes sends ",[464,2368,2369],{},"SIGTERM"," and, at the same time, starts removing the pod from the endpoints that route traffic to it. That removal takes a few seconds to reach every node, and requests keep arriving meanwhile. A server that stops accepting connections right away refuses them.",[452,2372,2373,2374,2376,2377,2380,2381,2383],{},"With ",[464,2375,622],{}," on, ",[464,2378,2379],{},"app.close()"," (and ",[464,2382,2369],{},", see below) runs:",[2385,2386,2387,2398,2405,2412],"ol",{},[2388,2389,2390,2393,2394,2397],"li",{},[464,2391,2392],{},"app.state"," turns ",[464,2395,2396],{},"draining",": readiness answers 503 from now on, liveness keeps answering 200.",[2388,2399,2400,2401,2404],{},"The server keeps serving for ",[464,2402,2403],{},"shutdown.drainDelay"," milliseconds.",[2388,2406,2407,2408,2411],{},"The server stops accepting connections and waits up to ",[464,2409,2410],{},"shutdown.timeout"," for requests in flight.",[2388,2413,2414,2415,2418],{},"The ",[464,2416,2417],{},"app.onClose()"," hooks run (the queue and scheduler drain here), then the container is disposed.",[452,2420,2421,2424,2425,2427,2428,2431,2432,2434],{},[464,2422,2423],{},"health: true"," changes two defaults to make this work out of the box: ",[464,2426,2403],{}," becomes 5000 and ",[464,2429,2430],{},"shutdown.handleSignals"," becomes ",[464,2433,1498],{},". Setting either explicitly wins.",[456,2436,2438],{"className":458,"code":2437,"filename":460,"language":461,"meta":462,"style":462},"export default defineConfig({\n  health: true,\n  shutdown: {\n    drainDelay: 5_000, \u002F\u002F keep serving while the endpoint removal propagates\n    timeout: 20_000,   \u002F\u002F then wait this long for requests in flight\n  },\n});\n",[464,2439,2440,2452,2462,2471,2486,2501,2505],{"__ignoreMap":462},[467,2441,2442,2444,2446,2448,2450],{"class":469,"line":470},[467,2443,513],{"class":473},[467,2445,516],{"class":473},[467,2447,482],{"class":519},[467,2449,522],{"class":481},[467,2451,525],{"class":477},[467,2453,2454,2456,2458,2460],{"class":469,"line":504},[467,2455,532],{"class":531},[467,2457,535],{"class":477},[467,2459,539],{"class":538},[467,2461,542],{"class":477},[467,2463,2464,2467,2469],{"class":469,"line":510},[467,2465,2466],{"class":531},"  shutdown",[467,2468,535],{"class":477},[467,2470,922],{"class":477},[467,2472,2473,2476,2478,2481,2483],{"class":469,"line":528},[467,2474,2475],{"class":531},"    drainDelay",[467,2477,535],{"class":477},[467,2479,2480],{"class":811}," 5_000",[467,2482,798],{"class":477},[467,2484,2485],{"class":577}," \u002F\u002F keep serving while the endpoint removal propagates\n",[467,2487,2488,2491,2493,2496,2498],{"class":469,"line":545},[467,2489,2490],{"class":531},"    timeout",[467,2492,535],{"class":477},[467,2494,2495],{"class":811}," 20_000",[467,2497,798],{"class":477},[467,2499,2500],{"class":577},"   \u002F\u002F then wait this long for requests in flight\n",[467,2502,2503],{"class":469,"line":599},[467,2504,1107],{"class":477},[467,2506,2507,2509,2511],{"class":469,"line":604},[467,2508,548],{"class":477},[467,2510,551],{"class":481},[467,2512,501],{"class":477},[452,2514,2515,1022,2517,2520,2521,2524,2525,2527,2528,2531],{},[464,2516,2392],{},[464,2518,2519],{},"'starting' | 'ready' | 'draining' | 'closed'",") and ",[464,2522,2523],{},"drainDelay"," also work without the ",[464,2526,622],{}," routes, for a readiness route of your own. Inject ",[464,2529,2530],{},"AppLifecycle"," to read the state from a controller.",[625,2533,2535],{"id":2534},"kubernetes","Kubernetes",[456,2537,2541],{"className":2538,"code":2539,"language":2540,"meta":462,"style":462},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","apiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: api\nspec:\n  replicas: 3\n  strategy:\n    rollingUpdate: { maxUnavailable: 0, maxSurge: 1 }\n  template:\n    spec:\n      # drainDelay (5s) + shutdown.timeout (20s) + onClose hooks, with room to spare\n      terminationGracePeriodSeconds: 40\n      containers:\n        - name: api\n          image: registry.example.com\u002Fapi:1.4.0\n          ports:\n            - containerPort: 3000\n          env:\n            - name: NODE_ENV\n              value: production\n          startupProbe:\n            httpGet: { path: \u002F_health\u002Fstartup, port: 3000 }\n            periodSeconds: 2\n            failureThreshold: 30 # up to 60s for the onStart hooks\n          readinessProbe:\n            httpGet: { path: \u002F_health\u002Fready, port: 3000 }\n            periodSeconds: 5\n            timeoutSeconds: 2\n            failureThreshold: 1\n          livenessProbe:\n            httpGet: { path: \u002F_health\u002Flive, port: 3000 }\n            periodSeconds: 10\n            timeoutSeconds: 2\n            failureThreshold: 3\n","yaml",[464,2542,2543,2553,2563,2571,2580,2587,2597,2604,2634,2641,2648,2653,2663,2670,2682,2692,2699,2712,2719,2730,2740,2747,2776,2786,2800,2808,2834,2844,2854,2864,2872,2898,2908,2917],{"__ignoreMap":462},[467,2544,2545,2548,2550],{"class":469,"line":470},[467,2546,2547],{"class":531},"apiVersion",[467,2549,535],{"class":477},[467,2551,2552],{"class":494}," apps\u002Fv1\n",[467,2554,2555,2558,2560],{"class":469,"line":504},[467,2556,2557],{"class":531},"kind",[467,2559,535],{"class":477},[467,2561,2562],{"class":494}," Deployment\n",[467,2564,2565,2568],{"class":469,"line":510},[467,2566,2567],{"class":531},"metadata",[467,2569,2570],{"class":477},":\n",[467,2572,2573,2575,2577],{"class":469,"line":528},[467,2574,775],{"class":531},[467,2576,535],{"class":477},[467,2578,2579],{"class":494}," api\n",[467,2581,2582,2585],{"class":469,"line":545},[467,2583,2584],{"class":531},"spec",[467,2586,2570],{"class":477},[467,2588,2589,2592,2594],{"class":469,"line":599},[467,2590,2591],{"class":531},"  replicas",[467,2593,535],{"class":477},[467,2595,2596],{"class":811}," 3\n",[467,2598,2599,2602],{"class":469,"line":604},[467,2600,2601],{"class":531},"  strategy",[467,2603,2570],{"class":477},[467,2605,2606,2609,2611,2613,2616,2618,2621,2623,2626,2628,2631],{"class":469,"line":614},[467,2607,2608],{"class":531},"    rollingUpdate",[467,2610,535],{"class":477},[467,2612,478],{"class":477},[467,2614,2615],{"class":531}," maxUnavailable",[467,2617,535],{"class":477},[467,2619,2620],{"class":811}," 0",[467,2622,798],{"class":477},[467,2624,2625],{"class":531}," maxSurge",[467,2627,535],{"class":477},[467,2629,2630],{"class":811}," 1",[467,2632,2633],{"class":477}," }\n",[467,2635,2636,2639],{"class":469,"line":859},[467,2637,2638],{"class":531},"  template",[467,2640,2570],{"class":477},[467,2642,2643,2646],{"class":469,"line":864},[467,2644,2645],{"class":531},"    spec",[467,2647,2570],{"class":477},[467,2649,2650],{"class":469,"line":1041},[467,2651,2652],{"class":577},"      # drainDelay (5s) + shutdown.timeout (20s) + onClose hooks, with room to spare\n",[467,2654,2655,2658,2660],{"class":469,"line":1078},[467,2656,2657],{"class":531},"      terminationGracePeriodSeconds",[467,2659,535],{"class":477},[467,2661,2662],{"class":811}," 40\n",[467,2664,2665,2668],{"class":469,"line":1084},[467,2666,2667],{"class":531},"      containers",[467,2669,2570],{"class":477},[467,2671,2672,2675,2678,2680],{"class":469,"line":1090},[467,2673,2674],{"class":477},"        -",[467,2676,2677],{"class":531}," name",[467,2679,535],{"class":477},[467,2681,2579],{"class":494},[467,2683,2684,2687,2689],{"class":469,"line":1096},[467,2685,2686],{"class":531},"          image",[467,2688,535],{"class":477},[467,2690,2691],{"class":494}," registry.example.com\u002Fapi:1.4.0\n",[467,2693,2694,2697],{"class":469,"line":1104},[467,2695,2696],{"class":531},"          ports",[467,2698,2570],{"class":477},[467,2700,2701,2704,2707,2709],{"class":469,"line":1110},[467,2702,2703],{"class":477},"            -",[467,2705,2706],{"class":531}," containerPort",[467,2708,535],{"class":477},[467,2710,2711],{"class":811}," 3000\n",[467,2713,2714,2717],{"class":469,"line":1808},[467,2715,2716],{"class":531},"          env",[467,2718,2570],{"class":477},[467,2720,2721,2723,2725,2727],{"class":469,"line":1818},[467,2722,2703],{"class":477},[467,2724,2677],{"class":531},[467,2726,535],{"class":477},[467,2728,2729],{"class":494}," NODE_ENV\n",[467,2731,2732,2735,2737],{"class":469,"line":1855},[467,2733,2734],{"class":531},"              value",[467,2736,535],{"class":477},[467,2738,2739],{"class":494}," production\n",[467,2741,2742,2745],{"class":469,"line":1865},[467,2743,2744],{"class":531},"          startupProbe",[467,2746,2570],{"class":477},[467,2748,2749,2752,2754,2756,2759,2761,2764,2766,2769,2771,2774],{"class":469,"line":1871},[467,2750,2751],{"class":531},"            httpGet",[467,2753,535],{"class":477},[467,2755,478],{"class":477},[467,2757,2758],{"class":531}," path",[467,2760,535],{"class":477},[467,2762,2763],{"class":494}," \u002F_health\u002Fstartup",[467,2765,798],{"class":477},[467,2767,2768],{"class":531}," port",[467,2770,535],{"class":477},[467,2772,2773],{"class":811}," 3000",[467,2775,2633],{"class":477},[467,2777,2778,2781,2783],{"class":469,"line":1877},[467,2779,2780],{"class":531},"            periodSeconds",[467,2782,535],{"class":477},[467,2784,2785],{"class":811}," 2\n",[467,2787,2789,2792,2794,2797],{"class":469,"line":2788},24,[467,2790,2791],{"class":531},"            failureThreshold",[467,2793,535],{"class":477},[467,2795,2796],{"class":811}," 30",[467,2798,2799],{"class":577}," # up to 60s for the onStart hooks\n",[467,2801,2803,2806],{"class":469,"line":2802},25,[467,2804,2805],{"class":531},"          readinessProbe",[467,2807,2570],{"class":477},[467,2809,2811,2813,2815,2817,2819,2821,2824,2826,2828,2830,2832],{"class":469,"line":2810},26,[467,2812,2751],{"class":531},[467,2814,535],{"class":477},[467,2816,478],{"class":477},[467,2818,2758],{"class":531},[467,2820,535],{"class":477},[467,2822,2823],{"class":494}," \u002F_health\u002Fready",[467,2825,798],{"class":477},[467,2827,2768],{"class":531},[467,2829,535],{"class":477},[467,2831,2773],{"class":811},[467,2833,2633],{"class":477},[467,2835,2837,2839,2841],{"class":469,"line":2836},27,[467,2838,2780],{"class":531},[467,2840,535],{"class":477},[467,2842,2843],{"class":811}," 5\n",[467,2845,2847,2850,2852],{"class":469,"line":2846},28,[467,2848,2849],{"class":531},"            timeoutSeconds",[467,2851,535],{"class":477},[467,2853,2785],{"class":811},[467,2855,2857,2859,2861],{"class":469,"line":2856},29,[467,2858,2791],{"class":531},[467,2860,535],{"class":477},[467,2862,2863],{"class":811}," 1\n",[467,2865,2867,2870],{"class":469,"line":2866},30,[467,2868,2869],{"class":531},"          livenessProbe",[467,2871,2570],{"class":477},[467,2873,2875,2877,2879,2881,2883,2885,2888,2890,2892,2894,2896],{"class":469,"line":2874},31,[467,2876,2751],{"class":531},[467,2878,535],{"class":477},[467,2880,478],{"class":477},[467,2882,2758],{"class":531},[467,2884,535],{"class":477},[467,2886,2887],{"class":494}," \u002F_health\u002Flive",[467,2889,798],{"class":477},[467,2891,2768],{"class":531},[467,2893,535],{"class":477},[467,2895,2773],{"class":811},[467,2897,2633],{"class":477},[467,2899,2901,2903,2905],{"class":469,"line":2900},32,[467,2902,2780],{"class":531},[467,2904,535],{"class":477},[467,2906,2907],{"class":811}," 10\n",[467,2909,2911,2913,2915],{"class":469,"line":2910},33,[467,2912,2849],{"class":531},[467,2914,535],{"class":477},[467,2916,2785],{"class":811},[467,2918,2920,2922,2924],{"class":469,"line":2919},34,[467,2921,2791],{"class":531},[467,2923,535],{"class":477},[467,2925,2596],{"class":811},[452,2927,2928,2929,2932,2933,2935,2936,2938,2939,2942,2943,2946,2947,2950,2951,2954],{},"Keep ",[464,2930,2931],{},"terminationGracePeriodSeconds"," above ",[464,2934,2523],{}," plus ",[464,2937,2410],{}," plus the time your ",[464,2940,2941],{},"onClose"," hooks need, or Kubernetes kills the process with ",[464,2944,2945],{},"SIGKILL"," halfway through. Keep ",[464,2948,2949],{},"timeoutSeconds"," above the check timeout (1000 ms by default), since a check that times out still has to answer. The drain replaces the ",[464,2952,2953],{},"preStop: sleep"," hook such setups often carry; with both, the pod waits twice.",[452,2956,2957,2958,1200,2961,2964,2965,2967,2968,2971],{},"Run the server process directly (",[464,2959,2960],{},"node dist\u002Findex.mjs",[464,2962,2963],{},"exec"," in a shell entrypoint) so it receives ",[464,2966,2369],{},". A wrapper such as ",[464,2969,2970],{},"npm start"," may not forward it.",[625,2973,2975],{"id":2974},"other-runtimes","Other runtimes",[2977,2978,2979,2997,3020,3028],"ul",{},[2388,2980,2981,2984,2985,2988,2989,2992,2993,2996],{},[2982,2983,207],"strong",{}," (AWS Lambda, Azure Functions, Vercel): the probes work as ordinary routes, and there is nothing to drain because the platform routes requests. Readiness reports ",[464,2986,2987],{},"starting"," until ",[464,2990,2991],{},"app.start()"," has run; ",[464,2994,2995],{},"app.listen()"," calls it without binding a port on these platforms.",[2388,2998,2999,3001,3002,3005,3006,3008,3009,1022,3012,3015,3016,3019],{},[2982,3000,256],{},": set the option on the module, ",[464,3003,3004],{},"vercubeNitro({ health: true })",", not in ",[464,3007,460],{},", because Nitro builds its route table from it. The token is read at runtime from ",[464,3010,3011],{},"runtimeConfig.vercube.healthToken",[464,3013,3014],{},"NITRO_VERCUBE_HEALTH_TOKEN","), so it never ends up in the build; register checks in the ",[464,3017,3018],{},"setupFile",". Nitro owns the server and its shutdown, so there is no drain.",[2388,3021,3022,3027],{},[2982,3023,3024],{},[464,3025,3026],{},"vercube dev",": the worker restarts on every change and gets no default drain delay, so a reload stays instant.",[2388,3029,3030,3036],{},[2982,3031,3032,3035],{},[464,3033,3034],{},"@vercube\u002Fvite"," in development",": the Vite dev server only forwards requests to discovered controllers, so the probes are not reachable there. The production build serves them.",[625,3038,3039],{"id":1718},"Options",[630,3041,3042,3054],{},[633,3043,3044],{},[636,3045,3046,3049,3052],{},[639,3047,3048],{},"Option",[639,3050,3051],{},"Default",[639,3053],{},[649,3055,3056,3070,3093,3107,3135,3150,3164,3181],{},[636,3057,3058,3062,3067],{},[654,3059,3060],{},[464,3061,2249],{},[654,3063,3064],{},[464,3065,3066],{},"'\u002F_health'",[654,3068,3069],{},"Base path of the three endpoints",[636,3071,3072,3076,3078],{},[654,3073,3074],{},[464,3075,2253],{},[654,3077],{},[654,3079,3080,1179,3083,1179,3086,3089,3090,3092],{},[464,3081,3082],{},"live",[464,3084,3085],{},"ready",[464,3087,3088],{},"startup",": a full path, or ",[464,3091,1219],{}," to leave the endpoint out",[636,3094,3095,3099,3104],{},[654,3096,3097],{},[464,3098,711],{},[654,3100,3101],{},[464,3102,3103],{},"[]",[654,3105,3106],{},"Checks registered at startup",[636,3108,3109,3113,3118],{},[654,3110,3111],{},[464,3112,1925],{},[654,3114,3115],{},[464,3116,3117],{},"'summary'",[654,3119,3120,3121,3124,3125,3127,3128,3131,3132],{},"What requests without the token see: ",[464,3122,3123],{},"'none'"," or ",[464,3126,3117],{},". ",[464,3129,3130],{},"'full'"," requires ",[464,3133,3134],{},"token",[636,3136,3137,3141,3143],{},[654,3138,3139],{},[464,3140,3134],{},[654,3142],{},[654,3144,3145,3146,3149],{},"Requests with ",[464,3147,3148],{},"Authorization: Bearer \u003Ctoken>"," get the full report",[636,3151,3152,3156,3161],{},[654,3153,3154],{},[464,3155,1227],{},[654,3157,3158],{},[464,3159,3160],{},"1000",[654,3162,3163],{},"Default per-check timeout in milliseconds",[636,3165,3166,3170,3174],{},[654,3167,3168],{},[464,3169,885],{},[654,3171,3172],{},[464,3173,3160],{},[654,3175,3176,3177,3180],{},"Milliseconds a readiness report is reused, ",[464,3178,3179],{},"0"," to run the checks on every probe",[636,3182,3183,3188,3192],{},[654,3184,3185],{},[464,3186,3187],{},"telemetry",[654,3189,3190],{},[464,3191,1219],{},[654,3193,3194],{},"Record probe requests in telemetry and devtools",[3196,3197,3198],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":462,"searchDepth":470,"depth":504,"links":3200},[3201,3202,3206,3207,3208,3209,3210,3211],{"id":627,"depth":504,"text":628},{"id":711,"depth":504,"text":712,"children":3203},[3204,3205],{"id":1120,"depth":510,"text":1121},{"id":1482,"depth":510,"text":1483},{"id":1907,"depth":504,"text":1908},{"id":2243,"depth":504,"text":2244},{"id":2362,"depth":504,"text":2363},{"id":2534,"depth":504,"text":2535},{"id":2974,"depth":504,"text":2975},{"id":1718,"depth":504,"text":3039},"Liveness, readiness and startup probes, and zero-downtime rolling deploys","md",null,{},{"title":61,"description":3212},"Vyaay6ba93Z1fTsnveyq1UUiAyzMt9W8YWGYdNxB2BY",[3219,3221],{"title":57,"path":58,"stem":59,"description":3220,"children":-1},"Ask a running Vercube application what it looks like",{"title":78,"path":79,"stem":80,"description":3222,"children":-1},"Flexible authentication system for Vercube applications",1794396673413]