[{"data":1,"prerenderedAt":992},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Foperating\u002Fproduction-checklist":314,"\u002Fdocs\u002Foperating\u002Fproduction-checklist-surround":987},[4,38,86,149,176,219,257,273],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"Getting started","i-lucide-flag",{"title":13,"path":14,"stem":15,"icon":16},"Modules overview","\u002Fdocs\u002Fgetting-started\u002Fmodules-overview","1.docs\u002F1.getting-started\u002F2.modules-overview","i-lucide-boxes",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":23,"path":24,"stem":25,"icon":26},"License configuration","\u002Fdocs\u002Fgetting-started\u002Flicense-configuration","1.docs\u002F1.getting-started\u002F4.license-configuration","i-lucide-key-round",{"title":28,"path":29,"stem":30,"icon":31},"Your first app","\u002Fdocs\u002Fgetting-started\u002Ffirst-app","1.docs\u002F1.getting-started\u002F5.first-app","i-lucide-square-play",{"title":33,"path":34,"stem":35,"icon":36},"Project setup","\u002Fdocs\u002Fgetting-started\u002Fproject-setup","1.docs\u002F1.getting-started\u002F6.project-setup","i-lucide-package",false,{"title":39,"path":40,"stem":41,"children":42,"icon":45},"Core Concepts","\u002Fdocs\u002Fconcepts","1.docs\u002F2.concepts\u002F1.index",[43,46,51,56,61,66,71,76,81],{"title":44,"path":40,"stem":41,"icon":45},"Core concepts","i-lucide-book-open",{"title":47,"path":48,"stem":49,"icon":50},"Architecture","\u002Fdocs\u002Fconcepts\u002Farchitecture","1.docs\u002F2.concepts\u002F2.architecture","i-lucide-layers",{"title":52,"path":53,"stem":54,"icon":55},"Exactly-once semantics","\u002Fdocs\u002Fconcepts\u002Fexactly-once","1.docs\u002F2.concepts\u002F3.exactly-once","i-lucide-shield-check",{"title":57,"path":58,"stem":59,"icon":60},"Lanes and parallelism","\u002Fdocs\u002Fconcepts\u002Flanes-and-parallelism","1.docs\u002F2.concepts\u002F4.lanes-and-parallelism","i-lucide-split",{"title":62,"path":63,"stem":64,"icon":65},"State and thread-safety","\u002Fdocs\u002Fconcepts\u002Fstate-and-thread-safety","1.docs\u002F2.concepts\u002F5.state-and-thread-safety","i-lucide-lock",{"title":67,"path":68,"stem":69,"icon":70},"Event time and watermarks","\u002Fdocs\u002Fconcepts\u002Fevent-time-and-watermarks","1.docs\u002F2.concepts\u002F6.event-time-and-watermarks","i-lucide-clock",{"title":72,"path":73,"stem":74,"icon":75},"The configuration model","\u002Fdocs\u002Fconcepts\u002Fconfiguration-model","1.docs\u002F2.concepts\u002F7.configuration-model","i-lucide-sliders-horizontal",{"title":77,"path":78,"stem":79,"icon":80},"The error-handling model","\u002Fdocs\u002Fconcepts\u002Ferror-handling-model","1.docs\u002F2.concepts\u002F8.error-handling-model","i-lucide-triangle-alert",{"title":82,"path":83,"stem":84,"icon":85},"How StoatFlow differs from Kafka Streams","\u002Fdocs\u002Fconcepts\u002Fhow-stoatflow-differs-from-ks","1.docs\u002F2.concepts\u002F9.how-stoatflow-differs-from-ks","i-lucide-arrow-left-right",{"title":87,"path":88,"stem":89,"children":90,"icon":93},"Building Topologies","\u002Fdocs\u002Fbuilding","1.docs\u002F3.building\u002F1.index",[91,94,99,104,109,114,119,124,129,134,139,144],{"title":92,"path":88,"stem":89,"icon":93},"Building topologies","i-lucide-blocks",{"title":95,"path":96,"stem":97,"icon":98},"Error handling and DLQ","\u002Fdocs\u002Fbuilding\u002Ferror-handling-dlq","1.docs\u002F3.building\u002F10.error-handling-dlq","i-lucide-circle-x",{"title":100,"path":101,"stem":102,"icon":103},"State stores","\u002Fdocs\u002Fbuilding\u002Fstate-stores","1.docs\u002F3.building\u002F11.state-stores","i-lucide-database",{"title":105,"path":106,"stem":107,"icon":108},"Testing topologies","\u002Fdocs\u002Fbuilding\u002Ftesting","1.docs\u002F3.building\u002F12.testing","i-lucide-flask-conical",{"title":110,"path":111,"stem":112,"icon":113},"Sources and sinks","\u002Fdocs\u002Fbuilding\u002Fstreams-builder","1.docs\u002F3.building\u002F2.streams-builder","i-lucide-import",{"title":115,"path":116,"stem":117,"icon":118},"KStream and KTable operations","\u002Fdocs\u002Fbuilding\u002Fkstream-ktable","1.docs\u002F3.building\u002F3.kstream-ktable","i-lucide-waypoints",{"title":120,"path":121,"stem":122,"icon":123},"Aggregations","\u002Fdocs\u002Fbuilding\u002Faggregations","1.docs\u002F3.building\u002F4.aggregations","i-lucide-sigma",{"title":125,"path":126,"stem":127,"icon":128},"Windowing","\u002Fdocs\u002Fbuilding\u002Fwindowing","1.docs\u002F3.building\u002F5.windowing","i-lucide-calendar-clock",{"title":130,"path":131,"stem":132,"icon":133},"Joins","\u002Fdocs\u002Fbuilding\u002Fjoins","1.docs\u002F3.building\u002F6.joins","i-lucide-git-merge",{"title":135,"path":136,"stem":137,"icon":138},"The Processor API","\u002Fdocs\u002Fbuilding\u002Fprocessor-api","1.docs\u002F3.building\u002F7.processor-api","i-lucide-cpu",{"title":140,"path":141,"stem":142,"icon":143},"Scheduled sources","\u002Fdocs\u002Fbuilding\u002Fscheduled-sources","1.docs\u002F3.building\u002F8.scheduled-sources","i-lucide-timer",{"title":145,"path":146,"stem":147,"icon":148},"Serdes and Avro","\u002Fdocs\u002Fbuilding\u002Fserdes","1.docs\u002F3.building\u002F9.serdes","i-lucide-binary",{"title":150,"path":151,"stem":152,"children":153,"icon":75},"Configuration","\u002Fdocs\u002Fconfiguration","1.docs\u002F4.configuration\u002F1.index",[154,156,161,166,171],{"title":155,"path":151,"stem":152,"icon":75},"How configuration works",{"title":157,"path":158,"stem":159,"icon":160},"Engine configuration (:core)","\u002Fdocs\u002Fconfiguration\u002Fcore-config","1.docs\u002F4.configuration\u002F2.core-config","i-lucide-settings-2",{"title":162,"path":163,"stem":164,"icon":165},"Runtime configuration (:runtime)","\u002Fdocs\u002Fconfiguration\u002Fruntime-config","1.docs\u002F4.configuration\u002F3.runtime-config","i-lucide-server-cog",{"title":167,"path":168,"stem":169,"icon":170},"Defaults, adaptivity, and presets","\u002Fdocs\u002Fconfiguration\u002Fdefaults-and-presets","1.docs\u002F4.configuration\u002F4.defaults-and-presets","i-lucide-gauge",{"title":172,"path":173,"stem":174,"icon":175},"Kafka client configuration","\u002Fdocs\u002Fconfiguration\u002Fkafka-client-config","1.docs\u002F4.configuration\u002F5.kafka-client-config","i-lucide-plug",{"title":177,"path":178,"stem":179,"children":180,"icon":183},"Running in Production","\u002Fdocs\u002Fruntime","1.docs\u002F5.runtime\u002F1.index",[181,184,189,194,199,204,209,214],{"title":182,"path":178,"stem":179,"icon":183},"The runtime","i-lucide-server",{"title":185,"path":186,"stem":187,"icon":188},"The REST API","\u002Fdocs\u002Fruntime\u002Frest-api","1.docs\u002F5.runtime\u002F2.rest-api","i-lucide-globe",{"title":190,"path":191,"stem":192,"icon":193},"Health checks","\u002Fdocs\u002Fruntime\u002Fhealth-checks","1.docs\u002F5.runtime\u002F3.health-checks","i-lucide-heart-pulse",{"title":195,"path":196,"stem":197,"icon":198},"Metrics","\u002Fdocs\u002Fruntime\u002Fmetrics","1.docs\u002F5.runtime\u002F4.metrics","i-lucide-activity",{"title":200,"path":201,"stem":202,"icon":203},"Pause and resume","\u002Fdocs\u002Fruntime\u002Fpause-unpause","1.docs\u002F5.runtime\u002F5.pause-unpause","i-lucide-pause",{"title":205,"path":206,"stem":207,"icon":208},"Plugins and lifecycle hooks","\u002Fdocs\u002Fruntime\u002Fplugins","1.docs\u002F5.runtime\u002F6.plugins","i-lucide-puzzle",{"title":210,"path":211,"stem":212,"icon":213},"Docker images","\u002Fdocs\u002Fruntime\u002Fdocker","1.docs\u002F5.runtime\u002F7.docker","i-lucide-container",{"title":215,"path":216,"stem":217,"icon":218},"GraalVM native image","\u002Fdocs\u002Fruntime\u002Fnative-image","1.docs\u002F5.runtime\u002F8.native-image","i-lucide-zap",{"title":220,"path":221,"stem":222,"children":223,"icon":226},"Deploying & Operating","\u002Fdocs\u002Foperating","1.docs\u002F6.operating\u002F1.index",[224,227,232,237,242,247,252],{"title":225,"path":221,"stem":222,"icon":226},"Deploying and operating","i-lucide-life-buoy",{"title":228,"path":229,"stem":230,"icon":231},"Running on Kubernetes","\u002Fdocs\u002Foperating\u002Fkubernetes","1.docs\u002F6.operating\u002F2.kubernetes","i-lucide-ship",{"title":233,"path":234,"stem":235,"icon":236},"High availability","\u002Fdocs\u002Foperating\u002Fhigh-availability","1.docs\u002F6.operating\u002F3.high-availability","i-lucide-copy",{"title":238,"path":239,"stem":240,"icon":241},"Liveness and readiness probes","\u002Fdocs\u002Foperating\u002Fprobes","1.docs\u002F6.operating\u002F4.probes","i-lucide-stethoscope",{"title":243,"path":244,"stem":245,"icon":246},"Observability","\u002Fdocs\u002Foperating\u002Fobservability","1.docs\u002F6.operating\u002F5.observability","i-lucide-telescope",{"title":248,"path":249,"stem":250,"icon":251},"Tuning under load","\u002Fdocs\u002Foperating\u002Ftuning","1.docs\u002F6.operating\u002F6.tuning","i-lucide-sliders",{"title":253,"path":254,"stem":255,"icon":256},"Production checklist","\u002Fdocs\u002Foperating\u002Fproduction-checklist","1.docs\u002F6.operating\u002F7.production-checklist","i-lucide-clipboard-check",{"title":258,"path":259,"stem":260,"children":261,"icon":85},"Migrating from Kafka Streams","\u002Fdocs\u002Fmigration","1.docs\u002F7.migration\u002F1.index",[262,263,268],{"title":258,"path":259,"stem":260,"icon":85},{"title":264,"path":265,"stem":266,"icon":267},"Migration without carrying state","\u002Fdocs\u002Fmigration\u002Fwithout-data-migration","1.docs\u002F7.migration\u002F2.without-data-migration","i-lucide-sparkles",{"title":269,"path":270,"stem":271,"icon":272},"Migration carrying state","\u002Fdocs\u002Fmigration\u002Fwith-data-migration","1.docs\u002F7.migration\u002F3.with-data-migration","i-lucide-database-backup",{"title":274,"path":275,"stem":276,"children":277,"icon":279},"Reference","\u002Fdocs\u002Freference","1.docs\u002F8.reference\u002F1.index",[278,280,285,290,295,300,305,309],{"title":274,"path":275,"stem":276,"icon":279},"i-lucide-list",{"title":281,"path":282,"stem":283,"icon":284},"Configuration reference","\u002Fdocs\u002Freference\u002Fconfiguration-reference","1.docs\u002F8.reference\u002F2.configuration-reference","i-lucide-table",{"title":286,"path":287,"stem":288,"icon":289},"REST API reference","\u002Fdocs\u002Freference\u002Frest-api-reference","1.docs\u002F8.reference\u002F3.rest-api-reference","i-lucide-network",{"title":291,"path":292,"stem":293,"icon":294},"Gradle plugin reference","\u002Fdocs\u002Freference\u002Fgradle-plugin-reference","1.docs\u002F8.reference\u002F4.gradle-plugin-reference","i-lucide-box",{"title":296,"path":297,"stem":298,"icon":299},"Maven reference","\u002Fdocs\u002Freference\u002Fmaven-reference","1.docs\u002F8.reference\u002F5.maven-reference","i-simple-icons-apachemaven",{"title":301,"path":302,"stem":303,"icon":304},"Kafka Streams compatibility matrix","\u002Fdocs\u002Freference\u002Fks-compatibility-matrix","1.docs\u002F8.reference\u002F6.ks-compatibility-matrix","i-lucide-table-2",{"title":306,"path":307,"stem":308,"icon":170},"Metrics reference","\u002Fdocs\u002Freference\u002Fmetrics-reference","1.docs\u002F8.reference\u002F7.metrics-reference",{"title":310,"path":311,"stem":312,"icon":313},"Glossary","\u002Fdocs\u002Freference\u002Fglossary","1.docs\u002F8.reference\u002F8.glossary","i-lucide-book-a",{"id":315,"title":253,"body":316,"description":980,"extension":981,"meta":982,"navigation":983,"pageType":984,"path":254,"seo":985,"stem":255,"__hash__":986},"docs\u002F1.docs\u002F6.operating\u002F7.production-checklist.md",{"type":317,"value":318,"toc":966},"minimark",[319,323,354,359,372,474,494,498,504,550,554,557,586,590,593,624,628,631,674,677,680,749,753,756,798,802,805,873,877,884,925,929],[320,321,322],"p",{},"Before you put a StoatFlow application in front of production traffic, walk this list. Each item is a decision or a wiring step you can verify, and each links to the page that covers it in full — this page is the index, not the explanation.",[324,325,326],"tldr-panel",{},[327,328,329,337,348],"ul",{},[330,331,332,336],"li",{},[333,334,335],"strong",{},"What this is:"," a pre-flight checklist for going live — one row per decision, each linking to its canonical page.",[330,338,339,342,343,347],{},[333,340,341],{},"Non-negotiables:"," exactly one ",[344,345,346],"em",{},"active"," instance, a deliberate HA tier, a valid license, readiness wired to hold traffic during restoration, and a deliberate error policy.",[330,349,350,353],{},[333,351,352],{},"How to use it:"," confirm each item against the linked page; nothing here repeats the detail, it points at it.",[355,356,358],"h2",{"id":357},"deployment-and-the-ha-tier","Deployment and the HA tier",[320,360,361,362,368,369,371],{},"The one rule an operator must not break: run ",[333,363,364,365,367],{},"exactly one ",[344,366,346],{}," instance",". Two ",[344,370,346],{}," instances pointed at the same source topics corrupt state. Then choose your HA tier — fast restart (default) or the opt-in hot-standby cluster — deliberately.",[327,373,376,406,428,441,460],{"className":374},[375],"contains-task-list",[330,377,380,385,386,389,390,394,395,398,399,402,403],{"className":378},[379],"task-list-item",[381,382],"input",{"disabled":383,"type":384},true,"checkbox"," ",[333,387,388],{},"HA tier chosen deliberately."," Fast restart (default, ",[391,392,393],"code",{},"replicas: 1",") for most workloads, or the opt-in hot-standby cluster (",[391,396,397],{},"replicas: 2"," or more, ",[391,400,401],{},"ha.mode: active-standby",") for near-instant failover on large state \u002F tight RTO. → ",[404,405,233],"a",{"href":234},[330,407,409,385,411,415,416,418,419,421,422,425,426],{"className":408},[379],[381,410],{"disabled":383,"type":384},[333,412,413],{},[391,414,393],{}," on the workload (default mode), with a rollout strategy that tears the old pod down before the new one starts processing — never two ",[344,417,346],{}," concurrently. Hot standby is the exception: a readiness-gated cluster of ",[391,420,397],{}," or more. → ",[404,423,424],{"href":229},"Kubernetes",", ",[404,427,233],{"href":234},[330,429,431,385,433,436,437,425,439],{"className":430},[379],[381,432],{"disabled":383,"type":384},[333,434,435],{},"Failure mode of two active instances understood",", and why the standby is passive. → ",[404,438,47],{"href":48},[404,440,225],{"href":221},[330,442,444,385,446,453,454,456,457],{"className":443},[379],[381,445],{"disabled":383,"type":384},[333,447,448,449,452],{},"Stable ",[391,450,451],{},"application-id","."," It is the application's identity — the consumer group and changelog topics derive from it. Two ",[344,455,346],{}," processes sharing it collide. → ",[404,458,459],{"href":158},"Core configuration",[330,461,463,385,465,471,472],{"className":462},[379],[381,464],{"disabled":383,"type":384},[333,466,467,468,452],{},"Graceful shutdown on ",[391,469,470],{},"SIGTERM"," The runtime drains in-flight records and commits a final barrier before exiting; give the orchestrator's termination grace period enough headroom (and, under hot standby, room for the handoff). → ",[404,473,424],{"href":229},[475,476,479],"callout",{"color":477,"icon":478},"error","i-lucide-alert-triangle",[320,480,481,487,488,491,492],{},[333,482,483,484,486],{},"Never run two ",[344,485,346],{}," replicas of the same StoatFlow application against the same source topics."," This is the single most important item on the list. The supported way to run more than one replica is the passive ",[404,489,490],{"href":234},"hot-standby"," cluster. → ",[404,493,225],{"href":221},[355,495,497],{"id":496},"state-persistence-and-restart","State persistence and restart",[320,499,500,501,503],{},"Fast restart — the default HA tier — depends on whether the new pod starts with a warm local store or rebuilds state from the changelog cold. (Hot standby sidesteps the restore entirely by keeping one or more warm standbys ready — see ",[404,502,233],{"href":234},".)",[327,505,507,522,538],{"className":506},[375],[330,508,510,385,512,515,516,519,520],{"className":509},[379],[381,511],{"disabled":383,"type":384},[333,513,514],{},"Persistent volume for warm restart."," A ",[391,517,518],{},"PersistentVolumeClaim"," retained across restarts means restoration only reads the changelog gap since the last commit, not the whole topic. → ",[404,521,424],{"href":229},[330,523,525,385,527,530,531,425,534],{"className":524},[379],[381,526],{"disabled":383,"type":384},[333,528,529],{},"Restart window understood."," Cold-start time scales with state size; the levers are state size, disk persistence, and broker read throughput. → ",[404,532,533],{"href":249},"Tuning",[404,535,537],{"href":536},"\u002Fproduct\u002Fbenchmarks","Benchmarks",[330,539,541,385,543,546,547],{"className":540},[379],[381,542],{"disabled":383,"type":384},[333,544,545],{},"Recovery semantics confirmed"," for your chosen processing guarantee — the last successful commit barrier is the recovery point. → ",[404,548,549],{"href":53},"Exactly-once",[355,551,553],{"id":552},"processing-guarantee","Processing guarantee",[320,555,556],{},"Pick exactly-once or at-least-once deliberately — it is the central reliability decision and it shapes your latency floor.",[327,558,560,571],{"className":559},[375],[330,561,563,385,565,568,569],{"className":562},[379],[381,564],{"disabled":383,"type":384},[333,566,567],{},"Exactly-once vs at-least-once chosen"," on purpose, not by default. Exactly-once commits state, output, and offsets atomically on a barrier; at-least-once trades possible duplicates for a lower commit-cadence floor on latency. → ",[404,570,549],{"href":53},[330,572,574,385,576,579,580,583,584],{"className":573},[379],[381,575],{"disabled":383,"type":384},[333,577,578],{},"Downstream consumers match the mode."," Under exactly-once, downstream reads with ",[391,581,582],{},"read_committed"," isolation see no duplicates; under at-least-once, downstream must be idempotent or duplicate-tolerant. → ",[404,585,549],{"href":53},[355,587,589],{"id":588},"license","License",[320,591,592],{},"A production instance needs a valid runtime license, injected as a secret — never baked into an image or committed.",[327,594,596,607],{"className":595},[375],[330,597,599,385,601,604,605],{"className":598},[379],[381,600],{"disabled":383,"type":384},[333,602,603],{},"License key injected"," as an environment variable \u002F secret, not hardcoded. → ",[404,606,23],{"href":24},[330,608,610,385,612,615,616,619,620,425,622],{"className":609},[379],[381,611],{"disabled":383,"type":384},[333,613,614],{},"License health is wired into readiness."," An expired, revoked, or missing license flips ",[391,617,618],{},"\u002Fhealth\u002Fready"," to not-ready; the renewal window surfaces a warning before it bites. → ",[404,621,23],{"href":24},[404,623,190],{"href":191},[355,625,627],{"id":626},"probes","Probes",[320,629,630],{},"Readiness is the lever that keeps traffic off a process that hasn't caught up. Wire both probes.",[327,632,634,649,663],{"className":633},[375],[330,635,637,385,639,644,645,425,647],{"className":636},[379],[381,638],{"disabled":383,"type":384},[333,640,641,643],{},[391,642,618],{}," wired as the readiness probe."," It returns 503 throughout state restoration, so nothing routes to a process that isn't caught up. → ",[404,646,627],{"href":239},[404,648,190],{"href":191},[330,650,652,385,654,660,661],{"className":651},[379],[381,653],{"disabled":383,"type":384},[333,655,656,659],{},[391,657,658],{},"\u002Fhealth\u002Flive"," wired as the liveness probe."," Lets the orchestrator restart a genuinely stuck process. → ",[404,662,627],{"href":239},[330,664,666,385,668,671,672],{"className":665},[379],[381,667],{"disabled":383,"type":384},[333,669,670],{},"Probe timing tuned"," so a long but legitimate restoration isn't killed by an aggressive liveness deadline. → ",[404,673,627],{"href":239},[355,675,243],{"id":676},"observability",[320,678,679],{},"You operate one process, so its metrics and introspection endpoints are your whole picture.",[327,681,683,699,710,721],{"className":682},[375],[330,684,686,385,688,694,695,425,697],{"className":685},[379],[381,687],{"disabled":383,"type":384},[333,689,690,693],{},[391,691,692],{},"\u002Fmetrics"," scraped"," into your monitoring stack — JVM, Kafka-client, and StoatFlow internal counters in Prometheus format. → ",[404,696,195],{"href":196},[404,698,243],{"href":244},[330,700,702,385,704,707,708],{"className":701},[379],[381,703],{"disabled":383,"type":384},[333,705,706],{},"Alerts set"," for the signals that matter on a single-instance app — consumer lag, commit stalls, error rates, restoration progress. → ",[404,709,243],{"href":244},[330,711,713,385,715,718,719],{"className":712},[379],[381,714],{"disabled":383,"type":384},[333,716,717],{},"Logs collected"," — plain text by default; add a JSON encoder to your Logback config for structured ingestion, and enable MDC to correlate by lane and barrier. → ",[404,720,243],{"href":244},[330,722,724,385,726,729,730,425,733,425,736,739,740,743,744,425,747],{"className":723},[379],[381,725],{"disabled":383,"type":384},[333,727,728],{},"Introspection endpoints reachable"," for diagnosis — ",[391,731,732],{},"\u002Ftopology",[391,734,735],{},"\u002Fstate",[391,737,738],{},"\u002Fwatermarks",", and the ",[391,741,742],{},"\u002Fdebug\u002F*"," views. → ",[404,745,746],{"href":186},"REST API",[404,748,243],{"href":244},[355,750,752],{"id":751},"error-handling","Error handling",[320,754,755],{},"Decide what happens to a bad record before one arrives — silent skipping should be a choice, not a default.",[327,757,759,774,785],{"className":758},[375],[330,760,762,385,764,767,768,425,771],{"className":761},[379],[381,763],{"disabled":383,"type":384},[333,765,766],{},"Processing-exception handler chosen"," — log-and-continue, log-and-fail, or route to a dead-letter queue. → ",[404,769,770],{"href":96},"Error handling (DLQ)",[404,772,773],{"href":78},"Error-handling model",[330,775,777,385,779,782,783],{"className":776},[379],[381,778],{"disabled":383,"type":384},[333,780,781],{},"Deserialization-error handler chosen"," for malformed source records, with its own policy. → ",[404,784,770],{"href":96},[330,786,788,385,790,793,794,425,796],{"className":787},[379],[381,789],{"disabled":383,"type":384},[333,791,792],{},"DLQ topic provisioned"," if you route to one, and monitored — a filling DLQ is a signal. → ",[404,795,770],{"href":96},[404,797,243],{"href":244},[355,799,801],{"id":800},"configuration-and-tuning","Configuration and tuning",[320,803,804],{},"Start from the presets, then tune against your workload rather than guessing.",[327,806,808,820,831,845,856],{"className":807},[375],[330,809,811,385,813,816,817],{"className":810},[379],[381,812],{"disabled":383,"type":384},[333,814,815],{},"Defaults and presets reviewed"," — you know which preset you're running and why. → ",[404,818,819],{"href":168},"Defaults and presets",[330,821,823,385,825,828,829],{"className":822},[379],[381,824],{"disabled":383,"type":384},[333,826,827],{},"Resources sized"," — CPU and memory for the single process, lane count for your core count. → ",[404,830,533],{"href":249},[330,832,834,385,836,839,840,425,842],{"className":833},[379],[381,835],{"disabled":383,"type":384},[333,837,838],{},"Commit-cadence bounds set"," appropriately for your latency-vs-throughput target. The cadence self-tunes within the configured bounds; you set the bounds. → ",[404,841,533],{"href":249},[404,843,844],{"href":73},"Configuration model",[330,846,848,385,850,853,854],{"className":847},[379],[381,849],{"disabled":383,"type":384},[333,851,852],{},"Kafka client config reviewed"," — bootstrap servers, security, and any client overrides. → ",[404,855,172],{"href":173},[330,857,859,385,861,867,868,425,870],{"className":858},[379],[381,860],{"disabled":383,"type":384},[333,862,863,866],{},[391,864,865],{},"-XX:+UseG1GC"," set"," so GC pauses stay short and predictable (the Gradle plugin applies it to the Docker image; set it explicitly otherwise). → ",[404,869,18],{"href":19},[404,871,872],{"href":211},"Docker",[355,874,876],{"id":875},"custom-processor-correctness","Custom processor correctness",[320,878,879,880,883],{},"If you wrote custom ",[391,881,882],{},"Processor"," code, make sure it holds under concurrent lane execution.",[327,885,887,899,913],{"className":886},[375],[330,888,890,385,892,895,896],{"className":889},[379],[381,891],{"disabled":383,"type":384},[333,893,894],{},"Thread safety understood"," — key affinity makes per-key updates serial, but custom processors that read-modify-write across multiple keys need the runtime's key-lock utility. → ",[404,897,898],{"href":63},"State and thread safety",[330,900,902,385,904,907,908,425,910],{"className":901},[379],[381,903],{"disabled":383,"type":384},[333,905,906],{},"No cross-lane state assumptions"," in custom code. → ",[404,909,898],{"href":63},[404,911,912],{"href":136},"Processor API",[330,914,916,385,918,921,922],{"className":915},[379],[381,917],{"disabled":383,"type":384},[333,919,920],{},"Topology tested"," with the in-memory test driver before deploying. → ",[404,923,924],{"href":106},"Testing",[355,926,928],{"id":927},"where-to-go-next","Where to go next",[327,930,931,938,945,952,959],{},[330,932,933,937],{},[333,934,935],{},[404,936,424],{"href":229}," — the manifest that satisfies the deployment and persistence rows above.",[330,939,940,944],{},[333,941,942],{},[404,943,243],{"href":244}," — what to scrape and what to alert on once you're live.",[330,946,947,951],{},[333,948,949],{},[404,950,533],{"href":249}," — turn the sizing and cadence rows into concrete numbers for your workload.",[330,953,954,958],{},[333,955,956],{},[404,957,233],{"href":234}," — the opt-in hot-standby cluster, if fast restart isn't fast enough.",[330,960,961,965],{},[333,962,963],{},[404,964,225],{"href":221}," — the operating section overview, including both HA tiers in full.",{"title":967,"searchDepth":968,"depth":968,"links":969},"",2,[970,971,972,973,974,975,976,977,978,979],{"id":357,"depth":968,"text":358},{"id":496,"depth":968,"text":497},{"id":552,"depth":968,"text":553},{"id":588,"depth":968,"text":589},{"id":626,"depth":968,"text":627},{"id":676,"depth":968,"text":243},{"id":751,"depth":968,"text":752},{"id":800,"depth":968,"text":801},{"id":875,"depth":968,"text":876},{"id":927,"depth":968,"text":928},"A go-live checklist for StoatFlow — replica count, license, probes, metrics, error policies, tuning, and thread safety — each item linking to the canonical page that covers it in full.","md",{},{"icon":256},"how-to",{"title":253,"description":980},"jPP9DAv34CrbFflPxwb0qIdc-mMQGkXXGdlEQolKh78",[988,990],{"title":248,"path":249,"stem":250,"description":989,"icon":251,"children":-1},"Practical tuning for StoatFlow under load — lane count, commit-cadence bounds, the memory and uncommitted-state knobs, and RocksDB sizing for large state, each tied to the symptom that tells you to reach for it.",{"title":258,"path":259,"stem":260,"description":991,"icon":85,"children":-1},"What carries over unchanged when you move a Kafka Streams topology to StoatFlow, what changes operationally, and how to decide between a green-field cutover and a state-carrying migration.",1783713363334]