<?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: Panagiotis Panageas (Παναγιώτης Παναγέας)</title>
    <description>The latest articles on DEV Community by Panagiotis Panageas (Παναγιώτης Παναγέας) (@panagiotis_panageas).</description>
    <link>https://dev.to/panagiotis_panageas</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%2F3818412%2Fd2906771-9f83-4807-a3a8-2c8ab1a07f11.jpg</url>
      <title>DEV Community: Panagiotis Panageas (Παναγιώτης Παναγέας)</title>
      <link>https://dev.to/panagiotis_panageas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/panagiotis_panageas"/>
    <language>en</language>
    <item>
      <title>Conductor: PostgreSQL-Backed Async Task Queue for Python (No Redis Required)</title>
      <dc:creator>Panagiotis Panageas (Παναγιώτης Παναγέας)</dc:creator>
      <pubDate>Fri, 14 Aug 2026 06:01:04 +0000</pubDate>
      <link>https://dev.to/panagiotis_panageas/conductor-postgresql-backed-async-task-queue-for-python-no-redis-required-29en</link>
      <guid>https://dev.to/panagiotis_panageas/conductor-postgresql-backed-async-task-queue-for-python-no-redis-required-29en</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: Do You Really Need Redis or RabbitMQ?
&lt;/h2&gt;

&lt;p&gt;Let me paint you a picture.&lt;/p&gt;

&lt;p&gt;You're building a Python application that needs to process background tasks. Maybe you're sending emails, generating reports, or processing images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1:&lt;/strong&gt; You deploy Redis or RabbitMQ. Now you're managing another service, dealing with persistence concerns, and increasing your infrastructure complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2:&lt;/strong&gt; You use Celery with Redis or RabbitMQ. It works, but you now have a sprawling configuration just to send a few emails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Hidden Cost:&lt;/strong&gt; For many projects, a separate message broker is overkill. You're spending more time managing infrastructure than building features.&lt;/p&gt;

&lt;p&gt;I faced this exact situation. So I built &lt;a href="https://github.com/Archangel-77/conductor" rel="noopener noreferrer"&gt;Conductor&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing Conductor
&lt;/h2&gt;

&lt;p&gt;Conductor is a &lt;strong&gt;PostgreSQL-backed async task queue&lt;/strong&gt; for Python teams that don't want to manage a separate message broker.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Makes Conductor Different?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. PostgreSQL as the Backend&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No new infrastructure to deploy&lt;/li&gt;
&lt;li&gt;Leverages PostgreSQL's durability and transaction guarantees&lt;/li&gt;
&lt;li&gt;Your existing database now powers your task queue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Exactly-Once Semantics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks run exactly once, no duplicates&lt;/li&gt;
&lt;li&gt;Idempotency is built into the design&lt;/li&gt;
&lt;li&gt;PostgreSQL's &lt;code&gt;ON CONFLICT&lt;/code&gt; ensures atomic operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Built for Async Python&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully &lt;code&gt;asyncio&lt;/code&gt; compatible&lt;/li&gt;
&lt;li&gt;Async workers that don't block your event loop&lt;/li&gt;
&lt;li&gt;FastAPI integration ready&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Production-Ready Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exponential backoff with jitter for retries&lt;/li&gt;
&lt;li&gt;Dead letter queue for failed tasks&lt;/li&gt;
&lt;li&gt;Prometheus metrics for observability&lt;/li&gt;
&lt;li&gt;Structured logging with request tracing&lt;/li&gt;
&lt;li&gt;Health checks for your workers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Impressive Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;400+ tasks per second&lt;/strong&gt; throughput per worker&lt;/li&gt;
&lt;li&gt;Scales horizontally with multiple workers&lt;/li&gt;
&lt;li&gt;Low latency for task scheduling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Example: How It Works
&lt;/h2&gt;



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

&lt;span class="c1"&gt;# Initialize with your existing PostgreSQL connection
&lt;/span&gt;&lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Conductor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgresql://user:pass@localhost/db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define a task
&lt;/span&gt;&lt;span class="nd"&gt;@conductor.task&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Your email sending logic here
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sending &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Schedule the task
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Thanks for signing up.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Run the worker
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&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. No Redis. No RabbitMQ. Just your PostgreSQL database.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Features You Actually Need
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Exactly-Once Semantics
&lt;/h3&gt;

&lt;p&gt;In production, duplicate task execution can be catastrophic. Imagine sending two welcome emails or processing a payment twice.&lt;/p&gt;

&lt;p&gt;Conductor uses PostgreSQL's transaction isolation and &lt;code&gt;ON CONFLICT&lt;/code&gt; to guarantee each task runs exactly once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Atomic task insertion with deduplication&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'unique_id_123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'send_email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{"to":"user@example.com"}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;CONFLICT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DO&lt;/span&gt; &lt;span class="k"&gt;NOTHING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Exponential Backoff with Jitter
&lt;/h3&gt;

&lt;p&gt;When a task fails, you want to retry - but not all at once.&lt;/p&gt;

&lt;p&gt;Conductor implements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurable retry policies&lt;/li&gt;
&lt;li&gt;Exponential backoff: &lt;code&gt;attempt^2&lt;/code&gt; seconds&lt;/li&gt;
&lt;li&gt;Jitter: adding random variance to prevent thundering herds&lt;/li&gt;
&lt;li&gt;Max retry limits to prevent infinite loops
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@conductor.task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;retry_delay_base&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Seconds: 2, 4, 8, 16, 32
&lt;/span&gt;    &lt;span class="n"&gt;retry_with_jitter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;flaky_api_call&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# This will retry with smart delays
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Dead Letter Queue
&lt;/h3&gt;

&lt;p&gt;Sometimes tasks just can't be processed. Maybe the data is corrupt, or an external API is permanently down.&lt;/p&gt;

&lt;p&gt;Conductor moves failed tasks to a dead letter queue for manual inspection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track why tasks failed&lt;/li&gt;
&lt;li&gt;Reprocess them after fixing the issue&lt;/li&gt;
&lt;li&gt;Prevent invalid tasks from clogging your system&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Observability Built-In
&lt;/h3&gt;

&lt;p&gt;A task queue is a black box unless you can see inside it.&lt;/p&gt;

&lt;p&gt;Conductor provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus metrics&lt;/strong&gt; for task rates, success/failure counts, and latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured JSON logging&lt;/strong&gt; with trace IDs for debugging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana dashboards&lt;/strong&gt; for real-time monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health check endpoints&lt;/strong&gt; for load balancers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Deployment Guides
&lt;/h3&gt;

&lt;p&gt;I've included guides for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker Compose&lt;/strong&gt;: Local development with one command&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes&lt;/strong&gt;: Production deployment with rolling updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;systemd&lt;/strong&gt;: Traditional server deployment&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Benchmarks: Conductor vs. Redis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Conductor (PostgreSQL)&lt;/th&gt;
&lt;th&gt;Redis RQ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tasks/sec per worker&lt;/td&gt;
&lt;td&gt;400+&lt;/td&gt;
&lt;td&gt;~500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message persistence&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No (optional)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transaction support&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exactly-once semantics&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operational complexity&lt;/td&gt;
&lt;td&gt;✅ Low&lt;/td&gt;
&lt;td&gt;⚠️ Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Verdict:&lt;/strong&gt; Redis RQ is faster by ~20%, but Conductor offers stronger guarantees with less operational overhead.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Should Use Conductor?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✅ Use Conductor if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You already use PostgreSQL&lt;/li&gt;
&lt;li&gt;You don't want to manage Redis or RabbitMQ&lt;/li&gt;
&lt;li&gt;You need exactly-once task execution&lt;/li&gt;
&lt;li&gt;You're building a FastAPI / async Python application&lt;/li&gt;
&lt;li&gt;You're in the early stages of your project and want to keep it simple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Don't use Conductor if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need sub-millisecond task latency&lt;/li&gt;
&lt;li&gt;You're processing millions of tasks per second&lt;/li&gt;
&lt;li&gt;You need complex routing or priority queues&lt;/li&gt;
&lt;li&gt;Your team is already expert in Celery/Redis&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started in 3 Minutes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Conductor
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;conductor-task-queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create Your PostgreSQL Database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;conductor_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Write Your First Task
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# tasks.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Conductor&lt;/span&gt;

&lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Conductor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgresql://user:pass@localhost/conductor_db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@conductor.task&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="c1"&gt;# Schedule it
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;add_numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Start Your Worker
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# worker.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;conductor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Monitor Your Tasks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# monitor.py
&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_task_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task_id_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Result: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&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;h2&gt;
  
  
  What's Next for Conductor?
&lt;/h2&gt;

&lt;p&gt;I'm actively developing Conductor and have big plans:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[ ] Dashboard UI&lt;/strong&gt; for task management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[ ] Cron-like scheduled tasks&lt;/strong&gt; with interval support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[ ] Batch processing&lt;/strong&gt; for parallel execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[ ] WebSocket support&lt;/strong&gt; for real-time updates&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How You Can Help
&lt;/h2&gt;

&lt;p&gt;Conductor is open-source and MIT licensed. Here's how you can contribute:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⭐ Star the repository:&lt;/strong&gt; &lt;a href="https://github.com/Archangel-77/conductor" rel="noopener noreferrer"&gt;GitHub - Conductor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐛 Report issues:&lt;/strong&gt; Found a bug? Open an issue on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Suggest features:&lt;/strong&gt; Tell me what you need from a task queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔧 Contribute code:&lt;/strong&gt; PRs are welcome for bug fixes and improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Write documentation:&lt;/strong&gt; Good docs are essential for adoption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connect With Me
&lt;/h2&gt;

&lt;p&gt;I'm Panagiotis Panageas, a Python backend engineer building production systems in Europe.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Archangel-77" rel="noopener noreferrer"&gt;@Archangel-77&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open to roles:&lt;/strong&gt; Remote or EU-based backend engineering positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using Conductor or building similar tools, I'd love to hear about your experience!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Have you tried using PostgreSQL as a task queue? What challenges did you face? Share your experience in the comments below! 👇&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>postgressql</category>
      <category>opensource</category>
      <category>database</category>
    </item>
    <item>
      <title>How I Built agent-pr-firewall: A GitHub App PR Governance Check</title>
      <dc:creator>Panagiotis Panageas (Παναγιώτης Παναγέας)</dc:creator>
      <pubDate>Wed, 11 Mar 2026 11:36:45 +0000</pubDate>
      <link>https://dev.to/panagiotis_panageas/how-i-built-agent-pr-firewall-a-github-app-pr-governance-check-1nll</link>
      <guid>https://dev.to/panagiotis_panageas/how-i-built-agent-pr-firewall-a-github-app-pr-governance-check-1nll</guid>
      <description>&lt;p&gt;AI-assisted coding increased risky PR patterns in my workflow. I built agent-pr-firewall to enforce one required governance check before merge, with policy-based pass/warn/block decisions.&lt;/p&gt;

&lt;p&gt;Why CI alone was not enough&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The policy model (pass/warn/block)&lt;/li&gt;
&lt;li&gt;GitHub App webhook architecture&lt;/li&gt;
&lt;li&gt;Policies that matter in practice&lt;/li&gt;
&lt;li&gt;Branch protection as the enforcement point&lt;/li&gt;
&lt;li&gt;Observability and failure handling&lt;/li&gt;
&lt;li&gt;Lessons learned and next steps&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/Archangel-77/agent-pr-firewall" rel="noopener noreferrer"&gt;https://github.com/Archangel-77/agent-pr-firewall&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Release: &lt;a href="https://github.com/Archangel-77/agent-firewall/releases/tag/v0.1.1" rel="noopener noreferrer"&gt;https://github.com/Archangel-77/agent-firewall/releases/tag/v0.1.1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Proof PR/checks: &lt;a href="https://github.com/Archangel-77/agent-pr-firewall/pull/2" rel="noopener noreferrer"&gt;https://github.com/Archangel-77/agent-pr-firewall/pull/2&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
