[{"data":1,"prerenderedAt":1082},["ShallowReactive",2],{"navigation":3,"comparison-matrix":38,"mdc--8xwrd0-key":465,"mdc-3pf9qg-key":477,"mdc-pu4fki-key":485,"mdc--mg8vom-key":493,"mdc-9uufvf-key":501,"mdc--5z26ml-key":519,"mdc--3h1rya-key":541,"mdc-fpbl6h-key":555,"mdc-boxirr-key":563,"mdc-jmlzdl-key":571,"mdc-mhix7s-key":579,"mdc-m4o528-key":587,"mdc-hwzrxe-key":595,"mdc-2qk1oj-key":603,"mdc-wxtryj-key":620,"mdc-e4a3bz-key":628,"mdc--aroe44-key":636,"mdc--xzp0er-key":644,"mdc-ye6d4i-key":652,"mdc-m3z4dt-key":660,"mdc-1f2rc4-key":668,"mdc-jgix5m-key":676,"mdc--h7ctol-key":684,"mdc-633711-key":692,"mdc--n5l3i3-key":700,"mdc-re6e2k-key":708,"mdc--mqsrm1-key":716,"mdc-fx5z15-key":724,"mdc-tb4wzz-key":732,"mdc--m9bjd8-key":740,"mdc-kusdnv-key":748,"mdc-gmgnjr-key":756,"mdc-320skj-key":764,"mdc--8ywmed-key":772,"mdc-ras11z-key":780,"mdc-fdq7dy-key":788,"mdc--p37kuy-key":796,"mdc-mqlwk4-key":804,"mdc--lr3p77-key":812,"mdc--x6rdv0-key":820,"mdc-e7jrnv-key":828,"mdc-rxvz3q-key":836,"mdc-btim63-key":844,"mdc--7o8qwb-key":852,"mdc-15070z-key":860,"mdc-b041xx-key":868,"mdc--ihtx81-key":876,"mdc-5rgr5f-key":884,"mdc--prxwhz-key":892,"mdc--ydolzb-key":900,"mdc--3lqx65-key":908,"mdc--g3hnhw-key":916,"mdc--shbgfk-key":924,"mdc-hs2451-key":932,"mdc-5q3b1a-key":940,"mdc--4pclga-key":948,"mdc--3gue6v-key":956,"mdc--2qaip-key":964,"mdc-szrogs-key":972,"mdc-r6zzq3-key":986,"mdc--h0fyd5-key":994,"mdc--z1jrab-key":1018,"mdc--t0989q-key":1035,"mdc-ktvli4-key":1043,"mdc--rmuyc-key":1074},[4],{"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},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"License configuration","\u002Fdocs\u002Fgetting-started\u002Flicense-configuration","1.docs\u002F1.getting-started\u002F3.license-configuration","i-lucide-key-round",{"title":23,"path":24,"stem":25,"icon":26},"Your first app","\u002Fdocs\u002Fgetting-started\u002Ffirst-app","1.docs\u002F1.getting-started\u002F4.first-app","i-lucide-square-play",{"title":28,"path":29,"stem":30,"icon":31},"Architecture","\u002Fdocs\u002Fgetting-started\u002Farchitecture","1.docs\u002F1.getting-started\u002F5.architecture","i-lucide-layers",{"title":33,"path":34,"stem":35,"icon":36},"Migrating from Kafka Streams","\u002Fdocs\u002Fgetting-started\u002Fmigration","1.docs\u002F1.getting-started\u002F6.migration","i-lucide-shuffle",false,{"id":39,"title":40,"body":41,"comparisonMatrix":42,"description":172,"dslFeatureMatrix":173,"extension":431,"intro":432,"meta":433,"navigation":434,"path":435,"seo":436,"singleMachine":437,"stem":451,"versusProse":452,"__hash__":464},"comparisonMatrixPage\u002F6.pages\u002Fproduct\u002Fcomparison-matrix.yml","Product comparison matrix",null,{"columns":43,"rows":60,"legend":171},[44,47,51,55],{"id":45,"label":46,"brand":45},"stoatflow","StoatFlow",{"id":48,"label":49,"brand":50},"kafkaStreams","Kafka Streams","kafka",{"id":52,"label":53,"sublabel":54,"brand":52},"flink","Apache Flink","self-hosted",{"id":56,"label":57,"sublabel":58,"brand":59},"managedFlink","Managed Flink","varies significantly by provider","managed",[61,68,75,82,88,95,101,107,114,120,126,132,138,144,150,157,164],{"axis":62,"cells":63},"Deployment model",{"stoatflow":64,"kafkaStreams":65,"flink":66,"managedFlink":67},"JVM app → single instance → static group membership","JVM app → n service instances → Kafka consumer group","JAR\u002FSQL\u002FPython job → Flink cluster → Session\u002FApplication mode → 1 active JobManager (+ HA standby) → n TaskManagers","JAR\u002FSQL\u002FPython job → managed service → provider-specific compute\u002Fcapacity units, autoscaling, and runtime constraints",{"axis":69,"cells":70},"Scaling model",{"stoatflow":71,"kafkaStreams":72,"flink":73,"managedFlink":74},"Vertical — CPU, memory, `n` lanes (virtual threads)","Horizontal — scale out `n` replicas; stream threads `t`","Horizontal — scale out n TaskManagers; operator parallelism `t`","(same)",{"axis":76,"cells":77},"Rebalancing",{"stoatflow":78,"kafkaStreams":79,"flink":80,"managedFlink":81},"None — single instance","Consumer-group rebalances and state restoration are operational concerns; mitigated by static membership, cooperative rebalancing, and standby replicas","Rescaling requires savepoint → stop\u002Frestart with new parallelism (downtime); Reactive Mode automates rescaling but still restarts tasks and restores from checkpoint state","Provider may automate or hide rescaling\u002Frestart mechanics; workload recovery still follows Flink's checkpoint\u002Fsavepoint model.",{"axis":83,"cells":84},"Repartitioning",{"stoatflow":85,"kafkaStreams":86,"flink":87,"managedFlink":74},"Local, in-process redistribution via lane channels → no Kafka repartition topics → no broker round-trip, no serialization, no network shuffle","Kafka repartition topics → serialization → network IO, load on brokers","Serialization shuffle → network IO when remote, local channel when same TaskManager → `keyBy` always breaks operator chaining",{"axis":89,"cells":90},"Exactly-once",{"stoatflow":91,"kafkaStreams":92,"flink":93,"managedFlink":94},"Chandy-Lamport with barriers + Kafka transactions; single-coordinator","Kafka transactions; stream task scoped","Distributed checkpoints, Chandy-Lamport with barriers — incremental, unaligned, generic log-based, ForSt-backed","Distributed checkpoints (managed) — config options depend on provider & service",{"axis":96,"cells":97},"State model",{"stoatflow":98,"kafkaStreams":99,"flink":100,"managedFlink":74},"Global — any key accessible from any lane — no replicated copies across application instances","Partition-scoped; global stores (limited scope) with local copies per replica","Operator-scoped; broadcast state available (push-based, local copy per subtask)",{"axis":102,"cells":103},"State access",{"stoatflow":104,"kafkaStreams":105,"flink":106,"managedFlink":74},"(1) abstracted by DSL — (2) flexible direct global store access via interactive queries","(1) abstracted by DSL — (2) flexible direct partition-bounded store access via interactive queries","Operator-scoped, key-scoped — abstracted by DSL\u002FSQL — no equivalent to interactive queries from external code at runtime; offline inspection via State Processor API",{"axis":108,"cells":109},"High-availability model",{"stoatflow":110,"kafkaStreams":111,"flink":112,"managedFlink":113},"Single active instance with fast restart — benchmarked 400ms (stateless) \u002F 800–1200ms (stateful) — no cross-instance rebalance or state shuffle in the normal failure path — hot-standby for blue-green failover on roadmap","HA patterns via static membership, cooperative rebalancing, and standby replicas; effective when configured well, but requires expert knowledge to setup and operate","HA JobManager plus checkpoint\u002Fsavepoint-based task recovery; recovery time depends on state size, backend, checkpoint storage, restart strategy, and available cluster capacity.","Managed control plane and recovery infrastructure; workload recovery still follows Flink's checkpoint\u002Fsavepoint model, with provider-specific autoscaling and failover behaviour.",{"axis":115,"cells":116},"DSL",{"stoatflow":117,"kafkaStreams":118,"flink":119,"managedFlink":74},"Kafka Streams DSL-compatible + StoatFlow extensions","Kafka Streams DSL (native)","DataStream \u002F Table \u002F SQL — different API",{"axis":121,"cells":122},"Low-latency",{"stoatflow":123,"kafkaStreams":124,"flink":125,"managedFlink":74},"Designed for E2E sub-second Kafka-native workloads","Sub-second E2E latency per sub-topology — every (repartition) Kafka round-trip adds latency","Sub-second E2E with EOS achievable but rarely operated — every checkpoint sets the commit cadence, and per-sink-subtask 2PC overhead scales with parallelism",{"axis":127,"cells":128},"Throughput ceiling",{"stoatflow":129,"kafkaStreams":130,"flink":131,"managedFlink":74},"Benchmarked up to 500 MB\u002Fsec on single machine (8 Core VM)","Scales with instance count — repartition topics add Kafka I\u002FO, which factors into the throughput envelope (distribution tax)","Scales with cluster — Flink is known for supporting massive-scale workloads (Alibaba, …)",{"axis":133,"cells":134},"External I\u002FO (REST, DB, AI)",{"stoatflow":135,"kafkaStreams":136,"flink":137,"managedFlink":74},"Virtual-thread-friendly blocking I\u002FO — high concurrency without dedicating platform threads per request — configurable parallelism","No native async-I\u002FO DSL operator — blocking calls occupy stream threads — parallelism limited by Kafka partitions","AsyncIO operator — configurable parallelism × capacity — orderedWait\u002FunorderedWait",{"axis":139,"cells":140},"Migration from Kafka Streams",{"stoatflow":141,"kafkaStreams":142,"flink":143,"managedFlink":143},"Dependency swap + config cleanup; state recovers via reprocess from source topics (assumes adequate retention)","— (native)","Full rewrite",{"axis":145,"cells":146},"License",{"stoatflow":147,"kafkaStreams":148,"flink":148,"managedFlink":149},"Commercial — seats + machines","Apache 2.0 (free)","Commercial — pricing model varies by vendor (usage-based for SaaS offerings like AWS KDA \u002F Confluent Flink \u002F Ververica Cloud; subscription for self-managed Ververica Platform)",{"axis":151,"cells":152},"Maturity",{"stoatflow":153,"kafkaStreams":154,"flink":155,"managedFlink":156},"v1.0, MVP — early production pilots","Production since 2016 — battle-tested at scale","Production since 2014 — battle-tested at massive scale","Ververica Platform GA since ~2018; AWS KDA for Apache Flink GA Nov 2018; Confluent Flink GA 2024",{"axis":158,"cells":159},"SQL interface",{"stoatflow":160,"kafkaStreams":161,"flink":162,"managedFlink":163},"None — Kotlin\u002FJava DSL only","None — DSL only (ksqlDB is Confluent licensed and no longer mentioned\u002Frelevant)","First-class — Flink SQL + Table API; common entry point for analyst-facing teams","Same as Flink; often the primary surface",{"axis":165,"cells":166},"Not best fit",{"stoatflow":167,"kafkaStreams":168,"flink":169,"managedFlink":170},"Workloads needing open-ended horizontal scale or very large state beyond one machine","Workloads where rebalance\u002Fstate\u002Frepartition overhead dominates","Small Kafka-only services where cluster overhead dominates","Cost-sensitive mid-size Kafka-only workloads","**(same)** = identical to the column to the left.","Honest side-by-side — StoatFlow vs Kafka Streams vs Apache Flink (self-hosted) vs managed Flink platforms.",{"heading":174,"intro":175,"columns":176,"categories":180},"Feature parity","Side-by-side DSL coverage — Kafka Streams baseline, Apache Flink for reference, StoatFlow's surface against both.",[177,178,179],{"id":45,"label":46,"brand":45},{"id":48,"label":49,"brand":50},{"id":52,"label":53,"brand":52},[181,194,211,226,235,253,271,283,304,319,343,354,369,384,396,410,422],{"name":182,"features":183},"Core transformations",[184,188,191],{"name":185,"support":186},"map, flatMap, filter, peek",{"stoatflow":187,"kafkaStreams":187,"flink":187},"yes",{"name":189,"support":190},"transform \u002F process",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":192,"support":193},"Processor API \u002F ProcessFunction",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":195,"features":196},"Branching \u002F routing",[197,200,204,208],{"name":198,"support":199},"split, branch, merge",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":201,"support":202},"union",{"stoatflow":203,"kafkaStreams":203,"flink":187},"no",{"name":205,"support":206},"side outputs",{"stoatflow":207,"kafkaStreams":203,"flink":187},"on roadmap",{"name":209,"support":210},"broadcast",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":212,"features":213},"Keying \u002F partitioning",[214,217,220,223],{"name":215,"support":216},"selectKey \u002F keyBy, groupBy",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":218,"support":219},"repartition",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":221,"support":222},"shuffle, rescale, rebalance",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":224,"support":225},"global \u002F GlobalKTable",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":227,"features":228},"Aggregations",[229,232],{"name":230,"support":231},"count, reduce, aggregate",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":233,"support":234},"cogroup",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":236,"features":237},"Windowing",[238,241,244,247,250],{"name":239,"support":240},"tumbling, hopping\u002Fsliding, session windows",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":242,"support":243},"custom windows",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":245,"support":246},"grace period \u002F allowed lateness",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":248,"support":249},"suppression",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":251,"support":252},"triggers, evictors",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":254,"features":255},"Time",[256,259,262,265,268],{"name":257,"support":258},"event time, processing time",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":260,"support":261},"stream time",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":263,"support":264},"ingestion time",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":266,"support":267},"watermarks",{"stoatflow":187,"kafkaStreams":203,"flink":187},{"name":269,"support":270},"idleness, watermark alignment",{"stoatflow":187,"kafkaStreams":203,"flink":187},{"name":272,"features":273},"Timers \u002F callbacks",[274,277,280],{"name":275,"support":276},"punctuators (stream-time \u002F wall-clock-time)",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":278,"support":279},"timers (event-time \u002F processing-time)",{"stoatflow":187,"kafkaStreams":203,"flink":187},{"name":281,"support":282},"scheduled sources",{"stoatflow":187,"kafkaStreams":203,"flink":203},{"name":284,"features":285},"Joins",[286,289,292,295,298,301],{"name":287,"support":288},"stream-stream join, stream-table join, table-table join",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":290,"support":291},"inner join, left join, outer join",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":293,"support":294},"window join",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":296,"support":297},"foreign-key join",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":299,"support":300},"interval join, temporal join",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":302,"support":303},"semi join, anti join",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":305,"features":306},"Tables \u002F changelogs",[307,310,313,316],{"name":308,"support":309},"KTable \u002F dynamic table",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":311,"support":312},"changelog stream, upsert",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":314,"support":315},"GlobalKTable",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":317,"support":318},"retractions",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":320,"features":321},"State",[322,325,328,331,334,337,340],{"name":323,"support":324},"local state, keyed state",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":326,"support":327},"key-value state, window state, session state",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":329,"support":330},"custom state store",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":332,"support":333},"operator state, broadcast state",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":335,"support":336},"state TTL",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":338,"support":339},"atomic store operations (compute, merge)",{"stoatflow":187,"kafkaStreams":203,"flink":203},{"name":341,"support":342},"KeyLockManager",{"stoatflow":187,"kafkaStreams":203,"flink":203},{"name":102,"features":344},[345,348,351],{"name":346,"support":347},"interactive queries",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":349,"support":350},"local state queries",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":352,"support":353},"containsKey, containsSession",{"stoatflow":187,"kafkaStreams":203,"flink":203},{"name":355,"features":356},"I\u002FO",[357,360,363,366],{"name":358,"support":359},"Kafka source, Kafka sink",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":361,"support":362},"custom source, custom sink",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":364,"support":365},"file source\u002Fsink, JDBC source\u002Fsink",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":367,"support":368},"async I\u002FO",{"stoatflow":187,"kafkaStreams":203,"flink":187},{"name":370,"features":371},"Fault tolerance",[372,375,378,381],{"name":373,"support":374},"restore",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":376,"support":377},"changelog topics \u002F changelog state backend",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":379,"support":380},"standby replicas",{"stoatflow":207,"kafkaStreams":187,"flink":203},{"name":382,"support":383},"checkpoints, savepoints",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":385,"features":386},"Consistency",[387,390,393],{"name":388,"support":389},"at-least-once, exactly-once",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":391,"support":392},"transactions",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":394,"support":395},"two-phase commit",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":397,"features":398},"Higher-level APIs",[399,401,404,407],{"name":115,"support":400},{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":402,"support":403},"Processor API \u002F DataStream API",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":405,"support":406},"Table API, SQL",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":408,"support":409},"CEP",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":411,"features":412},"Execution modes",[413,416,419],{"name":414,"support":415},"streaming",{"stoatflow":187,"kafkaStreams":187,"flink":187},{"name":417,"support":418},"bounded streams, batch",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":420,"support":421},"unified batch\u002Fstreaming",{"stoatflow":203,"kafkaStreams":203,"flink":187},{"name":423,"features":424},"Testing",[425,428],{"name":426,"support":427},"TopologyTestDriver",{"stoatflow":187,"kafkaStreams":187,"flink":203},{"name":429,"support":430},"MiniCluster, OperatorTestHarness",{"stoatflow":203,"kafkaStreams":203,"flink":187},"yml","One honest side-by-side so evaluators don't have to assemble it themselves. Strengths of each are acknowledged in the rows where they apply; trade-offs are stated plainly.\n",{},true,"\u002Fpages\u002Fproduct\u002Fcomparison-matrix",{"title":40,"description":172},{"heading":438,"headline":439,"intro":440,"workloads":441,"footer":450},"Measured single-machine limit","On a basic _8-core Hetzner dedicated VM_, StoatFlow saturates CPU or network at **~200–300 MB\u002Fs uncompressed throughput** — in events, ~124K\u002Fsec on a 1KB stateless transform, up to ~2.1M\u002Fsec output on word-count-style aggregation. That is the practical ceiling to plan against when sizing a single instance; sustained workloads above it are the ones where horizontal scale-out is the right tool.\n","Two reference workloads anchor that envelope.",[442,446],{"name":443,"pipeline":444,"throughput":445},"stateless-simple","1 KB strings → `map(uppercase())` → sink","124k ops\u002Fs in -> 124k ops\u002Fs out",{"name":447,"pipeline":448,"throughput":449},"word-count","phrases dictionary → `split` + `groupBy` + `count` → sink","52k ops\u002Fs in -> 2.1M ops\u002Fs out","Last measured 2026-05-10. More benchmarks — on stronger hardware — coming soon.","6.pages\u002Fproduct\u002Fcomparison-matrix",{"heading":453,"items":454},"When StoatFlow vs. each",[455,458,461],{"heading":456,"body":457},"vs. Kafka Streams","Kafka Streams is battle-tested and has one of the most ergonomic topology APIs on the JVM. StoatFlow keeps a Kafka Streams DSL-compatible programming model, but trades Kafka Streams' horizontal scale-out architecture for a simpler single-instance runtime. That removes whole categories of distributed overhead: inter-instance rebalancing, state migration, and repartition-topic round-trips. For Kafka-native workloads that fit comfortably on one modern machine, this can translate into lower compute, memory, network, and storage usage — and often lower latency, higher throughput on the same hardware, and materially lower operating cost. The trade-off is explicit: StoatFlow gives up open-ended horizontal scale in favour of simpler, more resource-efficient vertical scale.\n",{"heading":459,"body":460},"vs. Apache Flink (self-hosted)","Flink is the right tool for non-Kafka sources and sinks, analytics, ML, unified streaming + batch, or massive-scale workloads (Netflix, Uber, Stripe, Alibaba). StoatFlow targets the wide middle of Kafka-native stream processing applications — workloads Flink can also handle, but where the JobManager\u002FTaskManager runtime, checkpoint tuning, and platform expertise can become a significant part of the cost structure.\n",{"heading":462,"body":463},"vs. Managed Flink","Managed Flink removes much of the operational burden, but you still pay for a managed distributed data-processing platform. That cost is justified when you need Flink's scale, elasticity, SQL, or connector ecosystem. It can be disproportionate for Kafka-native workloads that would otherwise fit comfortably on one machine. StoatFlow targets that middle ground: simpler deployment and service-like cost structure, with explicit single-machine limits.\n","5jNieonxrspBzjshzXpiTSLSAECFgWB7QD584lbDHGU",{"data":466,"body":467},{},{"type":468,"children":469},"root",[470],{"type":471,"tag":472,"props":473,"children":474},"element","p",{},[475],{"type":476,"value":64},"text",{"data":478,"body":479},{},{"type":468,"children":480},[481],{"type":471,"tag":472,"props":482,"children":483},{},[484],{"type":476,"value":65},{"data":486,"body":487},{},{"type":468,"children":488},[489],{"type":471,"tag":472,"props":490,"children":491},{},[492],{"type":476,"value":66},{"data":494,"body":495},{},{"type":468,"children":496},[497],{"type":471,"tag":472,"props":498,"children":499},{},[500],{"type":476,"value":67},{"data":502,"body":503},{},{"type":468,"children":504},[505],{"type":471,"tag":472,"props":506,"children":507},{},[508,510,517],{"type":476,"value":509},"Vertical — CPU, memory, ",{"type":471,"tag":511,"props":512,"children":514},"code",{"className":513},[],[515],{"type":476,"value":516},"n",{"type":476,"value":518}," lanes (virtual threads)",{"data":520,"body":521},{},{"type":468,"children":522},[523],{"type":471,"tag":472,"props":524,"children":525},{},[526,528,533,535],{"type":476,"value":527},"Horizontal — scale out ",{"type":471,"tag":511,"props":529,"children":531},{"className":530},[],[532],{"type":476,"value":516},{"type":476,"value":534}," replicas; stream threads ",{"type":471,"tag":511,"props":536,"children":538},{"className":537},[],[539],{"type":476,"value":540},"t",{"data":542,"body":543},{},{"type":468,"children":544},[545],{"type":471,"tag":472,"props":546,"children":547},{},[548,550],{"type":476,"value":549},"Horizontal — scale out n TaskManagers; operator parallelism ",{"type":471,"tag":511,"props":551,"children":553},{"className":552},[],[554],{"type":476,"value":540},{"data":556,"body":557},{},{"type":468,"children":558},[559],{"type":471,"tag":472,"props":560,"children":561},{},[562],{"type":476,"value":78},{"data":564,"body":565},{},{"type":468,"children":566},[567],{"type":471,"tag":472,"props":568,"children":569},{},[570],{"type":476,"value":79},{"data":572,"body":573},{},{"type":468,"children":574},[575],{"type":471,"tag":472,"props":576,"children":577},{},[578],{"type":476,"value":80},{"data":580,"body":581},{},{"type":468,"children":582},[583],{"type":471,"tag":472,"props":584,"children":585},{},[586],{"type":476,"value":81},{"data":588,"body":589},{},{"type":468,"children":590},[591],{"type":471,"tag":472,"props":592,"children":593},{},[594],{"type":476,"value":85},{"data":596,"body":597},{},{"type":468,"children":598},[599],{"type":471,"tag":472,"props":600,"children":601},{},[602],{"type":476,"value":86},{"data":604,"body":605},{},{"type":468,"children":606},[607],{"type":471,"tag":472,"props":608,"children":609},{},[610,612,618],{"type":476,"value":611},"Serialization shuffle → network IO when remote, local channel when same TaskManager → ",{"type":471,"tag":511,"props":613,"children":615},{"className":614},[],[616],{"type":476,"value":617},"keyBy",{"type":476,"value":619}," always breaks operator chaining",{"data":621,"body":622},{},{"type":468,"children":623},[624],{"type":471,"tag":472,"props":625,"children":626},{},[627],{"type":476,"value":91},{"data":629,"body":630},{},{"type":468,"children":631},[632],{"type":471,"tag":472,"props":633,"children":634},{},[635],{"type":476,"value":92},{"data":637,"body":638},{},{"type":468,"children":639},[640],{"type":471,"tag":472,"props":641,"children":642},{},[643],{"type":476,"value":93},{"data":645,"body":646},{},{"type":468,"children":647},[648],{"type":471,"tag":472,"props":649,"children":650},{},[651],{"type":476,"value":94},{"data":653,"body":654},{},{"type":468,"children":655},[656],{"type":471,"tag":472,"props":657,"children":658},{},[659],{"type":476,"value":98},{"data":661,"body":662},{},{"type":468,"children":663},[664],{"type":471,"tag":472,"props":665,"children":666},{},[667],{"type":476,"value":99},{"data":669,"body":670},{},{"type":468,"children":671},[672],{"type":471,"tag":472,"props":673,"children":674},{},[675],{"type":476,"value":100},{"data":677,"body":678},{},{"type":468,"children":679},[680],{"type":471,"tag":472,"props":681,"children":682},{},[683],{"type":476,"value":104},{"data":685,"body":686},{},{"type":468,"children":687},[688],{"type":471,"tag":472,"props":689,"children":690},{},[691],{"type":476,"value":105},{"data":693,"body":694},{},{"type":468,"children":695},[696],{"type":471,"tag":472,"props":697,"children":698},{},[699],{"type":476,"value":106},{"data":701,"body":702},{},{"type":468,"children":703},[704],{"type":471,"tag":472,"props":705,"children":706},{},[707],{"type":476,"value":110},{"data":709,"body":710},{},{"type":468,"children":711},[712],{"type":471,"tag":472,"props":713,"children":714},{},[715],{"type":476,"value":111},{"data":717,"body":718},{},{"type":468,"children":719},[720],{"type":471,"tag":472,"props":721,"children":722},{},[723],{"type":476,"value":112},{"data":725,"body":726},{},{"type":468,"children":727},[728],{"type":471,"tag":472,"props":729,"children":730},{},[731],{"type":476,"value":113},{"data":733,"body":734},{},{"type":468,"children":735},[736],{"type":471,"tag":472,"props":737,"children":738},{},[739],{"type":476,"value":117},{"data":741,"body":742},{},{"type":468,"children":743},[744],{"type":471,"tag":472,"props":745,"children":746},{},[747],{"type":476,"value":118},{"data":749,"body":750},{},{"type":468,"children":751},[752],{"type":471,"tag":472,"props":753,"children":754},{},[755],{"type":476,"value":119},{"data":757,"body":758},{},{"type":468,"children":759},[760],{"type":471,"tag":472,"props":761,"children":762},{},[763],{"type":476,"value":123},{"data":765,"body":766},{},{"type":468,"children":767},[768],{"type":471,"tag":472,"props":769,"children":770},{},[771],{"type":476,"value":124},{"data":773,"body":774},{},{"type":468,"children":775},[776],{"type":471,"tag":472,"props":777,"children":778},{},[779],{"type":476,"value":125},{"data":781,"body":782},{},{"type":468,"children":783},[784],{"type":471,"tag":472,"props":785,"children":786},{},[787],{"type":476,"value":129},{"data":789,"body":790},{},{"type":468,"children":791},[792],{"type":471,"tag":472,"props":793,"children":794},{},[795],{"type":476,"value":130},{"data":797,"body":798},{},{"type":468,"children":799},[800],{"type":471,"tag":472,"props":801,"children":802},{},[803],{"type":476,"value":131},{"data":805,"body":806},{},{"type":468,"children":807},[808],{"type":471,"tag":472,"props":809,"children":810},{},[811],{"type":476,"value":135},{"data":813,"body":814},{},{"type":468,"children":815},[816],{"type":471,"tag":472,"props":817,"children":818},{},[819],{"type":476,"value":136},{"data":821,"body":822},{},{"type":468,"children":823},[824],{"type":471,"tag":472,"props":825,"children":826},{},[827],{"type":476,"value":137},{"data":829,"body":830},{},{"type":468,"children":831},[832],{"type":471,"tag":472,"props":833,"children":834},{},[835],{"type":476,"value":141},{"data":837,"body":838},{},{"type":468,"children":839},[840],{"type":471,"tag":472,"props":841,"children":842},{},[843],{"type":476,"value":142},{"data":845,"body":846},{},{"type":468,"children":847},[848],{"type":471,"tag":472,"props":849,"children":850},{},[851],{"type":476,"value":143},{"data":853,"body":854},{},{"type":468,"children":855},[856],{"type":471,"tag":472,"props":857,"children":858},{},[859],{"type":476,"value":147},{"data":861,"body":862},{},{"type":468,"children":863},[864],{"type":471,"tag":472,"props":865,"children":866},{},[867],{"type":476,"value":148},{"data":869,"body":870},{},{"type":468,"children":871},[872],{"type":471,"tag":472,"props":873,"children":874},{},[875],{"type":476,"value":149},{"data":877,"body":878},{},{"type":468,"children":879},[880],{"type":471,"tag":472,"props":881,"children":882},{},[883],{"type":476,"value":153},{"data":885,"body":886},{},{"type":468,"children":887},[888],{"type":471,"tag":472,"props":889,"children":890},{},[891],{"type":476,"value":154},{"data":893,"body":894},{},{"type":468,"children":895},[896],{"type":471,"tag":472,"props":897,"children":898},{},[899],{"type":476,"value":155},{"data":901,"body":902},{},{"type":468,"children":903},[904],{"type":471,"tag":472,"props":905,"children":906},{},[907],{"type":476,"value":156},{"data":909,"body":910},{},{"type":468,"children":911},[912],{"type":471,"tag":472,"props":913,"children":914},{},[915],{"type":476,"value":160},{"data":917,"body":918},{},{"type":468,"children":919},[920],{"type":471,"tag":472,"props":921,"children":922},{},[923],{"type":476,"value":161},{"data":925,"body":926},{},{"type":468,"children":927},[928],{"type":471,"tag":472,"props":929,"children":930},{},[931],{"type":476,"value":162},{"data":933,"body":934},{},{"type":468,"children":935},[936],{"type":471,"tag":472,"props":937,"children":938},{},[939],{"type":476,"value":163},{"data":941,"body":942},{},{"type":468,"children":943},[944],{"type":471,"tag":472,"props":945,"children":946},{},[947],{"type":476,"value":167},{"data":949,"body":950},{},{"type":468,"children":951},[952],{"type":471,"tag":472,"props":953,"children":954},{},[955],{"type":476,"value":168},{"data":957,"body":958},{},{"type":468,"children":959},[960],{"type":471,"tag":472,"props":961,"children":962},{},[963],{"type":476,"value":169},{"data":965,"body":966},{},{"type":468,"children":967},[968],{"type":471,"tag":472,"props":969,"children":970},{},[971],{"type":476,"value":170},{"data":973,"body":974},{},{"type":468,"children":975},[976],{"type":471,"tag":472,"props":977,"children":978},{},[979,984],{"type":471,"tag":980,"props":981,"children":982},"strong",{},[983],{"type":476,"value":74},{"type":476,"value":985}," = identical to the column to the left.",{"data":987,"body":988},{},{"type":468,"children":989},[990],{"type":471,"tag":472,"props":991,"children":992},{},[993],{"type":476,"value":207},{"data":995,"body":996},{},{"type":468,"children":997},[998],{"type":471,"tag":472,"props":999,"children":1000},{},[1001,1003,1009,1011,1016],{"type":476,"value":1002},"On a basic ",{"type":471,"tag":1004,"props":1005,"children":1006},"em",{},[1007],{"type":476,"value":1008},"8-core Hetzner dedicated VM",{"type":476,"value":1010},", StoatFlow saturates CPU or network at ",{"type":471,"tag":980,"props":1012,"children":1013},{},[1014],{"type":476,"value":1015},"~200–300 MB\u002Fs uncompressed throughput",{"type":476,"value":1017}," — in events, ~124K\u002Fsec on a 1KB stateless transform, up to ~2.1M\u002Fsec output on word-count-style aggregation. That is the practical ceiling to plan against when sizing a single instance; sustained workloads above it are the ones where horizontal scale-out is the right tool.",{"data":1019,"body":1020},{},{"type":468,"children":1021},[1022],{"type":471,"tag":472,"props":1023,"children":1024},{},[1025,1027,1033],{"type":476,"value":1026},"1 KB strings → ",{"type":471,"tag":511,"props":1028,"children":1030},{"className":1029},[],[1031],{"type":476,"value":1032},"map(uppercase())",{"type":476,"value":1034}," → sink",{"data":1036,"body":1037},{},{"type":468,"children":1038},[1039],{"type":471,"tag":472,"props":1040,"children":1041},{},[1042],{"type":476,"value":445},{"data":1044,"body":1045},{},{"type":468,"children":1046},[1047],{"type":471,"tag":472,"props":1048,"children":1049},{},[1050,1052,1058,1060,1066,1067,1073],{"type":476,"value":1051},"phrases dictionary → ",{"type":471,"tag":511,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":476,"value":1057},"split",{"type":476,"value":1059}," + ",{"type":471,"tag":511,"props":1061,"children":1063},{"className":1062},[],[1064],{"type":476,"value":1065},"groupBy",{"type":476,"value":1059},{"type":471,"tag":511,"props":1068,"children":1070},{"className":1069},[],[1071],{"type":476,"value":1072},"count",{"type":476,"value":1034},{"data":1075,"body":1076},{},{"type":468,"children":1077},[1078],{"type":471,"tag":472,"props":1079,"children":1080},{},[1081],{"type":476,"value":449},1780332011892]