<?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>Forem: Lucas Merencia</title>
    <description>The latest articles on Forem by Lucas Merencia (@merencia).</description>
    <link>https://forem.com/merencia</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3412308%2Fd9434975-b268-4b36-a95e-a3c54712200f.png</url>
      <title>Forem: Lucas Merencia</title>
      <link>https://forem.com/merencia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/merencia"/>
    <language>en</language>
    <item>
      <title>Just launched: Sidequest.js, a background job processing for Node.js using your existing database.</title>
      <dc:creator>Lucas Merencia</dc:creator>
      <pubDate>Mon, 04 Aug 2025 16:24:52 +0000</pubDate>
      <link>https://forem.com/merencia/just-launched-sidequestjs-a-background-job-processing-for-nodejs-using-your-existing-database-1p24</link>
      <guid>https://forem.com/merencia/just-launched-sidequestjs-a-background-job-processing-for-nodejs-using-your-existing-database-1p24</guid>
      <description>&lt;p&gt;Hey folks 👋&lt;/p&gt;

&lt;p&gt;A while ago I built &lt;a href="https://nodecron.com/" rel="noopener noreferrer"&gt;node-cron&lt;/a&gt;, a small library to schedule recurring tasks in Node.js. It got pretty popular (5M+ downloads/month), and I'm happy to see how widely it’s been adopted.&lt;/p&gt;

&lt;p&gt;But over time, I noticed a recurring issue: people were running it inside production APIs (like Express apps), which led to some serious problems. Running background jobs inside Express apps can cause blocking I/O and make your API unresponsive.&lt;/p&gt;

&lt;p&gt;Also, if your app is deployed across multiple instances, each one might run the same job, unless you set up a distributed locking mechanism manually.&lt;/p&gt;

&lt;p&gt;To solve that, we created &lt;a href="https://sidequestjs.com/" rel="noopener noreferrer"&gt;Sidequest.js&lt;/a&gt;, a background job runner for Node.js focused on simplicity, isolation, and zero lock-in.&lt;/p&gt;

&lt;p&gt;It’s inspired by Oban (Elixir) and Sidekiq (Rails), but works with infrastructure most people already have. You can use PostgreSQL, MySQL, SQLite, or MongoDB as a backend, reusing the same database your app already relies on.&lt;/p&gt;

&lt;p&gt;Jobs run in worker threads, isolated from your app’s main process. The system supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unique jobs&lt;/li&gt;
&lt;li&gt;retries with exponential backoff&lt;/li&gt;
&lt;li&gt;snoozing &amp;amp; priorities&lt;/li&gt;
&lt;li&gt;concurrency control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s how it looks in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Sidequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Job&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sidequest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailJob&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Job&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Sending email to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Enqueue&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Sidequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EmailJob&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Starting Sidequest&lt;/span&gt;
&lt;span class="nx"&gt;Sidequest&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;span class="na"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@sidequest/postgres-backend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres://postgres:postgres@localhost:5432/my_database&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;There's also a dashboard to monitor everything:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faw3gbohmj2s0vnt5m0y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faw3gbohmj2s0vnt5m0y2.png" alt=" " width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve used BullMQ and want something that doesn’t depend solely on Redis, or if you’re tired of being locked into SQS or other cloud services — give Sidequest a try.&lt;/p&gt;

&lt;p&gt;Just released the first stable version. I would love your feedback!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧪 &lt;a href="https://docs.sidequestjs.com/overview" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;a href="https://github.com/sidequestjs/sidequest" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for checking it out!&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>distributedsystems</category>
    </item>
  </channel>
</rss>
