[{"data":1,"prerenderedAt":2294},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-regions":987},[4,27,63,138,306,330,912,921,969,983],{"title":5,"path":6,"stem":7,"children":8,"order":10,"icon":11},"Overview","\u002Fdocs\u002Foverview","docs\u002F1.overview\u002Findex",[9,12,18,24],{"title":5,"path":6,"stem":7,"order":10,"icon":11},1,"i-lucide-info",{"title":13,"path":14,"stem":15,"order":16,"icon":17},"Getting Started","\u002Fdocs\u002Foverview\u002Fgetting-started","docs\u002F1.overview\u002F2.getting-started",2,"i-lucide-rocket",{"title":19,"path":20,"stem":21,"order":22,"icon":23},"Contributing","\u002Fdocs\u002Foverview\u002Fcontributing","docs\u002F1.overview\u002F3.contributing",3,"i-lucide-heart",{"title":5,"path":25,"stem":26,"order":10},"\u002Fdocs\u002Foverview\u002F_dir","docs\u002F1.overview\u002F_dir",{"title":28,"path":29,"stem":30,"children":31,"page":62},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[32,37,42,47,53,59],{"title":33,"path":34,"stem":35,"order":10,"icon":36},"Events","\u002Fdocs\u002Fconcepts\u002Fevents","docs\u002F2.concepts\u002F1.events","i-lucide-zap",{"title":38,"path":39,"stem":40,"order":16,"icon":41},"Transports","\u002Fdocs\u002Fconcepts\u002Ftransports","docs\u002F2.concepts\u002F2.transports","i-lucide-network",{"title":43,"path":44,"stem":45,"order":22,"icon":46},"Module System","\u002Fdocs\u002Fconcepts\u002Fmodules","docs\u002F2.concepts\u002F3.modules","i-lucide-puzzle",{"title":48,"path":49,"stem":50,"order":51,"icon":52},"Flows","\u002Fdocs\u002Fconcepts\u002Fflows","docs\u002F2.concepts\u002F4.flows",4,"i-lucide-workflow",{"title":54,"path":55,"stem":56,"order":57,"icon":58},"Scheduler","\u002Fdocs\u002Fconcepts\u002Fscheduler","docs\u002F2.concepts\u002F5.scheduler",5,"i-lucide-clock",{"title":28,"path":60,"stem":61,"order":16},"\u002Fdocs\u002Fconcepts\u002F_dir","docs\u002F2.concepts\u002F_dir",false,{"title":64,"path":65,"stem":66,"children":67,"page":62},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides",[68,73,77,81,86,90,94,98,102,107,113,119,125,131,135],{"title":69,"path":70,"stem":71,"order":10,"icon":72},"Creating a Go App","\u002Fdocs\u002Fguides\u002Fcreating-go-app","docs\u002F3.guides\u002F1.creating-go-app","i-lucide-terminal",{"title":74,"path":75,"stem":76},"E2E tests & demo videos","\u002Fdocs\u002Fguides\u002Fe2e-and-demo-videos","docs\u002F3.guides\u002F10.e2e-and-demo-videos",{"title":78,"path":79,"stem":80,"icon":17},"Deploying to production","\u002Fdocs\u002Fguides\u002Fdeploying-to-production","docs\u002F3.guides\u002F11.deploying-to-production",{"title":82,"path":83,"stem":84,"icon":85},"Events & services dashboard","\u002Fdocs\u002Fguides\u002Fevents-dashboard","docs\u002F3.guides\u002F12.events-dashboard","i-lucide-radio-tower",{"title":87,"path":88,"stem":89,"icon":41},"Multi-server Swarm","\u002Fdocs\u002Fguides\u002Fmulti-server-swarm","docs\u002F3.guides\u002F13.multi-server-swarm",{"title":91,"path":92,"stem":93,"order":16,"icon":46},"Creating a Go Module","\u002Fdocs\u002Fguides\u002Fcreating-go-module","docs\u002F3.guides\u002F2.creating-go-module",{"title":95,"path":96,"stem":97,"order":22,"icon":36},"Adding Events","\u002Fdocs\u002Fguides\u002Fadding-events-to-go-module","docs\u002F3.guides\u002F3.adding-events-to-go-module",{"title":99,"path":100,"stem":101,"order":51,"icon":52},"FlowDSL to Service","\u002Fdocs\u002Fguides\u002Fflowdsl-to-redelay","docs\u002F3.guides\u002F4.flowdsl-to-redelay",{"title":103,"path":104,"stem":105,"order":57,"icon":106},"Choosing a Transport","\u002Fdocs\u002Fguides\u002Fchoosing-a-transport","docs\u002F3.guides\u002F5.choosing-a-transport","i-lucide-git-branch",{"title":108,"path":109,"stem":110,"order":111,"icon":112},"Module Browser (\u002Fmodules)","\u002Fdocs\u002Fguides\u002Fmodules-browser","docs\u002F3.guides\u002F6.modules-browser",6,"i-lucide-layout-dashboard",{"title":114,"path":115,"stem":116,"order":117,"icon":118},"Running Flows","\u002Fdocs\u002Fguides\u002Frunning-flows","docs\u002F3.guides\u002F7.running-flows",7,"i-lucide-play-circle",{"title":120,"path":121,"stem":122,"order":123,"icon":124},"Trace + Live Observability","\u002Fdocs\u002Fguides\u002Fobservability","docs\u002F3.guides\u002F8.observability",8,"i-lucide-activity",{"title":126,"path":127,"stem":128,"order":129,"icon":130},"Project AI Assistant","\u002Fdocs\u002Fguides\u002Fai-assistant","docs\u002F3.guides\u002F9.ai-assistant",9,"i-lucide-sparkles",{"title":132,"path":133,"stem":134},"Debug taps — trace live data through any node","\u002Fdocs\u002Fguides\u002Fdebug-taps","docs\u002F3.guides\u002F9.debug-taps",{"title":64,"path":136,"stem":137,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002F3.guides\u002F_dir",{"title":139,"path":140,"stem":141,"children":142,"page":62},"Reference","\u002Fdocs\u002Freference","docs\u002F4.reference",[143,148,152,157,162,167,172,177,181,186,191,196,202,208,214,219,224,228,234,239,245,251,256,262,268,272,276,282,287,293,297,303],{"title":144,"path":145,"stem":146,"order":10,"icon":147},"Go Framework","\u002Fdocs\u002Freference\u002Fgo-framework","docs\u002F4.reference\u002F01.go-framework","i-simple-icons-go",{"title":149,"path":150,"stem":151,"order":16,"icon":46},"Built-in Modules","\u002Fdocs\u002Freference\u002Fgo-modules","docs\u002F4.reference\u002F02.go-modules",{"title":153,"path":154,"stem":155,"order":22,"icon":156},"Domain Addon Modules","\u002Fdocs\u002Freference\u002Fgo-modules-addons","docs\u002F4.reference\u002F03.go-modules-addons","i-lucide-blocks",{"title":158,"path":159,"stem":160,"order":51,"icon":161},"Go Events","\u002Fdocs\u002Freference\u002Fgo-events","docs\u002F4.reference\u002F04.go-events","i-lucide-radio",{"title":163,"path":164,"stem":165,"order":57,"icon":166},"Email Module","\u002Fdocs\u002Freference\u002Fgo-module-email","docs\u002F4.reference\u002F05.go-module-email","i-lucide-mail",{"title":168,"path":169,"stem":170,"order":111,"icon":171},"Go Core & IR","\u002Fdocs\u002Freference\u002Fgo-core","docs\u002F4.reference\u002F06.go-core","i-lucide-cpu",{"title":173,"path":174,"stem":175,"order":117,"icon":176},"Module Definition Files","\u002Fdocs\u002Freference\u002Fgo-module-files","docs\u002F4.reference\u002F07.go-module-files","i-lucide-file-code",{"title":178,"path":179,"stem":180,"order":123,"icon":72},"CLI Reference","\u002Fdocs\u002Freference\u002Fgo-cli","docs\u002F4.reference\u002F08.go-cli",{"title":182,"path":183,"stem":184,"order":129,"icon":185},"Go Formats","\u002Fdocs\u002Freference\u002Fgo-formats","docs\u002F4.reference\u002F09.go-formats","i-lucide-file-json",{"title":187,"path":188,"stem":189,"order":190,"icon":161},"AsyncAPI Module","\u002Fdocs\u002Freference\u002Fgo-asyncapi","docs\u002F4.reference\u002F10.go-asyncapi",10,{"title":192,"path":193,"stem":194,"order":195,"icon":52},"Go FlowDSL","\u002Fdocs\u002Freference\u002Fgo-flowdsl","docs\u002F4.reference\u002F11.go-flowdsl",11,{"title":197,"path":198,"stem":199,"order":200,"icon":201},"FlowDSL Examples","\u002Fdocs\u002Freference\u002Fflowdsl-examples","docs\u002F4.reference\u002F12.flowdsl-examples",12,"i-lucide-file-code-2",{"title":203,"path":204,"stem":205,"order":206,"icon":207},"FlowDSL Sync","\u002Fdocs\u002Freference\u002Fflowdsl-sync","docs\u002F4.reference\u002F13.flowdsl-sync",13,"i-lucide-refresh-cw",{"title":209,"path":210,"stem":211,"order":212,"icon":213},"Node.js Framework","\u002Fdocs\u002Freference\u002Fjs-framework","docs\u002F4.reference\u002F14.js-framework",14,"i-simple-icons-nodedotjs",{"title":215,"path":216,"stem":217,"order":212,"icon":218},"Python Framework","\u002Fdocs\u002Freference\u002Fpy-framework","docs\u002F4.reference\u002F14.py-framework","i-simple-icons-python",{"title":220,"path":221,"stem":222,"order":223,"icon":213},"Node.js Events","\u002Fdocs\u002Freference\u002Fjs-events","docs\u002F4.reference\u002F15.js-events",15,{"title":225,"path":226,"stem":227,"order":223,"icon":218},"Python Events","\u002Fdocs\u002Freference\u002Fpy-events","docs\u002F4.reference\u002F15.py-events",{"title":229,"path":230,"stem":231,"order":232,"icon":233},"go-ai — LLM Providers, Guard, Ledger","\u002Fdocs\u002Freference\u002Fgo-ai","docs\u002F4.reference\u002F16.go-ai",16,"i-lucide-brain-circuit",{"title":235,"path":236,"stem":237,"order":238,"icon":41},"Infrastructure Modules","\u002Fdocs\u002Freference\u002Fgeneric-infra-modules","docs\u002F4.reference\u002F17.generic-infra-modules",17,{"title":240,"path":241,"stem":242,"order":243,"icon":244},"Flow Templates","\u002Fdocs\u002Freference\u002Fflow-templates","docs\u002F4.reference\u002F18.flow-templates",18,"i-lucide-library-big",{"title":246,"path":247,"stem":248,"order":249,"icon":250},"Assistant (chat + handoff)","\u002Fdocs\u002Freference\u002Fassistant","docs\u002F4.reference\u002F19.assistant",19,"i-lucide-messages-square",{"title":252,"path":253,"stem":254,"order":255,"icon":41},"Coordination","\u002Fdocs\u002Freference\u002Fcoordination","docs\u002F4.reference\u002F20.coordination",20,{"title":257,"path":258,"stem":259,"order":260,"icon":261},"Search (vector)","\u002Fdocs\u002Freference\u002Fsearch","docs\u002F4.reference\u002F21.search",21,"i-lucide-search",{"title":263,"path":264,"stem":265,"order":266,"icon":267},"Profiles","\u002Fdocs\u002Freference\u002Fprofiles","docs\u002F4.reference\u002F22.profiles",22,"i-lucide-bookmark",{"title":269,"path":270,"stem":271},"Flow-driven HTTP endpoints","\u002Fdocs\u002Freference\u002Fflow-driven-endpoints","docs\u002F4.reference\u002F23.flow-driven-endpoints",{"title":273,"path":274,"stem":275},"Deployments","\u002Fdocs\u002Freference\u002Fdeployments","docs\u002F4.reference\u002F24.deployments",{"title":277,"path":278,"stem":279,"order":280,"icon":281},"i18n (translations)","\u002Fdocs\u002Freference\u002Fi18n","docs\u002F4.reference\u002F25.i18n",25,"i-lucide-languages",{"title":283,"path":284,"stem":285,"order":286,"icon":161},"WebSockets","\u002Fdocs\u002Freference\u002Fwebsockets","docs\u002F4.reference\u002F26.websockets",26,{"title":288,"path":289,"stem":290,"order":291,"icon":292},"Localized content","\u002Fdocs\u002Freference\u002Flocalized-content","docs\u002F4.reference\u002F27.localized-content",27,"i-lucide-file-text",{"title":294,"path":295,"stem":296},"Instagram","\u002Fdocs\u002Freference\u002Finstagram","docs\u002F4.reference\u002F28.instagram",{"title":298,"path":299,"stem":300,"order":301,"icon":302},"Regions","\u002Fdocs\u002Freference\u002Fregions","docs\u002F4.reference\u002F29.regions",29,"i-lucide-globe-2",{"title":139,"path":304,"stem":305,"order":51},"\u002Fdocs\u002Freference\u002F_dir","docs\u002F4.reference\u002F_dir",{"title":307,"path":308,"stem":309,"children":310,"page":62},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F5.integrations",[311,315,319,323,327],{"title":312,"path":313,"stem":314,"order":10,"icon":52},"FlowDSL","\u002Fdocs\u002Fintegrations\u002Fflowdsl","docs\u002F5.integrations\u002F1.flowdsl",{"title":316,"path":317,"stem":318,"order":16,"icon":292},"OpenAPI","\u002Fdocs\u002Fintegrations\u002Fopenapi","docs\u002F5.integrations\u002F2.openapi",{"title":320,"path":321,"stem":322,"order":22,"icon":161},"AsyncAPI","\u002Fdocs\u002Fintegrations\u002Fasyncapi","docs\u002F5.integrations\u002F3.asyncapi",{"title":324,"path":325,"stem":326},"MCP Integration","\u002Fdocs\u002Fintegrations\u002Fmcp","docs\u002F5.integrations\u002F4.mcp",{"title":307,"path":328,"stem":329,"order":57},"\u002Fdocs\u002Fintegrations\u002F_dir","docs\u002F5.integrations\u002F_dir",{"title":331,"path":332,"stem":333,"children":334},"FlowDSL Node Catalog","\u002Fdocs\u002Fnodes","docs\u002F5.nodes\u002Findex",[335,336,340,344,348,352,356,360,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436,440,444,448,452,456,460,464,468,472,476,480,484,488,492,496,500,504,508,512,516,520,524,528,532,536,540,544,548,552,556,560,564,568,572,576,580,584,588,592,596,600,604,608,612,616,620,624,628,632,636,640,644,648,652,656,660,664,668,672,676,680,684,688,692,696,700,704,708,712,716,720,724,728,732,736,740,744,748,752,756,760,764,768,772,776,780,784,788,792,796,800,804,808,812,816,820,824,828,832,836,840,844,848,852,856,860,864,868,872,876,880,884,888,892,896,900,904,908],{"title":331,"path":332,"stem":333},{"title":337,"path":338,"stem":339,"order":57},"Node Catalog","\u002Fdocs\u002Fnodes\u002F_dir","docs\u002F5.nodes\u002F_dir",{"title":341,"path":342,"stem":343},"Record Alert","\u002Fdocs\u002Fnodes\u002Falerts_record","docs\u002F5.nodes\u002Falerts_record",{"title":345,"path":346,"stem":347},"Log to API Log","\u002Fdocs\u002Fnodes\u002Fapilog_record","docs\u002F5.nodes\u002Fapilog_record",{"title":349,"path":350,"stem":351},"ClickHouse Exec","\u002Fdocs\u002Fnodes\u002Fclickhouse_exec","docs\u002F5.nodes\u002Fclickhouse_exec",{"title":353,"path":354,"stem":355},"ClickHouse Insert","\u002Fdocs\u002Fnodes\u002Fclickhouse_insert","docs\u002F5.nodes\u002Fclickhouse_insert",{"title":357,"path":358,"stem":359},"ClickHouse Query","\u002Fdocs\u002Fnodes\u002Fclickhouse_query","docs\u002F5.nodes\u002Fclickhouse_query",{"title":361,"path":362,"stem":363},"Array Op","\u002Fdocs\u002Fnodes\u002Fcore_array-ops","docs\u002F5.nodes\u002Fcore_array-ops",{"title":365,"path":366,"stem":367},"Assert","\u002Fdocs\u002Fnodes\u002Fcore_assert","docs\u002F5.nodes\u002Fcore_assert",{"title":369,"path":370,"stem":371},"Audit Emit","\u002Fdocs\u002Fnodes\u002Fcore_audit-emit","docs\u002F5.nodes\u002Fcore_audit-emit",{"title":373,"path":374,"stem":375},"Catch","\u002Fdocs\u002Fnodes\u002Fcore_catch","docs\u002F5.nodes\u002Fcore_catch",{"title":377,"path":378,"stem":379},"DateTime","\u002Fdocs\u002Fnodes\u002Fcore_datetime","docs\u002F5.nodes\u002Fcore_datetime",{"title":381,"path":382,"stem":383},"Dead Letter","\u002Fdocs\u002Fnodes\u002Fcore_dead-letter","docs\u002F5.nodes\u002Fcore_dead-letter",{"title":385,"path":386,"stem":387},"Delay","\u002Fdocs\u002Fnodes\u002Fcore_delay","docs\u002F5.nodes\u002Fcore_delay",{"title":389,"path":390,"stem":391},"ForEach","\u002Fdocs\u002Fnodes\u002Fcore_foreach","docs\u002F5.nodes\u002Fcore_foreach",{"title":393,"path":394,"stem":395},"Idempotency Key","\u002Fdocs\u002Fnodes\u002Fcore_idempotency-key","docs\u002F5.nodes\u002Fcore_idempotency-key",{"title":397,"path":398,"stem":399},"If","\u002Fdocs\u002Fnodes\u002Fcore_if","docs\u002F5.nodes\u002Fcore_if",{"title":401,"path":402,"stem":403},"Inspect","\u002Fdocs\u002Fnodes\u002Fcore_inspect","docs\u002F5.nodes\u002Fcore_inspect",{"title":405,"path":406,"stem":407},"JSON Merge","\u002Fdocs\u002Fnodes\u002Fcore_json-merge","docs\u002F5.nodes\u002Fcore_json-merge",{"title":409,"path":410,"stem":411},"JSON Schema Validate","\u002Fdocs\u002Fnodes\u002Fcore_json-schema-validate","docs\u002F5.nodes\u002Fcore_json-schema-validate",{"title":413,"path":414,"stem":415},"JSONPath Extract","\u002Fdocs\u002Fnodes\u002Fcore_jsonpath-extract","docs\u002F5.nodes\u002Fcore_jsonpath-extract",{"title":417,"path":418,"stem":419},"Log","\u002Fdocs\u002Fnodes\u002Fcore_log","docs\u002F5.nodes\u002Fcore_log",{"title":421,"path":422,"stem":423},"Math","\u002Fdocs\u002Fnodes\u002Fcore_math","docs\u002F5.nodes\u002Fcore_math",{"title":425,"path":426,"stem":427},"Merge","\u002Fdocs\u002Fnodes\u002Fcore_merge","docs\u002F5.nodes\u002Fcore_merge",{"title":429,"path":430,"stem":431},"Metric Counter","\u002Fdocs\u002Fnodes\u002Fcore_metric-counter","docs\u002F5.nodes\u002Fcore_metric-counter",{"title":433,"path":434,"stem":435},"Metric Gauge","\u002Fdocs\u002Fnodes\u002Fcore_metric-gauge","docs\u002F5.nodes\u002Fcore_metric-gauge",{"title":437,"path":438,"stem":439},"Mock","\u002Fdocs\u002Fnodes\u002Fcore_mock","docs\u002F5.nodes\u002Fcore_mock",{"title":441,"path":442,"stem":443},"No-op","\u002Fdocs\u002Fnodes\u002Fcore_noop","docs\u002F5.nodes\u002Fcore_noop",{"title":445,"path":446,"stem":447},"Object Omit","\u002Fdocs\u002Fnodes\u002Fcore_object-omit","docs\u002F5.nodes\u002Fcore_object-omit",{"title":449,"path":450,"stem":451},"Object Pick","\u002Fdocs\u002Fnodes\u002Fcore_object-pick","docs\u002F5.nodes\u002Fcore_object-pick",{"title":453,"path":454,"stem":455},"Parallel Fan-Out","\u002Fdocs\u002Fnodes\u002Fcore_parallel","docs\u002F5.nodes\u002Fcore_parallel",{"title":457,"path":458,"stem":459},"Raise","\u002Fdocs\u002Fnodes\u002Fcore_raise","docs\u002F5.nodes\u002Fcore_raise",{"title":461,"path":462,"stem":463},"Rate Limit Check","\u002Fdocs\u002Fnodes\u002Fcore_rate-limit-check","docs\u002F5.nodes\u002Fcore_rate-limit-check",{"title":465,"path":466,"stem":467},"Regex Extract","\u002Fdocs\u002Fnodes\u002Fcore_regex-extract","docs\u002F5.nodes\u002Fcore_regex-extract",{"title":469,"path":470,"stem":471},"Require Fields","\u002Fdocs\u002Fnodes\u002Fcore_require-fields","docs\u002F5.nodes\u002Fcore_require-fields",{"title":473,"path":474,"stem":475},"Rethrow","\u002Fdocs\u002Fnodes\u002Fcore_rethrow","docs\u002F5.nodes\u002Fcore_rethrow",{"title":477,"path":478,"stem":479},"Return","\u002Fdocs\u002Fnodes\u002Fcore_return","docs\u002F5.nodes\u002Fcore_return",{"title":481,"path":482,"stem":483},"HMAC Signature Verify","\u002Fdocs\u002Fnodes\u002Fcore_signature-verify","docs\u002F5.nodes\u002Fcore_signature-verify",{"title":485,"path":486,"stem":487},"String Op","\u002Fdocs\u002Fnodes\u002Fcore_string-ops","docs\u002F5.nodes\u002Fcore_string-ops",{"title":489,"path":490,"stem":491},"Subflow Invoke","\u002Fdocs\u002Fnodes\u002Fcore_subflow-invoke","docs\u002F5.nodes\u002Fcore_subflow-invoke",{"title":493,"path":494,"stem":495},"Switch","\u002Fdocs\u002Fnodes\u002Fcore_switch","docs\u002F5.nodes\u002Fcore_switch",{"title":497,"path":498,"stem":499},"Template Render","\u002Fdocs\u002Fnodes\u002Fcore_template-render","docs\u002F5.nodes\u002Fcore_template-render",{"title":501,"path":502,"stem":503},"Throttle","\u002Fdocs\u002Fnodes\u002Fcore_throttle","docs\u002F5.nodes\u002Fcore_throttle",{"title":505,"path":506,"stem":507},"Timeout","\u002Fdocs\u002Fnodes\u002Fcore_timeout","docs\u002F5.nodes\u002Fcore_timeout",{"title":509,"path":510,"stem":511},"Type Cast","\u002Fdocs\u002Fnodes\u002Fcore_type-cast","docs\u002F5.nodes\u002Fcore_type-cast",{"title":513,"path":514,"stem":515},"Webhook Respond","\u002Fdocs\u002Fnodes\u002Fcore_webhook-respond","docs\u002F5.nodes\u002Fcore_webhook-respond",{"title":517,"path":518,"stem":519},"File Delete","\u002Fdocs\u002Fnodes\u002Ffilesys_delete","docs\u002F5.nodes\u002Ffilesys_delete",{"title":521,"path":522,"stem":523},"Directory List","\u002Fdocs\u002Fnodes\u002Ffilesys_list","docs\u002F5.nodes\u002Ffilesys_list",{"title":525,"path":526,"stem":527},"File Read","\u002Fdocs\u002Fnodes\u002Ffilesys_read","docs\u002F5.nodes\u002Ffilesys_read",{"title":529,"path":530,"stem":531},"File Stat","\u002Fdocs\u002Fnodes\u002Ffilesys_stat","docs\u002F5.nodes\u002Ffilesys_stat",{"title":533,"path":534,"stem":535},"File Write","\u002Fdocs\u002Fnodes\u002Ffilesys_write","docs\u002F5.nodes\u002Ffilesys_write",{"title":537,"path":538,"stem":539},"FTP Delete","\u002Fdocs\u002Fnodes\u002Fftp_delete","docs\u002F5.nodes\u002Fftp_delete",{"title":541,"path":542,"stem":543},"FTP Download","\u002Fdocs\u002Fnodes\u002Fftp_download","docs\u002F5.nodes\u002Fftp_download",{"title":545,"path":546,"stem":547},"FTP List","\u002Fdocs\u002Fnodes\u002Fftp_list","docs\u002F5.nodes\u002Fftp_list",{"title":549,"path":550,"stem":551},"FTP Upload","\u002Fdocs\u002Fnodes\u002Fftp_upload","docs\u002F5.nodes\u002Fftp_upload",{"title":553,"path":554,"stem":555},"HTTP DELETE","\u002Fdocs\u002Fnodes\u002Fhttp_delete","docs\u002F5.nodes\u002Fhttp_delete",{"title":557,"path":558,"stem":559},"HTTP GET","\u002Fdocs\u002Fnodes\u002Fhttp_get","docs\u002F5.nodes\u002Fhttp_get",{"title":561,"path":562,"stem":563},"HTTP POST","\u002Fdocs\u002Fnodes\u002Fhttp_post","docs\u002F5.nodes\u002Fhttp_post",{"title":565,"path":566,"stem":567},"HTTP PUT","\u002Fdocs\u002Fnodes\u002Fhttp_put","docs\u002F5.nodes\u002Fhttp_put",{"title":569,"path":570,"stem":571},"HTTP Request","\u002Fdocs\u002Fnodes\u002Fhttp_request","docs\u002F5.nodes\u002Fhttp_request",{"title":573,"path":574,"stem":575},"Fill Translations","\u002Fdocs\u002Fnodes\u002Fi18n_fill-translations","docs\u002F5.nodes\u002Fi18n_fill-translations",{"title":577,"path":578,"stem":579},"Resolve Locale","\u002Fdocs\u002Fnodes\u002Fi18n_resolve-locale","docs\u002F5.nodes\u002Fi18n_resolve-locale",{"title":581,"path":582,"stem":583},"Translate","\u002Fdocs\u002Fnodes\u002Fi18n_translate","docs\u002F5.nodes\u002Fi18n_translate",{"title":585,"path":586,"stem":587},"Mongo AGGREGATE","\u002Fdocs\u002Fnodes\u002Fmongoops_aggregate","docs\u002F5.nodes\u002Fmongoops_aggregate",{"title":589,"path":590,"stem":591},"Mongo DELETE","\u002Fdocs\u002Fnodes\u002Fmongoops_delete","docs\u002F5.nodes\u002Fmongoops_delete",{"title":593,"path":594,"stem":595},"Mongo FIND","\u002Fdocs\u002Fnodes\u002Fmongoops_find","docs\u002F5.nodes\u002Fmongoops_find",{"title":597,"path":598,"stem":599},"Mongo FIND ONE","\u002Fdocs\u002Fnodes\u002Fmongoops_find-one","docs\u002F5.nodes\u002Fmongoops_find-one",{"title":601,"path":602,"stem":603},"Mongo INSERT","\u002Fdocs\u002Fnodes\u002Fmongoops_insert","docs\u002F5.nodes\u002Fmongoops_insert",{"title":605,"path":606,"stem":607},"Mongo UPDATE","\u002Fdocs\u002Fnodes\u002Fmongoops_update","docs\u002F5.nodes\u002Fmongoops_update",{"title":609,"path":610,"stem":611},"Postgres COPY FROM","\u002Fdocs\u002Fnodes\u002Fpostgres_copy-from","docs\u002F5.nodes\u002Fpostgres_copy-from",{"title":613,"path":614,"stem":615},"Postgres Exec","\u002Fdocs\u002Fnodes\u002Fpostgres_exec","docs\u002F5.nodes\u002Fpostgres_exec",{"title":617,"path":618,"stem":619},"Postgres Query","\u002Fdocs\u002Fnodes\u002Fpostgres_query","docs\u002F5.nodes\u002Fpostgres_query",{"title":621,"path":622,"stem":623},"Postgres Transaction","\u002Fdocs\u002Fnodes\u002Fpostgres_transaction","docs\u002F5.nodes\u002Fpostgres_transaction",{"title":625,"path":626,"stem":627},"RabbitMQ Consume","\u002Fdocs\u002Fnodes\u002Frabbitmq_consume","docs\u002F5.nodes\u002Frabbitmq_consume",{"title":629,"path":630,"stem":631},"RabbitMQ Declare","\u002Fdocs\u002Fnodes\u002Frabbitmq_declare","docs\u002F5.nodes\u002Frabbitmq_declare",{"title":633,"path":634,"stem":635},"RabbitMQ Publish","\u002Fdocs\u002Fnodes\u002Frabbitmq_publish","docs\u002F5.nodes\u002Frabbitmq_publish",{"title":637,"path":638,"stem":639},"Auth Login","\u002Fdocs\u002Fnodes\u002Fredelay_auth-login","docs\u002F5.nodes\u002Fredelay_auth-login",{"title":641,"path":642,"stem":643},"Require Permission","\u002Fdocs\u002Fnodes\u002Fredelay_auth-require-permission","docs\u002F5.nodes\u002Fredelay_auth-require-permission",{"title":645,"path":646,"stem":647},"Validate Token","\u002Fdocs\u002Fnodes\u002Fredelay_auth-validate-token","docs\u002F5.nodes\u002Fredelay_auth-validate-token",{"title":649,"path":650,"stem":651},"Render Email Template","\u002Fdocs\u002Fnodes\u002Fredelay_email-render-template","docs\u002F5.nodes\u002Fredelay_email-render-template",{"title":653,"path":654,"stem":655},"Send Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send","docs\u002F5.nodes\u002Fredelay_email-send",{"title":657,"path":658,"stem":659},"Send Templated Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send-templated","docs\u002F5.nodes\u002Fredelay_email-send-templated",{"title":661,"path":662,"stem":663},"Event Source","\u002Fdocs\u002Fnodes\u002Fredelay_event-source","docs\u002F5.nodes\u002Fredelay_event-source",{"title":665,"path":666,"stem":667},"Create Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-create-group","docs\u002F5.nodes\u002Fredelay_groups-create-group",{"title":669,"path":670,"stem":671},"Delete Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-delete-group","docs\u002F5.nodes\u002Fredelay_groups-delete-group",{"title":673,"path":674,"stem":675},"Resolve Permissions","\u002Fdocs\u002Fnodes\u002Fredelay_groups-resolve-permissions","docs\u002F5.nodes\u002Fredelay_groups-resolve-permissions",{"title":677,"path":678,"stem":679},"Update Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-update-group","docs\u002F5.nodes\u002Fredelay_groups-update-group",{"title":681,"path":682,"stem":683},"HTTP Endpoint","\u002Fdocs\u002Fnodes\u002Fredelay_http-endpoint","docs\u002F5.nodes\u002Fredelay_http-endpoint",{"title":685,"path":686,"stem":687},"JSON Stream Source","\u002Fdocs\u002Fnodes\u002Fredelay_json-stream-source","docs\u002F5.nodes\u002Fredelay_json-stream-source",{"title":689,"path":690,"stem":691},"JSON → Event","\u002Fdocs\u002Fnodes\u002Fredelay_json-to-event","docs\u002F5.nodes\u002Fredelay_json-to-event",{"title":693,"path":694,"stem":695},"Kafka Produce","\u002Fdocs\u002Fnodes\u002Fredelay_kafka-produce","docs\u002F5.nodes\u002Fredelay_kafka-produce",{"title":697,"path":698,"stem":699},"Create Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-create","docs\u002F5.nodes\u002Fredelay_links-create",{"title":701,"path":702,"stem":703},"Delete Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-delete","docs\u002F5.nodes\u002Fredelay_links-delete",{"title":705,"path":706,"stem":707},"Resolve Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-resolve","docs\u002F5.nodes\u002Fredelay_links-resolve",{"title":709,"path":710,"stem":711},"LLM Chat","\u002Fdocs\u002Fnodes\u002Fredelay_llm-chat","docs\u002F5.nodes\u002Fredelay_llm-chat",{"title":713,"path":714,"stem":715},"LLM Embed","\u002Fdocs\u002Fnodes\u002Fredelay_llm-embed","docs\u002F5.nodes\u002Fredelay_llm-embed",{"title":717,"path":718,"stem":719},"LLM Guard","\u002Fdocs\u002Fnodes\u002Fredelay_llm-guard","docs\u002F5.nodes\u002Fredelay_llm-guard",{"title":721,"path":722,"stem":723},"LLM Tool Router","\u002Fdocs\u002Fnodes\u002Fredelay_llm-tool-router","docs\u002F5.nodes\u002Fredelay_llm-tool-router",{"title":725,"path":726,"stem":727},"NATS Publish","\u002Fdocs\u002Fnodes\u002Fredelay_nats-publish","docs\u002F5.nodes\u002Fredelay_nats-publish",{"title":729,"path":730,"stem":731},"Mark Notification Read","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-mark-read","docs\u002F5.nodes\u002Fredelay_notifications-mark-read",{"title":733,"path":734,"stem":735},"Send Notification","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-send","docs\u002F5.nodes\u002Fredelay_notifications-send",{"title":737,"path":738,"stem":739},"Redis Stream XADD","\u002Fdocs\u002Fnodes\u002Fredelay_redis-stream-publish","docs\u002F5.nodes\u002Fredelay_redis-stream-publish",{"title":741,"path":742,"stem":743},"S3 Copy Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-copy-object","docs\u002F5.nodes\u002Fredelay_s3-copy-object",{"title":745,"path":746,"stem":747},"S3 Delete Many","\u002Fdocs\u002Fnodes\u002Fredelay_s3-delete-many","docs\u002F5.nodes\u002Fredelay_s3-delete-many",{"title":749,"path":750,"stem":751},"S3 Head Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-head-object","docs\u002F5.nodes\u002Fredelay_s3-head-object",{"title":753,"path":754,"stem":755},"S3 List Objects","\u002Fdocs\u002Fnodes\u002Fredelay_s3-list-objects","docs\u002F5.nodes\u002Fredelay_s3-list-objects",{"title":757,"path":758,"stem":759},"Create Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-create-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-create-schedule",{"title":761,"path":762,"stem":763},"Cron Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-cron-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-cron-trigger",{"title":765,"path":766,"stem":767},"Delete Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-delete-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-delete-schedule",{"title":769,"path":770,"stem":771},"Interval Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-interval-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-interval-trigger",{"title":773,"path":774,"stem":775},"Search Query","\u002Fdocs\u002Fnodes\u002Fredelay_search-query","docs\u002F5.nodes\u002Fredelay_search-query",{"title":777,"path":778,"stem":779},"Search Upsert","\u002Fdocs\u002Fnodes\u002Fredelay_search-upsert","docs\u002F5.nodes\u002Fredelay_search-upsert",{"title":781,"path":782,"stem":783},"Delete Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-delete","docs\u002F5.nodes\u002Fredelay_settings-delete",{"title":785,"path":786,"stem":787},"Get Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-get","docs\u002F5.nodes\u002Fredelay_settings-get",{"title":789,"path":790,"stem":791},"Set Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-set","docs\u002F5.nodes\u002Fredelay_settings-set",{"title":793,"path":794,"stem":795},"Delete File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-delete","docs\u002F5.nodes\u002Fredelay_storage-delete",{"title":797,"path":798,"stem":799},"Download File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-download","docs\u002F5.nodes\u002Fredelay_storage-download",{"title":801,"path":802,"stem":803},"Generate Presigned URL","\u002Fdocs\u002Fnodes\u002Fredelay_storage-presign-url","docs\u002F5.nodes\u002Fredelay_storage-presign-url",{"title":805,"path":806,"stem":807},"Upload File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-upload","docs\u002F5.nodes\u002Fredelay_storage-upload",{"title":809,"path":810,"stem":811},"Subworkflow","\u002Fdocs\u002Fnodes\u002Fredelay_subworkflow","docs\u002F5.nodes\u002Fredelay_subworkflow",{"title":813,"path":814,"stem":815},"Activate User","\u002Fdocs\u002Fnodes\u002Fredelay_users-activate","docs\u002F5.nodes\u002Fredelay_users-activate",{"title":817,"path":818,"stem":819},"Create Pending User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-pending","docs\u002F5.nodes\u002Fredelay_users-create-pending",{"title":821,"path":822,"stem":823},"Create User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-user","docs\u002F5.nodes\u002Fredelay_users-create-user",{"title":825,"path":826,"stem":827},"Delete User","\u002Fdocs\u002Fnodes\u002Fredelay_users-delete-user","docs\u002F5.nodes\u002Fredelay_users-delete-user",{"title":829,"path":830,"stem":831},"Find User By Email","\u002Fdocs\u002Fnodes\u002Fredelay_users-find-by-email","docs\u002F5.nodes\u002Fredelay_users-find-by-email",{"title":833,"path":834,"stem":835},"Get User","\u002Fdocs\u002Fnodes\u002Fredelay_users-get-user","docs\u002F5.nodes\u002Fredelay_users-get-user",{"title":837,"path":838,"stem":839},"List Users","\u002Fdocs\u002Fnodes\u002Fredelay_users-list-users","docs\u002F5.nodes\u002Fredelay_users-list-users",{"title":841,"path":842,"stem":843},"Update User","\u002Fdocs\u002Fnodes\u002Fredelay_users-update-user","docs\u002F5.nodes\u002Fredelay_users-update-user",{"title":845,"path":846,"stem":847},"Request Email Verification (legacy)","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request","docs\u002F5.nodes\u002Fredelay_verification-request",{"title":849,"path":850,"stem":851},"Request Email Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-email","docs\u002F5.nodes\u002Fredelay_verification-request-email",{"title":853,"path":854,"stem":855},"Request SMS Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-sms","docs\u002F5.nodes\u002Fredelay_verification-request-sms",{"title":857,"path":858,"stem":859},"Verify Token","\u002Fdocs\u002Fnodes\u002Fredelay_verification-verify","docs\u002F5.nodes\u002Fredelay_verification-verify",{"title":861,"path":862,"stem":863},"Redis DEL","\u002Fdocs\u002Fnodes\u002Fredisops_del","docs\u002F5.nodes\u002Fredisops_del",{"title":865,"path":866,"stem":867},"Redis EXPIRE","\u002Fdocs\u002Fnodes\u002Fredisops_expire","docs\u002F5.nodes\u002Fredisops_expire",{"title":869,"path":870,"stem":871},"Redis GET","\u002Fdocs\u002Fnodes\u002Fredisops_get","docs\u002F5.nodes\u002Fredisops_get",{"title":873,"path":874,"stem":875},"Redis HGET","\u002Fdocs\u002Fnodes\u002Fredisops_hget","docs\u002F5.nodes\u002Fredisops_hget",{"title":877,"path":878,"stem":879},"Redis HSET","\u002Fdocs\u002Fnodes\u002Fredisops_hset","docs\u002F5.nodes\u002Fredisops_hset",{"title":881,"path":882,"stem":883},"Redis INCR","\u002Fdocs\u002Fnodes\u002Fredisops_incr","docs\u002F5.nodes\u002Fredisops_incr",{"title":885,"path":886,"stem":887},"Redis LPOP","\u002Fdocs\u002Fnodes\u002Fredisops_lpop","docs\u002F5.nodes\u002Fredisops_lpop",{"title":889,"path":890,"stem":891},"Redis LPUSH","\u002Fdocs\u002Fnodes\u002Fredisops_lpush","docs\u002F5.nodes\u002Fredisops_lpush",{"title":893,"path":894,"stem":895},"Redis PUBLISH","\u002Fdocs\u002Fnodes\u002Fredisops_publish","docs\u002F5.nodes\u002Fredisops_publish",{"title":897,"path":898,"stem":899},"Redis SET","\u002Fdocs\u002Fnodes\u002Fredisops_set","docs\u002F5.nodes\u002Fredisops_set",{"title":901,"path":902,"stem":903},"SFTP Download","\u002Fdocs\u002Fnodes\u002Fsftp_download","docs\u002F5.nodes\u002Fsftp_download",{"title":905,"path":906,"stem":907},"SFTP Upload","\u002Fdocs\u002Fnodes\u002Fsftp_upload","docs\u002F5.nodes\u002Fsftp_upload",{"title":909,"path":910,"stem":911},"Send SMS","\u002Fdocs\u002Fnodes\u002Fsms_send","docs\u002F5.nodes\u002Fsms_send",{"title":913,"path":914,"stem":915,"children":916,"page":62},"Rfcs","\u002Fdocs\u002Frfcs","docs\u002F6.rfcs",[917],{"title":918,"path":919,"stem":920},"RFC 0001 — Worker Assignment for Flow Deployments","\u002Fdocs\u002Frfcs\u002F0001-worker-assignment","docs\u002F6.rfcs\u002F0001-worker-assignment",{"title":922,"path":923,"stem":924,"children":925,"page":62},"Admin","\u002Fdocs\u002Fadmin","docs\u002F7.admin",[926,931,936,941,946,951,956,960,965],{"title":5,"path":927,"stem":928,"order":929,"icon":930},"\u002Fdocs\u002Fadmin\u002Foverview","docs\u002F7.admin\u002F00.overview",0,"i-lucide-compass",{"title":932,"path":933,"stem":934,"order":10,"icon":935},"Getting started","\u002Fdocs\u002Fadmin\u002Fgetting-started","docs\u002F7.admin\u002F01.getting-started","i-lucide-play",{"title":937,"path":938,"stem":939,"order":16,"icon":940},"Layered architecture","\u002Fdocs\u002Fadmin\u002Flayered-architecture","docs\u002F7.admin\u002F02.layered-architecture","i-lucide-layers",{"title":942,"path":943,"stem":944,"order":22,"icon":945},"Building a custom admin project","\u002Fdocs\u002Fadmin\u002Fbuilding-a-custom-admin-project","docs\u002F7.admin\u002F03.building-a-custom-admin-project","i-lucide-folder-plus",{"title":947,"path":948,"stem":949,"order":51,"icon":950},"Building admin modules","\u002Fdocs\u002Fadmin\u002Fbuilding-admin-modules","docs\u002F7.admin\u002F04.building-admin-modules","i-lucide-package-plus",{"title":952,"path":953,"stem":954,"order":57,"icon":955},"Base module reference","\u002Fdocs\u002Fadmin\u002Freference-base-modules","docs\u002F7.admin\u002F05.reference-base-modules","i-lucide-boxes",{"title":957,"path":958,"stem":959,"order":111,"icon":17},"Deployment","\u002Fdocs\u002Fadmin\u002Fdeployment","docs\u002F7.admin\u002F06.deployment",{"title":961,"path":962,"stem":963,"order":117,"icon":964},"Consuming the base layer (versioned)","\u002Fdocs\u002Fadmin\u002Fconsuming-the-base-layer","docs\u002F7.admin\u002F07.consuming-the-base-layer","i-lucide-package",{"title":966,"path":967,"stem":968,"order":117},"Admin UI","\u002Fdocs\u002Fadmin\u002F_dir","docs\u002F7.admin\u002F_dir",{"title":970,"path":971,"stem":972,"children":973,"page":62},"Services","\u002Fdocs\u002Fservices","docs\u002F8.services",[974,979],{"title":975,"path":976,"stem":977,"order":10,"icon":978},"Custom development & support services","\u002Fdocs\u002Fservices\u002Fcustom-development","docs\u002F8.services\u002F1.custom-development","i-lucide-briefcase",{"title":970,"path":980,"stem":981,"icon":978,"order":982},"\u002Fdocs\u002Fservices\u002F_dir","docs\u002F8.services\u002F_dir",80,{"title":984,"path":985,"stem":986,"order":929},"Dir","\u002Fdocs\u002F_dir","docs\u002F_dir",{"id":988,"title":298,"body":989,"description":2287,"extension":2288,"links":2289,"meta":2290,"navigation":2291,"path":299,"seo":2292,"stem":300,"__hash__":2293},"docs\u002Fdocs\u002F4.reference\u002F29.regions.md",{"type":990,"value":991,"toc":2273},"minimark",[992,997,1010,1017,1022,1029,1050,1053,1115,1127,1141,1340,1375,1386,1391,1398,1429,1440,1444,1451,1479,1733,1739,1829,1838,1842,2141,2145,2178,2182,2197,2201,2228,2232,2269],[993,994,996],"h1",{"id":995},"regions-local-reads-and-writes-in-every-region","Regions — local reads and writes in every region",[998,999,1000,1001,1005,1006,1009],"p",{},"A Redelay app can serve, say, Europe and North America from nodes in both, with\neach member's reads ",[1002,1003,1004],"strong",{},"and writes"," staying in their own region. This page is the\ndesign: the one rule every datastore follows, what the framework gives you, and\nwhat is still to come. Node placement and Swarm details are in\n",[1007,1008,87],"a",{"href":88},".",[998,1011,1012,1013,1009],{},"The overview with diagrams and measured round trips is the\n",[1007,1014,1016],{"href":1015},"\u002Fmulti-region","Multi-region page",[1018,1019,1021],"h2",{"id":1020},"the-rule-a-write-waits-for-its-majority-partner","The rule: a write waits for its majority partner",[998,1023,1024,1025,1028],{},"Every replicated store (MongoDB, Kafka, ClickHouse Keeper, Redis Cluster\nfailover) commits a write once a majority has it. The write is as fast as the\n",[1002,1026,1027],{},"nearest member of that majority",", so:",[1030,1031,1032,1040,1043],"ul",{},[1033,1034,1035,1036,1039],"li",{},"put a write's majority ",[1002,1037,1038],{},"inside the region"," that writes it;",[1033,1041,1042],{},"never let a write wait for a member across an ocean;",[1033,1044,1045,1046,1049],{},"add one ",[1002,1047,1048],{},"tie-breaker vote at a third site"," (non-electable) so a region keeps\na majority when one of its nodes is down — it never slows normal writes,\nbecause a majority of three is the primary plus the fastest acknowledgement.",[998,1051,1052],{},"Measured on a two-region deployment (Europe ↔ North America, ~120 ms apart):",[1054,1055,1056,1071],"table",{},[1057,1058,1059],"thead",{},[1060,1061,1062,1065,1068],"tr",{},[1063,1064],"th",{},[1063,1066,1067],{},"one replica set, primary in EU",[1063,1069,1070],{},"regional shards",[1072,1073,1074,1088,1099],"tbody",{},[1060,1075,1076,1080,1083],{},[1077,1078,1079],"td",{},"NA member: 2 reads + 3 majority writes",[1077,1081,1082],{},"~700 ms",[1077,1084,1085],{},[1002,1086,1087],{},"~13 ms",[1060,1089,1090,1093,1096],{},[1077,1091,1092],{},"EU member: same request",[1077,1094,1095],{},"~85 ms",[1077,1097,1098],{},"~96 ms",[1060,1100,1101,1109,1112],{},[1077,1102,1103,1104,1108],{},"Kafka publish, ",[1105,1106,1107],"code",{},"acks=all",", a replica across the ocean",[1077,1110,1111],{},"~1 s",[1077,1113,1114],{},"35 ms (replicas in one region)",[1018,1116,1118,1119,1122,1123,1126],{"id":1117},"mongodb-regional-shards-runtimemongo-runtimeregion","MongoDB — regional shards (",[1105,1120,1121],{},"runtime\u002Fmongo",", ",[1105,1124,1125],{},"runtime\u002Fregion",")",[998,1128,1129,1130,1133,1134,1137,1138,1009],{},"Member-owned collections are zone-sharded on ",[1105,1131,1132],{},"{home_region: 1, user_id: 1}",";\neach zone's shard has its primary and write majority in its region. Global data\n(catalogue, CMS, settings) stays unsharded on the primary shard and is read\nfrom local secondaries with ",[1105,1135,1136],{},"readPreference=nearest&maxStalenessSeconds=90",".\nPublic rows in a mixed collection use ",[1105,1139,1140],{},"home_region: \"global\"",[1054,1142,1143,1156],{},[1057,1144,1145],{},[1060,1146,1147,1150,1153],{},[1063,1148,1149],{},"Piece",[1063,1151,1152],{},"Since",[1063,1154,1155],{},"Use",[1072,1157,1158,1177,1194,1206,1222,1235,1250,1265,1286,1297,1311,1326],{},[1060,1159,1160,1168,1171],{},[1077,1161,1162,1122,1165],{},[1105,1163,1164],{},"region.ForCountry",[1105,1166,1167],{},"region.Validate",[1077,1169,1170],{},"go-framework v0.19.0",[1077,1172,1173,1174,1126],{},"assign a member's home region once, at sign-up (",[1105,1175,1176],{},"HOME_REGIONS",[1060,1178,1179,1188,1191],{},[1077,1180,1181,1184,1185],{},[1105,1182,1183],{},"rtmongo.WithHomeRegion"," \u002F ",[1105,1186,1187],{},"HomeRegionMiddleware",[1077,1189,1190],{},"v0.18.0",[1077,1192,1193],{},"carry the member's region on the request",[1060,1195,1196,1201,1203],{},[1077,1197,1198],{},[1105,1199,1200],{},"rtmongo.Own(ctx, coll, filter)",[1077,1202,1190],{},[1077,1204,1205],{},"read the member's own data from their home shard's primary",[1060,1207,1208,1213,1215],{},[1077,1209,1210],{},[1105,1211,1212],{},"rtmongo.StampRegionStrict(ctx, doc)",[1077,1214,1190],{},[1077,1216,1217,1218,1221],{},"set ",[1105,1219,1220],{},"home_region"," on inserts (an explicit value wins)",[1060,1223,1224,1229,1232],{},[1077,1225,1226],{},[1105,1227,1228],{},"region.Home(stored)",[1077,1230,1231],{},"v0.25.0",[1077,1233,1234],{},"the region to use for a member: the stored one, or the default for members from before home regions",[1060,1236,1237,1242,1244],{},[1077,1238,1239],{},[1105,1240,1241],{},"rtmongo.OwnFilter(ctx, filter)",[1077,1243,1231],{},[1077,1245,1246,1247],{},"write filters (update, delete, upsert) of the member's own data — the region is added only with ",[1105,1248,1249],{},"MONGO_HOME_REGION_FILTER=true",[1060,1251,1252,1257,1259],{},[1077,1253,1254],{},[1105,1255,1256],{},"rtmongo.BackfillRegion(ctx, spec)",[1077,1258,1231],{},[1077,1260,1261,1262,1264],{},"migration body: ",[1105,1263,1220],{}," on every row from its member (ObjectID or hex ids); members without one and orphans → the default; safe to run again",[1060,1266,1267,1272,1275],{},[1077,1268,1269],{},[1105,1270,1271],{},"rtmongo.NewRegionLookup(users).With(ctx, uid)",[1077,1273,1274],{},"v0.26.0",[1077,1276,1277,1278,1281,1282,1285],{},"writes outside the member's request (workers, links in emails, migrations, ops synced later): stamp with the ",[1002,1279,1280],{},"owner's"," region; cached 10 min, ",[1105,1283,1284],{},"Forget"," after moving a member",[1060,1287,1288,1292,1294],{},[1077,1289,1290],{},[1105,1291,1249],{},[1077,1293,1190],{},[1077,1295,1296],{},"add the region to filters — only after the backfill",[1060,1298,1299,1305,1308],{},[1077,1300,1301,1304],{},[1105,1302,1303],{},"rtmongo.Nearest(ctx)"," (single-document reads since v0.16.6) + recent-write marker",[1077,1306,1307],{},"v0.17.0",[1077,1309,1310],{},"local reads that still see the member's own fresh writes",[1060,1312,1313,1318,1320],{},[1077,1314,1315],{},[1105,1316,1317],{},"mongotest.AssertTargeted",[1077,1319,1190],{},[1077,1321,1322,1323,1126],{},"tests prove a query hits one shard (through a real ",[1105,1324,1325],{},"mongos",[1060,1327,1328,1334,1337],{},[1077,1329,1330,1333],{},[1105,1331,1332],{},"rtmongo.W1(coll)"," (last write majority)",[1077,1335,1336],{},"v0.24.0",[1077,1338,1339],{},"see below",[998,1341,1342,1345,1346,1349,1350,1353,1354,1357,1358,1360,1361,1363,1364,1367,1368,1370,1371,1374],{},[1002,1343,1344],{},"Rollout order per collection:"," (1) stamp new rows (",[1105,1347,1348],{},"StampRegionStrict",", write\nfilters through ",[1105,1351,1352],{},"OwnFilter","); (2) backfill (",[1105,1355,1356],{},"BackfillRegion"," in a migration) and\ncreate the shard-key index ",[1105,1359,1132],{},"; (3) run the backfill\nagain, then ",[1105,1362,1249],{}," — from here every filter carries the\nshard key, which upserts on a sharded collection need; (4) rebuild unique indexes\nwith the shard key first, ",[1105,1365,1366],{},"shardCollection",", zone ranges. Turning the switch on\nbefore the backfill would make upserts miss older rows and insert copies. Apps\nconnect through ",[1105,1369,1325],{}," before step 4: once chunks move, a client connected\ndirectly to one shard sees only part of the data (MongoDB 8.0 refuses direct\noperations on a shard unless the user has ",[1105,1372,1373],{},"directShardOperations",").",[998,1376,1377,1378,1381,1382,1385],{},"Settings that matter: ",[1105,1379,1380],{},"settings.chainingAllowed: false"," on every replica set (a\nsecondary syncing through a tie-breaker doubled majority-write time in our\nbenchmark), identity (email, password, sessions) ",[1002,1383,1384],{},"unsharded"," (a unique index on\na sharded collection must start with the shard key, so a global unique email\ncannot live there), and backups per shard plus config servers.",[1387,1388,1390],"h3",{"id":1389},"last-write-majority-last-write-majority","Last write majority {#last-write-majority}",[998,1392,1393,1394,1397],{},"Writes to one replica set are applied in order. A request that writes several\ntimes only needs to wait for the ",[1002,1395,1396],{},"last"," one: once it is majority-committed,\nevery earlier write on that primary is too.",[1399,1400,1405],"pre",{"className":1401,"code":1402,"language":1403,"meta":1404,"style":1404},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","fast := rtmongo.W1(orders)                    \u002F\u002F w:1 — no wait for the majority\n_, _ = fast.InsertOne(ctx, line1)\n_, _ = fast.UpdateOne(ctx, f, u)\n_, err := orders.InsertOne(ctx, summary)       \u002F\u002F the collection's own concern (majority): waits once\n","go","",[1105,1406,1407,1414,1419,1424],{"__ignoreMap":1404},[1408,1409,1411],"span",{"class":1410,"line":10},"line",[1408,1412,1413],{},"fast := rtmongo.W1(orders)                    \u002F\u002F w:1 — no wait for the majority\n",[1408,1415,1416],{"class":1410,"line":16},[1408,1417,1418],{},"_, _ = fast.InsertOne(ctx, line1)\n",[1408,1420,1421],{"class":1410,"line":22},[1408,1422,1423],{},"_, _ = fast.UpdateOne(ctx, f, u)\n",[1408,1425,1426],{"class":1410,"line":51},[1408,1427,1428],{},"_, err := orders.InsertOne(ctx, summary)       \u002F\u002F the collection's own concern (majority): waits once\n",[998,1430,1431,1432,1435,1436,1439],{},"Three majority waits of ~30 ms become one. Only within ONE replica set (one\nshard): writes that land on different shards each need their own majority\nwrite. If the primary fails before the last write is acknowledged, the earlier\n",[1105,1433,1434],{},"w:1"," writes may be rolled back with it — the request fails either way, as it\nwould have with three majority writes. Prefer ",[1105,1437,1438],{},"BulkWrite"," when the writes are to\none collection.",[1018,1441,1443],{"id":1442},"adopting-home-regions-in-an-app-adopting","Adopting home regions in an app {#adopting}",[998,1445,1446,1447,1450],{},"Any number of regions: ",[1105,1448,1449],{},"HOME_REGIONS=\"na=US,CA;apac=JP,AU,SG\""," plus the default\ngives three, each its own zone (one shard can hold several zones until a region\ngets its own); nothing in the framework assumes two (tested with eu\u002Fna\u002Fapac).",[998,1452,1453,1454,1457,1458,1460,1461,1464,1465,1467,1468,1470,1471,1474,1475,1478],{},"Home regions are ",[1002,1455,1456],{},"optional",". A single-region project sets nothing: with\n",[1105,1459,1176],{}," unset, ",[1105,1462,1463],{},"region.Enabled()"," is false and every helper below is a\nno-op (no users lookup, no ",[1105,1466,1220],{}," field, no index), so framework\nmodules can call them unconditionally. A multi-region project turns them on\nwith ",[1105,1469,1176],{}," (+ ",[1105,1472,1473],{},"HOME_REGION_DEFAULT","); ",[1105,1476,1477],{},"HOME_REGIONS_ENABLED=false","\nturns them off again.",[1054,1480,1481,1493],{},[1057,1482,1483],{},[1060,1484,1485,1491],{},[1063,1486,1487,1488,1490],{},"Helper (",[1105,1489,1121],{},", go-framework ≥ v0.28.0)",[1063,1492,1155],{},[1072,1494,1495,1509,1526,1547,1559,1573,1586,1599,1612,1628,1642,1654,1677,1706],{},[1060,1496,1497,1502],{},[1077,1498,1499],{},[1105,1500,1501],{},"Owner(ctx, coll, uid)",[1077,1503,1504,1505,1508],{},"ctx with the ",[1002,1506,1507],{},"row owner's"," region — in their request, a worker, an email link, an op synced later; never the caller's. A failed lookup is an error",[1060,1510,1511,1519],{},[1077,1512,1513,1184,1516],{},[1105,1514,1515],{},"StampOwner(ctx, coll, uid, doc)",[1105,1517,1518],{},"OwnerRegion",[1077,1520,1521,1522,1525],{},"the owner's region on an insert \u002F ",[1105,1523,1524],{},"$setOnInsert"," \u002F a struct field",[1060,1527,1528,1533],{},[1077,1529,1530],{},[1105,1531,1532],{},"Regions(db)",[1077,1534,1535,1536,1539,1540,1543,1544,1126],{},"the shared, cached ",[1105,1537,1538],{},"RegionLookup"," behind them (",[1105,1541,1542],{},"USERS_COLLECTION",", default ",[1105,1545,1546],{},"users",[1060,1548,1549,1554],{},[1077,1550,1551],{},[1105,1552,1553],{},"OwnFilter(ctx, filter)",[1077,1555,1556,1557],{},"upsert and update filters: the region only once ",[1105,1558,1249],{},[1060,1560,1561,1566],{},[1077,1562,1563],{},[1105,1564,1565],{},"PrepareRegionCollection(ctx, coll, owner)",[1077,1567,1568,1569,1572],{},"migration body: backfill from users + the ",[1105,1570,1571],{},"{home_region, owner}"," index",[1060,1574,1575,1580],{},[1077,1576,1577],{},[1105,1578,1579],{},"ReplaceUniqueIndex(ctx, coll, want, old)",[1077,1581,1582,1583,1585],{},"migration body: a unique index keyed ",[1105,1584,1220],{}," first (created before the old one is dropped)",[1060,1587,1588,1593],{},[1077,1589,1590],{},[1105,1591,1592],{},"CheckShardable(ctx, coll, owner)",[1077,1594,1595,1596,1126],{},"every reason the collection cannot be sharded yet (",[1105,1597,1598],{},"ErrNotShardable",[1060,1600,1601,1606],{},[1077,1602,1603],{},[1105,1604,1605],{},"ShardByRegion(ctx, coll, owner, zones…)",[1077,1607,1608,1609,1611],{},"operator step: ",[1105,1610,1366],{}," + one zone range per region, idempotent",[1060,1613,1614,1625],{},[1077,1615,1616,1184,1619,1184,1622],{},[1105,1617,1618],{},"mongotest.ShardedDB(t)",[1105,1620,1621],{},"mongotest.ShardByRegion(t, …)",[1105,1623,1624],{},"AssertTargeted",[1077,1626,1627],{},"tests on a real sharded cluster",[1060,1629,1630,1635],{},[1077,1631,1632],{},[1105,1633,1634],{},"crud.NewMongoCRUD(…).WithOwnerRegion(func(T) string)",[1077,1636,1637,1638,1641],{},"v0.29.0: ",[1105,1639,1640],{},"Create"," stamps the owner's region (opt-in per store)",[1060,1643,1644,1649],{},[1077,1645,1646],{},[1105,1647,1648],{},"crud.NewUserSingleton(…).WithHomeRegion()",[1077,1650,1651,1652],{},"v0.29.0: seed\u002Freplace stamp the user's region; every filter on the user's row through ",[1105,1653,1352],{},[1060,1655,1656,1659],{},[1077,1657,1658],{},"users module",[1077,1660,1637,1661,1664,1665,1668,1669,1672,1673,1676],{},[1105,1662,1663],{},"User.HomeRegion"," set at creation — explicit ",[1105,1666,1667],{},"UserCreateInput.HomeRegion"," (internal), else the request's country (",[1105,1670,1671],{},"region.CountryMiddleware",", mounted by the server when home regions are on), else the default; migration ",[1105,1674,1675],{},"users-20261017-home-region"," backfills the default — registered only with home regions on, so the ledger never marks it applied before a deployment opts in; an explicit region that is not configured is an error",[1060,1678,1679,1682],{},[1077,1680,1681],{},"auth module",[1077,1683,1684,1685,1688,1689,1184,1692,1695,1696,1699,1700,1702,1703,1705],{},"v0.29.0: the access token carries ",[1105,1686,1687],{},"hr"," (the member's home region); ",[1105,1690,1691],{},"AuthMiddleware",[1105,1693,1694],{},"OptionalAuth"," put it on the request (",[1105,1697,1698],{},"WithHomeRegion","). A token without ",[1105,1701,1687],{}," (issued before) adds nothing: reads stay unscoped, writes still look up the owner. After a member is moved, ",[1105,1704,1687],{}," is stale for at most one access-token TTL — fine, a move is a data move done in a window",[1060,1707,1708,1716],{},[1077,1709,1710,1184,1713],{},[1105,1711,1712],{},"recentwrite.FromEnv()",[1105,1714,1715],{},"InstallFromEnv()",[1077,1717,1718,1719,1722,1723,1184,1726,1184,1729,1732],{},"v0.29.0: the per-user recent-write marker from ",[1105,1720,1721],{},"REDIS_SHARED_*"," (then ",[1105,1724,1725],{},"rtmongo.Request",[1105,1727,1728],{},"ForUser",[1105,1730,1731],{},"RecentWriteMiddleware"," route a member's own reads: primary right after their write, nearest otherwise)",[998,1734,1735,1738],{},[1002,1736,1737],{},"Order, per app"," (each step its own release; verify by behaviour):",[1740,1741,1742,1772,1785,1807,1823],"ol",{},[1033,1743,1744,1747,1748,1750,1751,1753,1754,1757,1758,1760,1761,1764,1765,1767,1768,1771],{},[1002,1745,1746],{},"Expand."," Members get ",[1105,1749,1220],{}," at sign-up (",[1105,1752,1164],{},") and a\nbackfill (none → default). Every write of a member collection stamps the\nowner's region (",[1105,1755,1756],{},"Owner"," + ",[1105,1759,1348],{},", or ",[1105,1762,1763],{},"StampOwner",") and its\nupsert filters go through ",[1105,1766,1352],{},". Migrations:\n",[1105,1769,1770],{},"PrepareRegionCollection"," per collection.",[1033,1773,1774,1777,1778,1780,1781,1784],{},[1002,1775,1776],{},"Recheck + filter."," The same migration under a new id (rows the previous\nimage wrote during the roll), then ",[1105,1779,1249],{},". Run the\ntest suite with the flag ",[1002,1782,1783],{},"on"," first: a row without the region makes an\nupsert miss it and fail on a unique index.",[1033,1786,1787,1790,1791,1794,1795,1798,1799,1802,1803,1806],{},[1002,1788,1789],{},"Shard-ready."," Member collections use the ",[1002,1792,1793],{},"simple collation"," (store\nnames lowercased): a non-simple collation on a collection sharded on a\nstring key goes to every shard. Unique indexes become ",[1105,1796,1797],{},"{home_region, owner, …}"," with simple collation (",[1105,1800,1801],{},"ReplaceUniqueIndex",") — MongoDB refuses\nto shard otherwise. ",[1105,1804,1805],{},"CheckShardable"," must return nil for each collection.",[1033,1808,1809,1812,1813,1815,1816,1818,1819,1822],{},[1002,1810,1811],{},"Shard."," Through ",[1105,1814,1325],{}," only (every client of the database must connect\nthrough mongos first; MongoDB 8 refuses direct operations on a shard\nwithout ",[1105,1817,1373],{},"). ",[1105,1820,1821],{},"ShardByRegion"," with the zones whose\nshards should hold data now — add a region's range only when it has\nmembers: an empty range on a remote shard turns every query without the\nshard key into a cross-region round trip.",[1033,1824,1825,1828],{},[1002,1826,1827],{},"Move"," members of a region (add its range; the balancer moves chunks).",[998,1830,1831,1834,1835,1837],{},[1002,1832,1833],{},"Per collection, check:"," owner field and type (ObjectID or hex string — both\nmatch); every insert path, including background and late writers (stamp from\nthe parent row's owner: a journal op from its session's owner); every upsert\nfilter; unique indexes; queries without the shard key (fine, but they reach\nevery shard holding chunks); TTL indexes (fine). Identity (users, sessions,\ntokens) stays unsharded: a global unique email cannot live on a sharded\ncollection. Catalogue rows in a mixed collection get ",[1105,1836,1140],{},"\nin their own migration first.",[1387,1839,1841],{"id":1840},"testing-on-a-sharded-cluster-testing-sharded","Testing on a sharded cluster {#testing-sharded}",[1399,1843,1847],{"className":1844,"code":1845,"language":1846,"meta":1404,"style":1404},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker network create shtest\ndocker run -d --name sht-cfg --network shtest mongo:8 --configsvr --replSet cfgrs --port 27019 --bind_ip_all\ndocker run -d --name sht-a   --network shtest mongo:8 --shardsvr  --replSet rsa   --port 27018 --bind_ip_all\ndocker run -d --name sht-b   --network shtest mongo:8 --shardsvr  --replSet rsb   --port 27018 --bind_ip_all\ndocker exec sht-cfg mongosh --port 27019 --eval \"rs.initiate({_id:'cfgrs',configsvr:true,members:[{_id:0,host:'sht-cfg:27019'}]})\"\ndocker exec sht-a   mongosh --port 27018 --eval \"rs.initiate({_id:'rsa',members:[{_id:0,host:'sht-a:27018'}]})\"\ndocker exec sht-b   mongosh --port 27018 --eval \"rs.initiate({_id:'rsb',members:[{_id:0,host:'sht-b:27018'}]})\"\ndocker run -d --name sht-mongos --network shtest -p 27100:27017 mongo:8 mongos --configdb cfgrs\u002Fsht-cfg:27019 --bind_ip_all --port 27017\ndocker exec sht-mongos mongosh --eval \"sh.addShard('rsa\u002Fsht-a:27018'); sh.addShard('rsb\u002Fsht-b:27018'); sh.addShardToZone('rsa','eu'); sh.addShardToZone('rsa','global'); sh.addShardToZone('rsb','na')\"\nREDELAY_TEST_MONGO_SHARDED_URI='mongodb:\u002F\u002Flocalhost:27100' go test .\u002F...\n","bash",[1105,1848,1849,1865,1909,1946,1978,2007,2031,2054,2096,2115],{"__ignoreMap":1404},[1408,1850,1851,1855,1859,1862],{"class":1410,"line":10},[1408,1852,1854],{"class":1853},"sBMFI","docker",[1408,1856,1858],{"class":1857},"sfazB"," network",[1408,1860,1861],{"class":1857}," create",[1408,1863,1864],{"class":1857}," shtest\n",[1408,1866,1867,1869,1872,1875,1878,1881,1884,1887,1890,1893,1896,1899,1902,1906],{"class":1410,"line":16},[1408,1868,1854],{"class":1853},[1408,1870,1871],{"class":1857}," run",[1408,1873,1874],{"class":1857}," -d",[1408,1876,1877],{"class":1857}," --name",[1408,1879,1880],{"class":1857}," sht-cfg",[1408,1882,1883],{"class":1857}," --network",[1408,1885,1886],{"class":1857}," shtest",[1408,1888,1889],{"class":1857}," mongo:8",[1408,1891,1892],{"class":1857}," --configsvr",[1408,1894,1895],{"class":1857}," --replSet",[1408,1897,1898],{"class":1857}," cfgrs",[1408,1900,1901],{"class":1857}," --port",[1408,1903,1905],{"class":1904},"sbssI"," 27019",[1408,1907,1908],{"class":1857}," --bind_ip_all\n",[1408,1910,1911,1913,1915,1917,1919,1922,1925,1927,1929,1932,1935,1938,1941,1944],{"class":1410,"line":22},[1408,1912,1854],{"class":1853},[1408,1914,1871],{"class":1857},[1408,1916,1874],{"class":1857},[1408,1918,1877],{"class":1857},[1408,1920,1921],{"class":1857}," sht-a",[1408,1923,1924],{"class":1857},"   --network",[1408,1926,1886],{"class":1857},[1408,1928,1889],{"class":1857},[1408,1930,1931],{"class":1857}," --shardsvr",[1408,1933,1934],{"class":1857},"  --replSet",[1408,1936,1937],{"class":1857}," rsa",[1408,1939,1940],{"class":1857},"   --port",[1408,1942,1943],{"class":1904}," 27018",[1408,1945,1908],{"class":1857},[1408,1947,1948,1950,1952,1954,1956,1959,1961,1963,1965,1967,1969,1972,1974,1976],{"class":1410,"line":51},[1408,1949,1854],{"class":1853},[1408,1951,1871],{"class":1857},[1408,1953,1874],{"class":1857},[1408,1955,1877],{"class":1857},[1408,1957,1958],{"class":1857}," sht-b",[1408,1960,1924],{"class":1857},[1408,1962,1886],{"class":1857},[1408,1964,1889],{"class":1857},[1408,1966,1931],{"class":1857},[1408,1968,1934],{"class":1857},[1408,1970,1971],{"class":1857}," rsb",[1408,1973,1940],{"class":1857},[1408,1975,1943],{"class":1904},[1408,1977,1908],{"class":1857},[1408,1979,1980,1982,1985,1987,1990,1992,1994,1997,2001,2004],{"class":1410,"line":57},[1408,1981,1854],{"class":1853},[1408,1983,1984],{"class":1857}," exec",[1408,1986,1880],{"class":1857},[1408,1988,1989],{"class":1857}," mongosh",[1408,1991,1901],{"class":1857},[1408,1993,1905],{"class":1904},[1408,1995,1996],{"class":1857}," --eval",[1408,1998,2000],{"class":1999},"sMK4o"," \"",[1408,2002,2003],{"class":1857},"rs.initiate({_id:'cfgrs',configsvr:true,members:[{_id:0,host:'sht-cfg:27019'}]})",[1408,2005,2006],{"class":1999},"\"\n",[1408,2008,2009,2011,2013,2015,2018,2020,2022,2024,2026,2029],{"class":1410,"line":111},[1408,2010,1854],{"class":1853},[1408,2012,1984],{"class":1857},[1408,2014,1921],{"class":1857},[1408,2016,2017],{"class":1857},"   mongosh",[1408,2019,1901],{"class":1857},[1408,2021,1943],{"class":1904},[1408,2023,1996],{"class":1857},[1408,2025,2000],{"class":1999},[1408,2027,2028],{"class":1857},"rs.initiate({_id:'rsa',members:[{_id:0,host:'sht-a:27018'}]})",[1408,2030,2006],{"class":1999},[1408,2032,2033,2035,2037,2039,2041,2043,2045,2047,2049,2052],{"class":1410,"line":117},[1408,2034,1854],{"class":1853},[1408,2036,1984],{"class":1857},[1408,2038,1958],{"class":1857},[1408,2040,2017],{"class":1857},[1408,2042,1901],{"class":1857},[1408,2044,1943],{"class":1904},[1408,2046,1996],{"class":1857},[1408,2048,2000],{"class":1999},[1408,2050,2051],{"class":1857},"rs.initiate({_id:'rsb',members:[{_id:0,host:'sht-b:27018'}]})",[1408,2053,2006],{"class":1999},[1408,2055,2056,2058,2060,2062,2064,2067,2069,2071,2074,2077,2079,2082,2085,2088,2091,2093],{"class":1410,"line":123},[1408,2057,1854],{"class":1853},[1408,2059,1871],{"class":1857},[1408,2061,1874],{"class":1857},[1408,2063,1877],{"class":1857},[1408,2065,2066],{"class":1857}," sht-mongos",[1408,2068,1883],{"class":1857},[1408,2070,1886],{"class":1857},[1408,2072,2073],{"class":1857}," -p",[1408,2075,2076],{"class":1857}," 27100:27017",[1408,2078,1889],{"class":1857},[1408,2080,2081],{"class":1857}," mongos",[1408,2083,2084],{"class":1857}," --configdb",[1408,2086,2087],{"class":1857}," cfgrs\u002Fsht-cfg:27019",[1408,2089,2090],{"class":1857}," --bind_ip_all",[1408,2092,1901],{"class":1857},[1408,2094,2095],{"class":1904}," 27017\n",[1408,2097,2098,2100,2102,2104,2106,2108,2110,2113],{"class":1410,"line":129},[1408,2099,1854],{"class":1853},[1408,2101,1984],{"class":1857},[1408,2103,2066],{"class":1857},[1408,2105,1989],{"class":1857},[1408,2107,1996],{"class":1857},[1408,2109,2000],{"class":1999},[1408,2111,2112],{"class":1857},"sh.addShard('rsa\u002Fsht-a:27018'); sh.addShard('rsb\u002Fsht-b:27018'); sh.addShardToZone('rsa','eu'); sh.addShardToZone('rsa','global'); sh.addShardToZone('rsb','na')",[1408,2114,2006],{"class":1999},[1408,2116,2117,2121,2124,2127,2130,2132,2135,2138],{"class":1410,"line":190},[1408,2118,2120],{"class":2119},"sTEyZ","REDELAY_TEST_MONGO_SHARDED_URI",[1408,2122,2123],{"class":1999},"=",[1408,2125,2126],{"class":1999},"'",[1408,2128,2129],{"class":1857},"mongodb:\u002F\u002Flocalhost:27100",[1408,2131,2126],{"class":1999},[1408,2133,2134],{"class":1853}," go",[1408,2136,2137],{"class":1857}," test",[1408,2139,2140],{"class":1857}," .\u002F...\n",[1018,2142,2144],{"id":2143},"kafka-replicas-stay-in-one-region-go-events","Kafka — replicas stay in one region (go-events)",[998,2146,2147,2149,2150,2153,2154,2157,2158,2161,2162,2165,2166,2169,2170,2173,2174,2177],{},[1105,2148,1107],{}," waits for ",[1002,2151,2152],{},"every in-sync replica",", not ",[1105,2155,2156],{},"min.insync.replicas",". One\nreplica across an ocean makes every publish ~1 s. Keep a topic's replicas in one\nregion (RF 3 with a third-site broker, or RF 2 in-region); producers in the other\nregion pay one round trip. ",[1105,2159,2160],{},"KAFKA_TOPIC_RACK"," (go-events ≥ v0.7.3) creates new\ntopics only on brokers of that ",[1105,2163,2164],{},"broker.rack",", so a topic created by an app can't\nland in the other region. Planned: ",[1105,2167,2168],{},"EVENTS_REGION"," with a region prefix for\ntopics produced and consumed in one region, a consumer scope (",[1105,2171,2172],{},"local"," | ",[1105,2175,2176],{},"all","),\nand the outbox for publishes made inside a request so a request never waits for\nKafka.",[1018,2179,2181],{"id":2180},"clickhouse-nearest-keeper-batched-inserts","ClickHouse — nearest Keeper, batched inserts",[998,2183,2184,2185,2188,2189,2192,2193,2196],{},"Replicating the data is asynchronous; an insert waits for ~8 Keeper writes, each\na Keeper majority round. Batch inserts (or ",[1105,2186,2187],{},"async_insert=1",") and give each\nserver its nearest Keeper first: ",[1105,2190,2191],{},"zookeeper_load_balancing=in_order"," with a\nper-server node order — the default is ",[1002,2194,2195],{},"random",", and one session on a Keeper\nacross the ocean made 9 ms inserts take 800 ms in our benchmark.",[1018,2198,2200],{"id":2199},"redis-shared-cluster-with-replicas-and-an-acl-user","Redis — shared cluster with replicas and an ACL user",[998,2202,2203,2204,2207,2208,2211,2212,2215,2216,2219,2220,2223,2224,2227],{},"The shared cluster (locks, rate limits, coordination, event dedupe) needs a\nreplica per master on another node so one node down is not ",[1105,2205,2206],{},"CLUSTERDOWN",". Turn\nauth on with a ",[1002,2209,2210],{},"named ACL user"," (",[1105,2213,2214],{},"REDIS_SHARED_USERNAME"," \u002F\n",[1105,2217,2218],{},"REDIS_SHARED_PASSWORD",", go-modules ≥ v0.68.0; go-events ≥ v0.7.2 for the dedupe\nstore): a password sent to a server without one is an error, so clients log in\nas the user first and the default user is switched off last. Code that opens its\nown client on the cluster uses ",[1105,2221,2222],{},"SharedClusterOptions()",". The recent-write marker\n(",[1105,2225,2226],{},"runtime\u002Fmongo\u002Frecentwrite",") reads this node's own master; on a node that runs\nonly a replica (yul, a replica of amer's master) it reads the master with the\nlowest measured round trip (go-framework ≥ v0.27.0) instead of whichever master\nholds the user's key.",[1018,2229,2231],{"id":2230},"still-to-come","Still to come",[1054,2233,2234,2243],{},[1057,2235,2236],{},[1060,2237,2238,2240],{},[1063,2239,1149],{},[1063,2241,2242],{},"Where",[1072,2244,2245,2253,2261],{},[1060,2246,2247,2250],{},[1077,2248,2249],{},"go-events: region prefix, consumer scope (rack placement shipped in v0.7.3)",[1077,2251,2252],{},"go-events",[1060,2254,2255,2258],{},[1077,2256,2257],{},"Leader-only scheduler gauges (so the process exporting them can run 2 replicas)",[1077,2259,2260],{},"go-modules scheduler",[1060,2262,2263,2266],{},[1077,2264,2265],{},"A per-region Redis for rate limits and NA-local locks",[1077,2267,2268],{},"config + go-modules",[2270,2271,2272],"style",{},"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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}",{"title":1404,"searchDepth":16,"depth":16,"links":2274},[2275,2276,2280,2283,2284,2285,2286],{"id":1020,"depth":16,"text":1021},{"id":1117,"depth":16,"text":2277,"children":2278},"MongoDB — regional shards (runtime\u002Fmongo, runtime\u002Fregion)",[2279],{"id":1389,"depth":22,"text":1390},{"id":1442,"depth":16,"text":1443,"children":2281},[2282],{"id":1840,"depth":22,"text":1841},{"id":2143,"depth":16,"text":2144},{"id":2180,"depth":16,"text":2181},{"id":2199,"depth":16,"text":2200},{"id":2230,"depth":16,"text":2231},"Running one Redelay app in several regions — local reads and writes per region, what each datastore needs, and the framework pieces that make it work.","md",null,{},{"order":301,"icon":302},{"title":298,"description":2287},"ZYaLSA1_qHo3ZyTUdwxn_5ZHch7pxxyJnUj-9hbGPzk",1792248598143]