<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ankur Kumar Pandey</title>
    <description>The latest articles on DEV Community by Ankur Kumar Pandey (@ankurpaan).</description>
    <link>https://dev.to/ankurpaan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118447%2Fc73d8bfb-562a-45ae-b7e9-c2708aea5e2d.jpg</url>
      <title>DEV Community: Ankur Kumar Pandey</title>
      <link>https://dev.to/ankurpaan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ankurpaan"/>
    <language>en</language>
    <item>
      <title>We rewrote LF Edge eKuiper in Rust: 425k eps, 8MB RAM, 13ms boot (vs Flink, Go eKuiper &amp; Benthos)</title>
      <dc:creator>Ankur Kumar Pandey</dc:creator>
      <pubDate>Thu, 10 Sep 2026 03:30:28 +0000</pubDate>
      <link>https://dev.to/ankurpaan/we-rewrote-lf-edge-ekuiper-in-rust-425k-eps-8mb-ram-13ms-boot-vs-flink-go-ekuiper-benthos-1o3p</link>
      <guid>https://dev.to/ankurpaan/we-rewrote-lf-edge-ekuiper-in-rust-425k-eps-8mb-ram-13ms-boot-vs-flink-go-ekuiper-benthos-1o3p</guid>
      <description>&lt;p&gt;Over at &lt;strong&gt;&lt;a href="https://i-dacs.com" rel="noopener noreferrer"&gt;I-Dacs Labs&lt;/a&gt;&lt;/strong&gt;, we run high-throughput telemetry pipelines on edge devices (Raspberry Pis, Advantech gateways, and embedded x86/ARM boxes). We've been using LF Edge eKuiper for local stream processing (SQL filtering, sliding windows, and MQTT/Kafka sinks), but kept hitting the classic edge computing wall:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;JVM engines (Apache Flink)&lt;/strong&gt;: Incredible throughput, but require &amp;gt;1 GB RAM and take 20+ seconds to boot. Unusable on small industrial hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go engines (Upstream eKuiper, Benthos, Telegraf)&lt;/strong&gt;: Much lighter, but continuous Stop-The-World GC sweeps introduced tail latency jitter. Worse, under burst sensor loads (10k–100k events/sec), Go channel buffer saturation led to silent packet loss.
We decided to rewrite the entire engine in pure Rust: &lt;strong&gt;&lt;a href="https://github.com/ankur-paan/rekuiper" rel="noopener noreferrer"&gt;rekuiper&lt;/a&gt;&lt;/strong&gt; (v0.421-beta, dual licensed under MIT / Apache-2.0).
---
### What We Built&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Core Architecture&lt;/strong&gt;: Lock-free stream bus (&lt;code&gt;StreamBus&lt;/code&gt;), Tokio async actors for rule execution, and bounded actor queues for sinks with zero runtime GC pauses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% Drop-In Parity&lt;/strong&gt;: Fully compatible with the existing eKuiper Manager Web UI, OpenAPI 3.0 schemas, and standard streaming SQL. Zero scaffolded stubs across all 98 REST endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footprint&lt;/strong&gt;: 9.60 MB stripped static binary, ~6 – 8.2 MB idle RAM consumption.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  - &lt;strong&gt;Sub-15ms Cold Boot&lt;/strong&gt;: 12.5 – 14.5 ms internal daemon bootstrap; 123 ms end-to-end process-spawn-to-ready.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Empirical Head-to-Head Benchmarks (500,000 Records)
&lt;/h3&gt;

&lt;p&gt;Rather than hand-waving estimates, we ran all engines head-to-head on the exact same Linux machine (WSL2 / Ubuntu x86_64) using an identical 500,000-record telemetry workload:&lt;br&gt;
&lt;strong&gt;Pipeline:&lt;/strong&gt; Parse 500k JSON events → Compute formula (&lt;code&gt;temp * 1.8 + 32&lt;/code&gt;) → Filter (&lt;code&gt;temp &amp;gt; 20.0&lt;/code&gt;) → Project (&lt;code&gt;id, temp_f&lt;/code&gt;) → Sink&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Engine&lt;/th&gt;
      &lt;th&gt;Runtime&lt;/th&gt;
      &lt;th&gt;500k Elapsed&lt;/th&gt;
      &lt;th&gt;Throughput&lt;/th&gt;
      &lt;th&gt;Data Drops&lt;/th&gt;
      &lt;th&gt;Memory&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;rekuiper (0.421)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Pure Rust&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.176 s&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;425,308 eps&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0 (0.0%)&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;~8 MB&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Apache Flink&lt;/td&gt;
      &lt;td&gt;Java / JVM&lt;/td&gt;
      &lt;td&gt;2.144 s&lt;/td&gt;
      &lt;td&gt;233,209 eps&lt;/td&gt;
      &lt;td&gt;0 (0.0%)&lt;/td&gt;
      &lt;td&gt;~1,022 MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Telegraf&lt;/td&gt;
      &lt;td&gt;Go&lt;/td&gt;
      &lt;td&gt;8.194 s&lt;/td&gt;
      &lt;td&gt;61,019 eps&lt;/td&gt;
      &lt;td&gt;0 (0.0%)&lt;/td&gt;
      &lt;td&gt;~50 MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Upstream Go eKuiper&lt;/td&gt;
      &lt;td&gt;Go&lt;/td&gt;
      &lt;td&gt;11.290 s&lt;/td&gt;
      &lt;td&gt;44,287 eps&lt;/td&gt;
      &lt;td&gt;72,921 (14.6%)&lt;/td&gt;
      &lt;td&gt;~45 MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Redpanda Connect&lt;/td&gt;
      &lt;td&gt;Go&lt;/td&gt;
      &lt;td&gt;19.236 s&lt;/td&gt;
      &lt;td&gt;25,993 eps&lt;/td&gt;
      &lt;td&gt;0 (0.0%)&lt;/td&gt;
      &lt;td&gt;~38 MB&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h3&gt;
  
  
  Key Observations:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Channel Saturation in Go&lt;/strong&gt;: Under sustained 500k burst ingestion, upstream Go eKuiper dropped &lt;strong&gt;72,921 records&lt;/strong&gt; (14.6% data loss) due to channel saturation (&lt;code&gt;buffer full, drop message&lt;/code&gt;). &lt;code&gt;rekuiper&lt;/code&gt; processed all 500,000 events with 0 drops in 1.176s (&lt;strong&gt;9.6x faster&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vs Apache Flink&lt;/strong&gt;: Flink’s execution graph is fast (233k eps), but the JobManager + TaskManager JVM consumed &lt;strong&gt;over 1 GB of RAM&lt;/strong&gt;. &lt;code&gt;rekuiper&lt;/code&gt; beats it in single-core throughput while consuming &lt;strong&gt;125x less RAM&lt;/strong&gt; (&amp;lt; 8.2 MB).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  3. &lt;strong&gt;Cold Boot Time&lt;/strong&gt;: &lt;code&gt;rekuiper&lt;/code&gt; boots internally in &lt;strong&gt;~13 ms&lt;/strong&gt; (123 ms OS spawn to socket ready), compared to 1.2s for Go eKuiper and 20s for Apache Flink.
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Reproduce It in 2 Minutes
&lt;/h3&gt;

&lt;p&gt;All reproduction scripts and Docker configs are in the repository. Anyone can run the whole suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/ankur-paan/rekuiper.git
&lt;span class="nb"&gt;cd &lt;/span&gt;rekuiper
./test/benchmark/run_all.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>rust</category>
      <category>iot</category>
      <category>performance</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
