{"id":31378,"date":"2025-02-10T11:08:09","date_gmt":"2025-02-10T10:08:09","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=31378"},"modified":"2025-02-10T11:12:33","modified_gmt":"2025-02-10T10:12:33","slug":"queueing-without-a-queue-enter-fastq","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/","title":{"rendered":"Queueing Without a Queue: Enter fastq"},"content":{"rendered":"\n<p>How often have you needed to decouple processes using a queue, only to find that you didn&#8217;t have one due to limitations such as <strong>resource constraints<\/strong> or the inability to install additional software?<\/p>\n\n\n\n<p>In this series, I&#8217;ll show you how to solve this problem by using different libraries of tools that help you resolve it even if you do not have a real queue. These solutions are versatile and can be applied to a variety of scenarios.<\/p>\n\n\n\n<p>Before getting started, I want to reassure you: these approaches are not just for when you cannot have a real queue due to limitations. <strong>They are also flexible enough<\/strong> to be used even when you can have one, without any problem.<br>By exploring the examples in this series, you&#8217;ll evaluate which approach is the best for your case.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-fastq\">Fastq<\/h2>\n\n\n\n<p>The first post is about <a href=\"https:\/\/github.com\/mcollina\/fastq\" target=\"_blank\" rel=\"noreferrer noopener\">fastq<\/a>, an npm package for <a href=\"https:\/\/nodejs.org\/en\" target=\"_blank\" rel=\"noreferrer noopener\">Node.js<\/a> built by <a href=\"https:\/\/nodeland.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Matteo Collina<\/a>.<br>As you can understand, this solution only works in a Node.js environment.<br>Using this package, you can create one or more <strong>in-memory <\/strong>queues.<br>This means that when the process kills, you will lose all the data in the queue, and you will need a strategy to recreate the queue on the application&#8217;s startup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-getting-started-with-fastq\">Getting started with fastq<\/h2>\n\n\n\n<p>To get started with fastq, you must install it on your Node.js project.<br>I have already created a simple project for you to follow along with the post; you can find it <a href=\"https:\/\/github.com\/Puppo\/queueing-without-a-queue\/tree\/fastq-init\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<br>So, the first simple step, after the <em><kbd>git clone<\/kbd><\/em> and the <em><kbd>npm install<\/kbd><\/em>, is to run the command <em><kbd>npm install fastq<\/kbd><\/em>, which installs the dependency in your project.<br>With that, you are ready to use fastq on your project.<br>As you can see, this package&#8217;s setup is smooth and easy to do.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-my-first-queue\">My first queue<\/h3>\n\n\n\n<p>Now, it&#8217;s time to create your first queue.<br>Fastq has a simple API to interact with it. You must create a function that is the worker for your queue. This function has the first argument, which is the item to handle in the queue, and a second argument, which depends on which approach you want to follow to complete the item&#8217;s execution. If you like to use the callback approach, the second argument is your done function to call at the end of the worker; if there is a successful execution, the callback must be invoked with null as the first parameter. Otherwise, you must pass the error as the first parameter. Instead, if you are a promise approacher, you can skip this argument and handle the error throwing it, as you already know.<\/p>\n\n\n\n<p>You&#8217;ll follow the promising approach for this post, but feel free to write the code using callback if you prefer.<\/p>\n\n\n\n<p>Let&#8217;s create a new file <code>src\/queue.ts<\/code> containing our queue worker.<br>To simply this post, this queue will emulate the user&#8217;s sign-up in a real system, and its ownership will be to send a fake email to the user to confirm its email. As you can imagine, you won&#8217;t dive into all these details, but you&#8217;ll fake some services to have an accurate idea of what you can do with fastq.<br>So now it&#8217;s time to build your first queue! In the <code>queue.ts<\/code> file, let&#8217;s start with the interface definition of the task.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">interface<\/span> UserCreatedTask {\n\u00a0id: <span class=\"hljs-built_in\">string<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This interface describes what your item in the queue looks like.<br>Now, you need to use it to handle the process in the queue, so first, you need to import some dependencies.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">type<\/span> { queueAsPromised } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'fastq'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> * <span class=\"hljs-keyword\">as<\/span> fastq <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'fastq'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> logger <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'logger.js'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { setTimeout } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'node:timers\/promises'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The first two imports are used for the queue; the logger shows some in the terminal during the execution, and the setTimeout fakes the execution time of an external service (in this case, a fake SMTP server).<br>With all these dependencies now you can create your worker.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">userInsertHandler<\/span>(<span class=\"hljs-params\">arg: UserCreatedTask<\/span>) <\/span>{\n  logger.info(arg, <span class=\"hljs-string\">'User created task received'<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> fakeImplementation = <span class=\"hljs-built_in\">Math<\/span>.random() &gt; <span class=\"hljs-number\">0.8<\/span> ? <span class=\"hljs-string\">'success'<\/span> : <span class=\"hljs-string\">'error'<\/span>\n  <span class=\"hljs-keyword\">const<\/span> timeout = fakeImplementation === <span class=\"hljs-string\">'success'<\/span> ? <span class=\"hljs-number\">2000<\/span> : <span class=\"hljs-number\">1000<\/span>;\n  <span class=\"hljs-keyword\">await<\/span> setTimeout(timeout);\n  <span class=\"hljs-keyword\">if<\/span> (fakeImplementation === <span class=\"hljs-string\">'error'<\/span>) {\n    <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">`User created task got error with id: <span class=\"hljs-subst\">${arg.id}<\/span>`<\/span>);\n }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As you can see, this function is easy but can give you all the ideas required to handle a queue with fastq.<br>First, the argument is of type <code>UserCreatedTask<\/code>,  which means that you expect the item to have that shape.<br>Then, you faked a success or error result using a simple <code>Math.random()<\/code>. If the result is successful, the execution will wait for 2 seconds and then resolve the promise; otherwise, the execution will wait for 1 second and raise an error.<br>Very easy, as you can understand.<br>But now you need to associate this worker to a real fastq queue; to do that, you must type this code.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">const<\/span> queue: queueAsPromised&lt;UserCreatedTask&gt; = fastq.promise(userInsertHandler, <span class=\"hljs-number\">1<\/span>);\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> queue;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Using the <code>fastq.promise<\/code> method, you create your queue with fastq and associate your <code>userInsertHandler<\/code> worker to your queue. Last but not least, the second parameter is the number of concurrency workers you want to have; in this case, there is just one worker for this queue, but you can increase it if you prefer.<br>The last row exposes the queue outside this JS module and allows pushing items inside the queue.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2025\/02\/fastq.png\" alt=\"mcollina fastq node\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-pushing-data-inside-the-code\">Pushing data inside the code<\/h3>\n\n\n\n<p>The last puzzle piece is about pushing data inside the queue.<br>To do that, you need to import the queue in the consumer module and invoke the push method.<br>So, move to the <code>src\/index.ts<\/code> file and import the queue.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">import<\/span> userInsertQueue <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/queue.js'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, you&#8217;ll create a fake running method that creates different user IDs and pushes them inside the queue.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">run<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> usersToHandle = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Array<\/span>(<span class=\"hljs-number\">5<\/span>).fill(<span class=\"hljs-literal\">undefined<\/span>).map(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> randomUUID())\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> id of usersToHandle) {\n    <span class=\"hljs-keyword\">const<\/span> task = {\n      id\n }\n    userInsertQueue.push(task)\n .then(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      logger.info(task, <span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> has been completed`<\/span>);\n })\n .catch(<span class=\"hljs-function\">(<span class=\"hljs-params\"><span class=\"hljs-params\">error<\/span><\/span>) =&gt;<\/span> {\n      logger.error(task, <span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> has failed`<\/span>, error);\n })\n    logger.info(task, <span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> has been pushed`<\/span>);\n }\n}\n\nrun()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As you can see, the push method is a promise, so you can handle the promise result to understand when the task will be resolved or rejected.<br>Please remember this because it will be helpful when discussing the retry strategy.<br>Okay, let&#8217;s return to the example. In this run method, you create a user ID list using the <code>randomUUID<\/code> method. Then, looping the list, you push the element inside the queue. Using the then and catch methods, you log the result of the execution of that ID.<br>Perfect, it&#8217;s time to check the result, so move to the terminal and run the command <kbd>npm run start<\/kbd>.<br>You should see something like this in your terminal<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">&#91;14:35:13.067] INFO (59175): User created task received\n    id: <span class=\"hljs-string\">\"a966759c-f385-4651-a0c1-55742ceb4017\"<\/span>\n&#91;14:35:13.067] INFO (59175): Task with id a966759c-f385-4651-a0c1-55742ceb4017 has been pushed\n    id: <span class=\"hljs-string\">\"a966759c-f385-4651-a0c1-55742ceb4017\"<\/span>\n&#91;14:35:13.067] INFO (59175): Task with id 24d9d735-2399-471e-b64c-55ee0c769daa has been pushed\n    id: <span class=\"hljs-string\">\"24d9d735-2399-471e-b64c-55ee0c769daa\"<\/span>\n&#91;14:35:13.067] INFO (59175): Task with id 726b4bc5-794d-4581-a96c-e41a474c446d has been pushed\n    id: <span class=\"hljs-string\">\"726b4bc5-794d-4581-a96c-e41a474c446d\"<\/span>\n&#91;14:35:13.067] INFO (59175): Task with id 1a6dd1b4-2123-410b-a2ad-f420a14d53e9 has been pushed\n    id: <span class=\"hljs-string\">\"1a6dd1b4-2123-410b-a2ad-f420a14d53e9\"<\/span>\n&#91;14:35:13.067] INFO (59175): Task with id 6a8681e4-bba4-42e0-b484-976de8be9bcb has been pushed\n    id: <span class=\"hljs-string\">\"6a8681e4-bba4-42e0-b484-976de8be9bcb\"<\/span>\n&#91;14:35:14.069] INFO (59175): User created task received\n    id: <span class=\"hljs-string\">\"24d9d735-2399-471e-b64c-55ee0c769daa\"<\/span>\n&#91;14:35:14.070] ERROR (59175): Task with id a966759c-f385-4651-a0c1-55742ceb4017 has failed\n    id: <span class=\"hljs-string\">\"a966759c-f385-4651-a0c1-55742ceb4017\"<\/span>\n&#91;14:35:15.070] INFO (59175): User created task received\n    id: <span class=\"hljs-string\">\"726b4bc5-794d-4581-a96c-e41a474c446d\"<\/span>\n&#91;14:35:15.071] ERROR (59175): Task with id 24d9d735-2399-471e-b64c-55ee0c769daa has failed\n    id: <span class=\"hljs-string\">\"24d9d735-2399-471e-b64c-55ee0c769daa\"<\/span>\n&#91;14:35:16.071] INFO (59175): User created task received\n    id: <span class=\"hljs-string\">\"1a6dd1b4-2123-410b-a2ad-f420a14d53e9\"<\/span>\n&#91;14:35:16.071] ERROR (59175): Task with id 726b4bc5-794d-4581-a96c-e41a474c446d has failed\n    id: <span class=\"hljs-string\">\"726b4bc5-794d-4581-a96c-e41a474c446d\"<\/span>\n&#91;14:35:17.072] INFO (59175): User created task received\n    id: <span class=\"hljs-string\">\"6a8681e4-bba4-42e0-b484-976de8be9bcb\"<\/span>\n&#91;14:35:17.073] ERROR (59175): Task with id 1a6dd1b4-2123-410b-a2ad-f420a14d53e9 has failed\n    id: <span class=\"hljs-string\">\"1a6dd1b4-2123-410b-a2ad-f420a14d53e9\"<\/span>\n&#91;14:35:19.074] INFO (59175): Task with id 6a8681e4-bba4-42e0-b484-976de8be9bcb has been completed\n    id: <span class=\"hljs-string\">\"6a8681e4-bba4-42e0-b484-976de8be9bcb\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Double-checking the result, you can notice that some tasks have been failed and others have been completed. So, as you can understand, there isn&#8217;t any retry strategy out-of-the-box in fastq, because the failed tasks remain failed at the end of the execution.<br>So, how can you build your retry strategy?<br>In this example, a map can be used to save the task&#8217;s status and the number of retries.<br>Let&#8217;s see the implementations<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">import<\/span> logger <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'logger.js'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { randomUUID } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'node:crypto'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> userInsertQueue <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/queue.js'<\/span>;\n\n<span class=\"hljs-keyword\">type<\/span> Status = <span class=\"hljs-string\">'not-handle'<\/span> | <span class=\"hljs-string\">'error'<\/span> | <span class=\"hljs-string\">'success'<\/span>\n\n<span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">run<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> usersToHandle = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Array<\/span>(<span class=\"hljs-number\">5<\/span>).fill(<span class=\"hljs-literal\">undefined<\/span>).map(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> randomUUID())\n  <span class=\"hljs-keyword\">const<\/span> userProcessStatus: Record&lt;<span class=\"hljs-built_in\">string<\/span>, { status: Status, retryValue: <span class=\"hljs-built_in\">number<\/span> }&gt; = {}\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> id of usersToHandle) {\n    userProcessStatus&#91;id] = {\n      status: <span class=\"hljs-string\">'not-handle'<\/span>,\n      retryValue: <span class=\"hljs-number\">0<\/span>\n };\n    <span class=\"hljs-keyword\">const<\/span> task = {\n      id\n }\n    <span class=\"hljs-keyword\">const<\/span> pushMessage = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> userInsertQueue.push(task)\n .then(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        logger.info(<span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> has been proceed`<\/span>);\n        userProcessStatus&#91;id].status = <span class=\"hljs-string\">'success'<\/span>;\n })\n .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">err<\/span> =&gt;<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> state = userProcessStatus&#91;id]\n        logger.error(err, <span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> got error after retry <span class=\"hljs-subst\">${state.retryValue}<\/span>`<\/span>);\n        state.status = <span class=\"hljs-string\">'error'<\/span>;\n        <span class=\"hljs-keyword\">if<\/span> (state.retryValue &lt; <span class=\"hljs-number\">3<\/span>) {\n          state.retryValue++\n          pushMessage()\n }\n })\n    pushMessage()\n    logger.info(task, <span class=\"hljs-string\">`Task with id <span class=\"hljs-subst\">${task.id}<\/span> has been pushed`<\/span>);\n }\n\n  process.on(<span class=\"hljs-string\">'exit'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">const<\/span> &#91;id, { status, retryValue }] of <span class=\"hljs-built_in\">Object<\/span>.entries(userProcessStatus)) {\n      logger.info(<span class=\"hljs-string\">`Id <span class=\"hljs-subst\">${id}<\/span> is <span class=\"hljs-subst\">${status}<\/span> after <span class=\"hljs-subst\">${retryValue}<\/span> retries`<\/span>);\n }\n })\n}\n\nrun()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this approach, the <code>userProcessStatus<\/code> map contains the user IDs as keys and an object with two fields: the user&#8217;s status and the retries for that ID in the values.<br>Then, using the <code>pushMessage<\/code> you create a method that handles this map. First, you push the element in the queue, and waiting for the result, you can handle the retry in case of failure. So, if the result succeeds, you can set the element in the map as completed. Still, if the element fails, you set the status as <code>error<\/code>, and if the retry number is less than three, you increase the retry number and invoke the pushMessage again to retry that specific element.<br>I also added a hook before exiting the process to recap the tasks&#8217; results just for debugging.<br>Now, you can run <kbd>npm run start<\/kbd> again and look at the result. You will notice that the program tries to handle the failed tasks before ending.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n\n\n\n<p>It&#8217;s time to wrap up this blog post.<br>In this article, you learnt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>how to create your worker<\/li>\n\n\n\n<li>how to create a queue with fastq and associate this queue with your worker<\/li>\n\n\n\n<li>how to push items in the queue<\/li>\n\n\n\n<li>how to build a retry strategy for your item in the queue<\/li>\n<\/ul>\n\n\n\n<p>As you understand, this is a good solution in some scenarios and is easy to use, but it has some complications you must handle. First, if you need a retry strategy, you must implement it; second, this solution is entirely in memory, so you must hold the status of your entity in some way; otherwise, if the process dies, you&#8217;ll lose the status of your system.<br>That&#8217;s it from this blog post; I hope you&#8217;ve enjoyed it, and see you soon for the next chapter.<\/p>\n\n\n\n<p><em>You can find the result of this post at this <a href=\"https:\/\/github.com\/Puppo\/queueing-without-a-queue\/tree\/fastq-result\">link<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How often have you needed to decouple processes using a queue, only to find that you didn&#8217;t have one due to limitations such as resource constraints or the inability to install additional software? In this series, I&#8217;ll show you how to solve this problem by using different libraries of tools that help you resolve it&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\">Read more<\/a><\/p>\n","protected":false},"author":309,"featured_media":26972,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[9825],"tags":[13091,13093,13095,13097],"collections":[],"class_list":{"0":"post-31378","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-software-architecture","8":"tag-collina","9":"tag-node","10":"tag-npm","11":"tag-queue","12":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Queueing Without a Queue: Enter fastq - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Queueing Without a Queue: Enter fastq\" \/>\n<meta property=\"og:description\" content=\"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-10T10:08:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-10T10:12:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1792\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Puppo92\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Puppo92\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\"},\"author\":{\"name\":\"Puppo92\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/59285912d17139a5023ec1bc0850571f\"},\"headline\":\"Queueing Without a Queue: Enter fastq\",\"datePublished\":\"2025-02-10T10:08:09+00:00\",\"dateModified\":\"2025-02-10T10:12:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\"},\"wordCount\":1351,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp\",\"keywords\":[\"collina\",\"node\",\"npm\",\"queue\"],\"articleSection\":[\"Software Architecture\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\",\"name\":\"Queueing Without a Queue: Enter fastq - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp\",\"datePublished\":\"2025-02-10T10:08:09+00:00\",\"dateModified\":\"2025-02-10T10:12:33+00:00\",\"description\":\"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp\",\"width\":1792,\"height\":1024,\"caption\":\"srping MVC vis spring threads\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/backend\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Software Architecture\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Queueing Without a Queue: Enter fastq\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/59285912d17139a5023ec1bc0850571f\",\"name\":\"Puppo92\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f53382233f04621eca9e506d7cc3bbed35855197ea72254ad3e31b9a0b6d39a8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f53382233f04621eca9e506d7cc3bbed35855197ea72254ad3e31b9a0b6d39a8?s=96&d=mm&r=g\",\"caption\":\"Puppo92\"},\"description\":\"I'm a Senior Software Developer, Microsoft MVP, Google Developer Expert Codemotion Ambassador and GitKraken Ambassador. I love JavaScript and TypeScript. In my free time, I love studying new technologies, improving myself, creating YouTube content or writing technical articles. I can\u2019t stay without trail running and love to do it in my love Dolomiti.\",\"sameAs\":[\"https:\/\/www.delpuppo.net\/\"],\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/puppo92\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Queueing Without a Queue: Enter fastq - Codemotion Magazine","description":"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/","og_locale":"en_US","og_type":"article","og_title":"Queueing Without a Queue: Enter fastq","og_description":"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.","og_url":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2025-02-10T10:08:09+00:00","article_modified_time":"2025-02-10T10:12:33+00:00","og_image":[{"width":1792,"height":1024,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp","type":"image\/webp"}],"author":"Puppo92","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Puppo92","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/"},"author":{"name":"Puppo92","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/59285912d17139a5023ec1bc0850571f"},"headline":"Queueing Without a Queue: Enter fastq","datePublished":"2025-02-10T10:08:09+00:00","dateModified":"2025-02-10T10:12:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/"},"wordCount":1351,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp","keywords":["collina","node","npm","queue"],"articleSection":["Software Architecture"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/","url":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/","name":"Queueing Without a Queue: Enter fastq - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp","datePublished":"2025-02-10T10:08:09+00:00","dateModified":"2025-02-10T10:12:33+00:00","description":"Learn how to manage process queues without a traditional queue system using Fastq, a Node.js library. This article guides you through creating an in-memory queue, implementing a retry strategy, and efficiently handling tasks.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp","width":1792,"height":1024,"caption":"srping MVC vis spring threads"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/queueing-without-a-queue-enter-fastq\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Backend","item":"https:\/\/www.codemotion.com\/magazine\/backend\/"},{"@type":"ListItem","position":3,"name":"Software Architecture","item":"https:\/\/www.codemotion.com\/magazine\/backend\/software-architecture\/"},{"@type":"ListItem","position":4,"name":"Queueing Without a Queue: Enter fastq"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/59285912d17139a5023ec1bc0850571f","name":"Puppo92","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f53382233f04621eca9e506d7cc3bbed35855197ea72254ad3e31b9a0b6d39a8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f53382233f04621eca9e506d7cc3bbed35855197ea72254ad3e31b9a0b6d39a8?s=96&d=mm&r=g","caption":"Puppo92"},"description":"I'm a Senior Software Developer, Microsoft MVP, Google Developer Expert Codemotion Ambassador and GitKraken Ambassador. I love JavaScript and TypeScript. In my free time, I love studying new technologies, improving myself, creating YouTube content or writing technical articles. I can\u2019t stay without trail running and love to do it in my love Dolomiti.","sameAs":["https:\/\/www.delpuppo.net\/"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/puppo92\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-600x400.webp","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-600x600.webp","author_info":{"display_name":"Puppo92","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/puppo92\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp",1792,1024,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-150x150.webp",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-300x171.webp",300,171,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-768x439.webp",768,439,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-1024x585.webp",1024,585,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-1536x878.webp",1536,878,true],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog.webp",1792,1024,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-100x100.webp",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-180x128.webp",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-896x504.webp",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-400x225.webp",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-600x400.webp",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/DALL\u00b7E-2024-04-05-12.28.45-Illustrate-a-cartoon-style-image-showing-a-developer-coding-on-two-different-platforms-to-represent-coding-versatility-without-any-specific-technolog-600x600.webp",600,600,true]},"uagb_author_info":{"display_name":"Puppo92","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/puppo92\/"},"uagb_comment_info":0,"uagb_excerpt":"How often have you needed to decouple processes using a queue, only to find that you didn&#8217;t have one due to limitations such as resource constraints or the inability to install additional software? In this series, I&#8217;ll show you how to solve this problem by using different libraries of tools that help you resolve it&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/31378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/309"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=31378"}],"version-history":[{"count":3,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/31378\/revisions"}],"predecessor-version":[{"id":32029,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/31378\/revisions\/32029"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/26972"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=31378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=31378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=31378"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=31378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}