<?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: GrowerZer0</title>
    <description>The latest articles on DEV Community by GrowerZer0 (@growerzer0).</description>
    <link>https://dev.to/growerzer0</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%2F4002730%2F3cbe968f-94a0-4eee-82e9-a193b5576386.png</url>
      <title>DEV Community: GrowerZer0</title>
      <link>https://dev.to/growerzer0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/growerzer0"/>
    <language>en</language>
    <item>
      <title>Why I chose PGMQ over Redis for IoT sensor ingestion</title>
      <dc:creator>GrowerZer0</dc:creator>
      <pubDate>Tue, 07 Jul 2026 23:20:49 +0000</pubDate>
      <link>https://dev.to/growerzer0/why-i-chose-pgmq-over-redis-for-iot-sensor-ingestion-idl</link>
      <guid>https://dev.to/growerzer0/why-i-chose-pgmq-over-redis-for-iot-sensor-ingestion-idl</guid>
      <description>&lt;p&gt;In my last post, I introduced CultivatorsLedger — a local-first cultivation telemetry platform built on Next.js, PostgreSQL, and Docker. &lt;/p&gt;

&lt;p&gt;One of the first architectural decisions I made was how to handle sensor data ingestion. In a grow environment, WiFi is not reliable. Network drops happen. And when they do, standard HTTP posts lose data.&lt;/p&gt;

&lt;p&gt;I needed a queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Contenders
&lt;/h2&gt;

&lt;p&gt;I looked at three options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kafka&lt;/strong&gt; — powerful, but way too heavy for a homelab setup. I don't need a distributed log system to track VPD in a 4x4 tent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis&lt;/strong&gt; — lightweight and fast, but it meant adding another service to the stack. More moving parts, more things to break.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MQTT&lt;/strong&gt; — great for IoT, but it's a protocol, not a queue. I'd still need to handle reliability and persistence myself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why PGMQ
&lt;/h2&gt;

&lt;p&gt;PGMQ is a PostgreSQL extension that turns Postgres into a message queue. It's simple, reliable, and already built into the database I'm using.&lt;/p&gt;

&lt;p&gt;Here's the pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sensor data comes in via HTTP POST&lt;/li&gt;
&lt;li&gt;The API route sends it to the queue with &lt;code&gt;pgmq.send()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A worker picks it up with &lt;code&gt;pgmq.read()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The worker processes the data and inserts it into the timeseries tables&lt;/li&gt;
&lt;li&gt;The worker calls &lt;code&gt;pgmq.delete()&lt;/code&gt; to remove the message&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;If a sensor sends data and the worker is busy, the message stays in the queue. If the network drops, the message stays in the queue. If the server restarts, the message stays in the queue.&lt;/p&gt;

&lt;p&gt;No data loss. No complex broker setup. Just Postgres.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tradeoff
&lt;/h2&gt;

&lt;p&gt;PGMQ isn't as fast as Kafka at massive scale. But for a home grow or small facility, it's more than enough. And keeping everything in one database means fewer services to monitor and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;The consumer worker is a small Python script that runs continuously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pgmq&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PGMQ&lt;/span&gt;

&lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PGMQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sensor_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nf"&gt;save_to_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensor_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The worker reads one message at a time, processes it, and deletes it. If the processing fails, the message stays in the queue until the visibility timeout expires.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The architecture is stable. Now I'm working on the dashboard UI, Home Assistant integration, and CSV import.&lt;/p&gt;

&lt;p&gt;If you're building something similar or just want to follow along, check out the repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/growerzer0/cultivatorsledger" rel="noopener noreferrer"&gt;github.com/growerzer0/cultivatorsledger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or read the previous post: &lt;a href="https://dev.to/growerzer0/building-a-cultivation-dashboard-that-stays-on-your-hardware-335o"&gt;Building a Cultivation Dashboard That Stays On Your Hardware&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the Live Demo
&lt;/h2&gt;

&lt;p&gt;I've deployed an interactive demo so you can see what the dashboard looks like without installing anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://cultivators-ledger-omega.vercel.app" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Play with the VPD sliders, track dry-back progress, and test the feeding calculator. All data is simulated, but the experience is real.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>selfhosted</category>
      <category>iot</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building a cultivation dashboard that stays on your hardware</title>
      <dc:creator>GrowerZer0</dc:creator>
      <pubDate>Tue, 30 Jun 2026 12:52:27 +0000</pubDate>
      <link>https://dev.to/growerzer0/building-a-cultivation-dashboard-that-stays-on-your-hardware-335o</link>
      <guid>https://dev.to/growerzer0/building-a-cultivation-dashboard-that-stays-on-your-hardware-335o</guid>
      <description>&lt;p&gt;&lt;strong&gt;Live Demo is here!:&lt;/strong&gt; &lt;a href="https://cultivators-ledger-omega.vercel.app" rel="noopener noreferrer"&gt;https://cultivators-ledger-omega.vercel.app&lt;/a&gt;&lt;br&gt;
No installation required. Just click and explore the dashboard.&lt;/p&gt;

&lt;p&gt;I've spent most of my career in logistics and maintenance. When I started growing, I looked for telemetry tools and found a lot of cloud subscriptions and data lock-in. So I'm building something different.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm making:
&lt;/h2&gt;

&lt;p&gt;An open-source, local-first cultivation telemetry platform. VPD tracking, sensor ingestion, modern dashboard — all on your own hardware. No monthly fees. No data leaving your network unless you want it to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why local-first:
&lt;/h2&gt;

&lt;p&gt;I've seen too many systems fail because they depended on someone else's servers. I want data safety, redundancy, and control. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PGMQ with read() + delete()&lt;/strong&gt; for bulletproof ingestion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next.js dashboard&lt;/strong&gt; that talks to your own PostgreSQL instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full Docker Compose setup&lt;/strong&gt; for easy deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it's at right now:
&lt;/h2&gt;

&lt;p&gt;Early alpha. The dashboard is functional but rough. The architecture is solid but unproven. That's why I'm putting it on GitHub — to get feedback, find blind spots, and make it better with help from people who actually grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Try the Live Demo
&lt;/h2&gt;

&lt;p&gt;I've deployed an interactive demo so you can see what the dashboard looks like without installing anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://cultivators-ledger-omega.vercel.app" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Play with the VPD sliders, track dry-back progress, and test the feeding calculator. All data is simulated, but the experience is real.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm not building:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A walled-garden ecosystem&lt;/li&gt;
&lt;li&gt;A product that forces your data into the cloud&lt;/li&gt;
&lt;li&gt;A black-box platform that phones home&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;

&lt;p&gt;The repo is completely open-source: &lt;a href="https://github.com/growerzer0/cultivatorsledger" rel="noopener noreferrer"&gt;github.com/growerzer0/cultivatorsledger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm new to open-source. I'd highly appreciate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code reviews&lt;/li&gt;
&lt;li&gt;Architecture feedback&lt;/li&gt;
&lt;li&gt;Feature requests from real growers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll be posting architecture deep-dives next. Drop your thoughts or hardware setup in the comments below!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>selfhosted</category>
      <category>nextjs</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
