{"id":22826,"date":"2021-03-04T08:00:00","date_gmt":"2021-03-04T08:00:00","guid":{"rendered":"https:\/\/codeandpepper.com\/?p=22826"},"modified":"2023-10-11T14:17:19","modified_gmt":"2023-10-11T14:17:19","slug":"asynclocalstorage-in-node-js","status":"publish","type":"post","link":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/","title":{"rendered":"Simple Context Passing With AsyncLocalStorage in Node.js"},"content":{"rendered":"\n<p>Node.js is one of the most popular programming languages used on the web nowadays. It\u2019s single core design has lots of positives, but sometimes can be a little challenging &#8211; especially when it comes to passing the context between asynchronous invocations. It seems not to be such a problem anymore, though. Developers can use <strong>AsyncLocalStorage in Node.js<\/strong> to overcome long lasting problems. Let\u2019s dive in to check how to do that.<\/p>\n\n\n\n<!--more-->\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\" alt=\"Context Passing With AsyncLocalStorage in Node.js\" class=\"wp-image-22845\" width=\"864\" height=\"450\" srcset=\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg 864w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-300x156.jpg 300w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-768x400.jpg 768w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-361x188.jpg 361w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-192x100.jpg 192w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-720x375.jpg 720w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js-432x225.jpg 432w\" sizes=\"auto, (max-width: 864px) 100vw, 864px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-problems-can-asynclocalstorage-in-node-js-solve\">What problems can AsyncLocalStorage in Node.js solve<\/h2>\n\n\n\n<p>I bet that most of you have written a custom HTTP request logger to be sure what\u2019s happening behind the scenes for each server invocation. The code roughly could look like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require(\"express\");\n\nconst { v4: uuid } = require(\"uuid\");\n\nconst indexRouter = require(\".\/routes\/index\");\n\nconst app = express();\n\nfunction requestLogger(req, ...args) {\n  console.log(req.id, args);\n}\n\napp.use(express.json());\napp.use(express.urlencoded({ extended: false }));\n\napp.use((req, res, next) =&gt; {\n  req.id = uuid();\n  requestLogger(req, \"request started\");\n  next();\n});\n\napp.use(\"\/\", indexRouter);\n\napp.use((req, res, next) =&gt; {\n  requestLogger(req, \"request ended\");\n  next();\n});\n\nmodule.exports = app;<\/code><\/pre>\n\n\n\n<p>Let\u2019s take a look at the requestLogger function: the first parameter includes a request object, while the second one is the message that shall be logged. By looking at this piece of code, it is easy to identify the problem &#8211; it is needed to pass the \u201creq\u201d variable (lets call it the request context) to the logger. This kind of a pattern has been known in the Node.js community for years, but obviously that does not mean it should be the standard. It\u2019s worth pointing out that it&#8217;s a relatively simple example &#8211; oftentimes you may need to log for details of SQL query or details of cloud-related operations (for example by uploading to AWS S3). The situation can get complex really fast and it\u2019s hard to code just one logging method for each use-case. But the solution is on the horizon.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-asynclocalstorage-in-node-js-to-the-rescue\">AsyncLocalStorage in Node.js to the rescue!<\/h2>\n\n\n\n<p><strong>AsyncLocalStorage<\/strong> is a class which creates an asynchronous state within callbacks and promise chains. It allows us to persist context through a lifetime of async operations, for example within a web request, RabbitMQ event or WebSocket message.<\/p>\n\n\n\n<p id=\"h-before-i-start-explaining-how-to-do-it-make-sure-you-are-running-node-js-in-versions-12-17-0-or-13-10-0-at-least-14-supports-asynclocalstorage-by-default\"><strong>Before I start explaining how to do it &#8211; make sure you are running Node.js in versions 12.17.0 or 13.10.0 at least (14+ supports AsyncLocalStorage by default).<\/strong><\/p>\n\n\n\n<p>Let\u2019s try to refactor the previous example so it uses this new feature. Also, to show <strong>the power of AsyncLocalStorage in Node.js<\/strong>, we will make our logger inform us about the path of request and time delta between the request start and log call.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require(\"express\");\n\nconst { AsyncLocalStorage } = require(\"async_hooks\");\nconst { v4: uuid } = require(\"uuid\");\n\nconst indexRouter = require(\".\/routes\/index\");\n\nconst app = express();\nconst context = new AsyncLocalStorage();\n\nfunction requestLogger(...args) {\n  const store = context.getStore();\n  const id = store.get(\"id\");\n  const timeStart = store.get(\"timeStart\");\n  const { originalUrl } = store.get(\"request\");\n  console.log(`${id}, ${originalUrl}, ${+new Date() - timeStart}ms`, args);\n}\n\napp.use(express.json());\napp.use(express.urlencoded({ extended: false }));\n\napp.use((req, res, next) =&gt; {\n  const store = new Map();\n  context.run(store, () =&gt; {\n    store.set(\"id\", uuid());\n    store.set(\"timeStart\", +new Date());\n    store.set(\"request\", req);\n    requestLogger(\"request started\");\n    next();\n  });\n});\n\napp.use(\"\/\", indexRouter);\n\napp.use((req, res, next) =&gt; {\n  requestLogger(\"request ended\");\n  next();\n});\n\nmodule.exports = app;<\/code><\/pre>\n\n\n\n<p>First, it\u2019s necessary to import and create the AsyncLocalStorage context. Then let\u2019s take a look at our middleware on line 22 &#8211; first Map is created. It\u2019s going to keep our context. This way we can store more than one variable inside our context with flexible data structure. By calling context.run with our store as an argument, a shared context instance is being created. Inside the callback, we supply the store with needed details about our context &#8211; here request ID is being created, request object saved and the timestamp of invocation is saved.&nbsp;<\/p>\n\n\n\n<p>Now, let\u2019s move back to the requestLogger function. First of all, we can remove all context-related arguments. Later, we have to grab our store from the AsyncLocalStorage instance. The latter is just a simple implementation of the business logic. As you can see, the solution is robust and easy to read. Moreover, we can store as many context-related details as we want.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-versatility-of-asynclocalstorage-in-node-js\">The versatility of AsyncLocalStorage in Node.js <\/h2>\n\n\n\n<p>Example shown in this article is really easy &#8211; but this is just an explanation. You can easily implement sophisticated monitoring tools, loggers with lots\u2019 of features, much better error handling, single SQL transaction per HTTP request and more.&nbsp;<\/p>\n\n\n\n<p>But there are also some tips you have to remember about:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/codeandpepper.com\/google-lighthouse-tool-guide\/\"><strong>Due to performance<\/strong><\/a>, you shouldn\u2019t really create more than 10-15 <em>AsyncLocalStorages<\/em>. Also, library creators shouldn\u2019t really use it.<\/li><li>If you are not really sure whether data will be cleared via GarbageCollector, use the context.exit() method.<\/li><li>Remember about the limitations of async\/await &#8211; asynchronous operations which take less than 2ms shouldn\u2019t really we wrapped with Promises.<\/li><\/ul>\n\n\n\n<p>With these in mind I hope that you can benefit from this new language feature and clean up your code a little bit!<\/p>\n\n\n\n<p><em>Based on Node.js documentation and \u201cRequest context tracking (AsyncLocalStorage use cases and best practices)\u201c talk by <a href=\"https:\/\/www.youtube.com\/watch?v=c7ic3TtBtb0\" rel=\"nofollow\"><strong>Vladimir de Turckheim<\/strong><\/a>, Lead Node.js Engineer @ Sqreen.<\/em><\/p>\n\n\n\n<p>If you find this interesting, be sure to check out other posts on our blog, where we cover topics such as <a href=\"https:\/\/codeandpepper.com\/service-workers-in-progressive-web-apps\/\"><strong>service workers in progressive web apps<\/strong><\/a> and break down the details of a <a href=\"https:\/\/codeandpepper.com\/software-development-process\/\"><strong>solid software development process!<\/strong><\/a><\/p>\n\n\n\n\n\n<section id=\"contact\" class=\"contact-block block common-block alignfull\">\n  <div class=\"container\">\n\n\n    \n  <svg class=\"wave\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"280\" height=\"9\" viewBox=\"0 0 280 9\">\n    <path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M0 3.6c2.88 0 4.18-.668 5.824-1.515C7.724 1.108 9.879 0 13.998 0c4.12 0 6.274 1.108 8.175 2.085 1.644.847 2.943 1.515 5.823 1.515 2.88 0 4.179-.668 5.824-1.515C35.72 1.108 37.874 0 41.995 0c4.12 0 6.274 1.108 8.174 2.085 1.645.847 2.945 1.515 5.824 1.515 2.88 0 4.18-.668 5.826-1.515C63.719 1.108 65.873 0 69.993 0c4.12 0 6.274 1.108 8.174 2.085 1.645.847 2.945 1.515 5.823 1.515 2.88 0 4.18-.668 5.825-1.515C91.715 1.108 93.87 0 97.99 0c4.12 0 6.273 1.108 8.174 2.085 1.645.847 2.945 1.515 5.823 1.515 2.88 0 4.178-.668 5.824-1.515 1.9-.977 4.054-2.085 8.173-2.085 4.12 0 6.273 1.108 8.174 2.085 1.646.847 2.945 1.515 5.825 1.515 2.88 0 4.18-.668 5.826-1.515 1.9-.977 4.055-2.085 8.175-2.085 4.12 0 6.273 1.108 8.174 2.085 1.646.847 2.945 1.515 5.825 1.515 2.88 0 4.179-.668 5.824-1.515 1.9-.977 4.054-2.085 8.175-2.085 4.12 0 6.274 1.108 8.175 2.085 1.646.847 2.946 1.515 5.826 1.515 2.88 0 4.18-.668 5.826-1.515 1.9-.977 4.054-2.085 8.175-2.085 4.12 0 6.273 1.108 8.174 2.085 1.646.847 2.945 1.515 5.825 1.515 2.881 0 4.18-.668 5.827-1.515 1.9-.977 4.056-2.085 8.176-2.085 4.121 0 6.276 1.108 8.177 2.085 1.646.847 2.946 1.515 5.827 1.515s4.181-.668 5.828-1.515C259.718 1.108 261.873 0 265.995 0c4.121 0 6.275 1.108 8.177 2.084 1.645.848 2.946 1.516 5.828 1.516V9h-.007l-5.252-.793c-1.129-.382-2.056-.848-2.919-1.291-1.646-.847-2.946-1.516-5.827-1.516-2.882 0-4.183.669-5.829 1.516-1.9.977-4.056 2.084-8.177 2.084-4.12 0-6.275-1.107-8.176-2.084-1.647-.847-2.947-1.516-5.828-1.516-2.88 0-4.18.669-5.827 1.516-1.9.977-4.055 2.084-8.176 2.084-4.12 0-6.273-1.107-8.175-2.084-1.645-.847-2.944-1.516-5.824-1.516s-4.18.669-5.826 1.516c-1.9.977-4.055 2.084-8.175 2.084-4.12 0-6.275-1.107-8.176-2.084-1.644-.847-2.945-1.516-5.825-1.516-2.88 0-4.18.669-5.825 1.516-1.9.977-4.054 2.084-8.174 2.084-4.12 0-6.274-1.107-8.176-2.084-1.644-.847-2.943-1.516-5.823-1.516-2.88 0-4.18.669-5.826 1.516-1.9.977-4.054 2.084-8.175 2.084-4.12 0-6.274-1.107-8.174-2.084-1.646-.847-2.946-1.516-5.825-1.516s-4.179.669-5.824 1.516c-1.9.977-4.053 2.084-8.173 2.084s-6.273-1.107-8.173-2.084c-1.645-.847-2.945-1.516-5.824-1.516-2.88 0-4.179.669-5.824 1.516C90.265 7.893 88.11 9 83.99 9c-4.12 0-6.273-1.107-8.173-2.084-1.645-.847-2.944-1.516-5.824-1.516s-4.18.669-5.825 1.516C62.268 7.893 60.113 9 55.993 9c-4.12 0-6.274-1.107-8.174-2.084-1.645-.847-2.945-1.516-5.824-1.516-2.88 0-4.18.669-5.825 1.516C34.27 7.893 32.116 9 27.996 9c-4.12 0-6.273-1.107-8.174-2.084-1.645-.847-2.945-1.516-5.824-1.516s-4.179.669-5.824 1.516C7.311 7.359 1.127 8.618 0 9\"\/>\n<\/svg>\n\n<p class=\"block-title section-title\">\n  We have Senior React &#038; Node engineers <br class=\"desktop-only\">available at the moment.<\/p>\n\n\n  <div class=\"block-description typography-body\">\n    <p>Want to have them working for you? <br class=\"desktop-only\"> Leave your contact details and I\u2019ll get to you back right away.<\/p>\n  <\/div>\n\n    \n          <div class=\"contact-block-person\">\n        <img loading=\"lazy\" decoding=\"async\" width=\"90\" height=\"90\" src=\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-90x90.png\" class=\"contact-block-person-image\" alt=\"\" srcset=\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-90x90.png 90w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-150x150.png 150w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-140x140.png 140w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-160x160.png 160w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6-136x136.png 136w, https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/09\/Olga_Pogorzelska_online-6.png 200w\" sizes=\"auto, (max-width: 90px) 100vw, 90px\" \/>        <div class=\"contact-block-person-text\">\n          <div class=\"typography-title-m\">\n            Olga Pogorzelska          <\/div>\n          <div class=\"typography-body-medium\">\n            New Business          <\/div>\n        <\/div>\n      <\/div>\n    \n\n    <form class=\"contact-form\" method=\"POST\" action=\"https:\/\/codeandpepper.com\/wp-admin\/admin-ajax.php\">\n            <amp-recaptcha-input layout=\"nodisplay\" name=\"recaptcha_token\" data-sitekey=\"6LeEo8cqAAAAABpahzrYQeEsO-xoutAjoIkrKpTB\" data-action=\"contact_block\"><\/amp-recaptcha-input>\n            <input type=\"hidden\" name=\"action\" value=\"contact_block_submit\" \/>\n      <input type=\"hidden\" name=\"block\" value=\"smallContactForm\" \/>\n      <input id=\"contact-email\" type=\"email\" name=\"email\" placeholder=\"Email\" class=\"gtm_form_input\" required>\n      <label for=\"contact-email\" class=\"contact-block-hidden-label\">Email<\/label>\n      <input id=\"contact-name\" type=\"text\" name=\"name\" placeholder=\"Full name\" class=\"gtm_form_input\" required>\n      <label for=\"contact-name\" class=\"contact-block-hidden-label\">\n        Full name      <\/label>\n\n      <input type=\"submit\" name=\"submit\" value=\"Contact me\" class=\"gtm_form_submit btn-big\">\n\n      <div submitting>\n      <\/div>\n      <div id=\"TYPSmallForm\" class=\"submit-msg submit-success\" submit-success>\n        <template type=\"amp-mustache\">\n          <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 26 26\">\n    <g fill=\"none\" fill-rule=\"evenodd\">\n        <g stroke=\"#FFF\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" transform=\"translate(1 1)\">\n            <path d=\"M17 8.5l-7.5 7L7 13\"\/>\n            <circle cx=\"12\" cy=\"12\" r=\"11.5\"\/>\n        <\/g>\n        <path d=\"M1 1h24v24H1z\"\/>\n    <\/g>\n<\/svg>\n          Your message has been sent. We will get back to you as soon as possible.\n        <\/template>\n      <\/div>\n      <div id=\"ErrorSmallForm\" class=\"submit-msg submit-error\" submit-error>\n        <template type=\"amp-mustache\">\n          <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"25\" height=\"25\" viewBox=\"0 0 25 25\">\n    <g fill=\"none\" fill-rule=\"evenodd\">\n        <g stroke=\"currentColor\" stroke-linejoin=\"round\">\n            <path stroke-linecap=\"round\" stroke-width=\"2\" d=\"M23.498 12.31c.105 6.075-4.923 11.086-10.998 11.192-6.074.104-10.893-4.734-10.998-10.81C1.396 6.619 6.426 1.606 12.5 1.502c6.074-.106 10.893 4.734 10.998 10.808zM12.5 14V7\"\/>\n            <path fill=\"currentColor\" stroke-width=\"1.5\" d=\"M13 17.5a.5.5 0 0 1-1 0 .5.5 0 0 1 1 0z\"\/>\n        <\/g>\n        <path d=\"M1 0h24v24H1z\"\/>\n    <\/g>\n<\/svg>\n          Oops! Something went wrong. Please try again later.\n        <\/template>\n      <\/div>\n    <\/form>\n\n\n  <\/div>\n<\/section>\n<style type=\"text\/css\">\n  #contact {\n    background: #007bb3;\n    color: #FFFFFF;\n  }\n\n  #contactsvg {\n    color: #ffffff;\n  }\n<\/style>","protected":false},"excerpt":{"rendered":"<p>Node.js is one of the most popular programming languages used on the web nowadays. It\u2019s single core design has lots of positives, but sometimes can be a little challenging &#8211; especially when it comes to passing the context between asynchronous invocations. It seems not to be such a problem anymore, though. Developers can use AsyncLocalStorage<a class=\"moretag\" href=\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\"> Read the full article&#8230;<\/a><\/p>\n","protected":false},"author":20417,"featured_media":22845,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1647],"tags":[1749,173],"class_list":["post-22826","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development","tag-node-js","tag-software-development-process"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper<\/title>\n<meta name=\"description\" content=\"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code &amp; Pepper team explains how!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper\" \/>\n<meta property=\"og:description\" content=\"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code &amp; Pepper team explains how!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Code &amp; Pepper\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/codeandpepper\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-04T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-10-11T14:17:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"864\" \/>\n\t<meta property=\"og:image:height\" content=\"450\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Piotr Moszkowicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@codeandpepper\" \/>\n<meta name=\"twitter:site\" content=\"@codeandpepper\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Piotr Moszkowicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\"},\"author\":{\"name\":\"Piotr Moszkowicz\",\"@id\":\"https:\/\/codeandpepper.com\/#\/schema\/person\/67d5307274f0bb28bbf08bd331215f8a\"},\"headline\":\"Simple Context Passing With AsyncLocalStorage in Node.js\",\"datePublished\":\"2021-03-04T08:00:00+00:00\",\"dateModified\":\"2023-10-11T14:17:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\"},\"wordCount\":753,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/codeandpepper.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\",\"keywords\":[\"Node.js\",\"Software development process\"],\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\",\"url\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\",\"name\":\"Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper\",\"isPartOf\":{\"@id\":\"https:\/\/codeandpepper.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\",\"datePublished\":\"2021-03-04T08:00:00+00:00\",\"dateModified\":\"2023-10-11T14:17:19+00:00\",\"description\":\"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code & Pepper team explains how!\",\"breadcrumb\":{\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage\",\"url\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\",\"contentUrl\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg\",\"width\":864,\"height\":450,\"caption\":\"Context Passing With AsyncLocalStorage in Node.js\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/codeandpepper.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Simple Context Passing With AsyncLocalStorage in Node.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/codeandpepper.com\/#website\",\"url\":\"https:\/\/codeandpepper.com\/\",\"name\":\"Code & Pepper\",\"description\":\"FinTech Developers\",\"publisher\":{\"@id\":\"https:\/\/codeandpepper.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/codeandpepper.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/codeandpepper.com\/#organization\",\"name\":\"Code & Pepper\",\"url\":\"https:\/\/codeandpepper.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codeandpepper.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/06\/logo.png\",\"contentUrl\":\"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/06\/logo.png\",\"width\":319,\"height\":144,\"caption\":\"Code & Pepper\"},\"image\":{\"@id\":\"https:\/\/codeandpepper.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/codeandpepper\/\",\"https:\/\/x.com\/codeandpepper\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/codeandpepper.com\/#\/schema\/person\/67d5307274f0bb28bbf08bd331215f8a\",\"name\":\"Piotr Moszkowicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codeandpepper.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/22c3001bb6c952ae63844021b0de8c19044c26bfa86a493ad20bf88ba2ed1712?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/22c3001bb6c952ae63844021b0de8c19044c26bfa86a493ad20bf88ba2ed1712?s=96&d=mm&r=g\",\"caption\":\"Piotr Moszkowicz\"},\"description\":\"Senior TypeScript FullStack Developer at Code &amp; Pepper. A co-host of the \u201cKernel\u201d Academic Circle at the AGH University of Science and Technology. During his studies, he created software for CERN and in his free time, he plays the piano and collects ASG replica guns.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/piotr-moszkowicz-2608ab146\"],\"url\":\"https:\/\/codeandpepper.com\/author\/p-moszkowicz\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper","description":"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code & Pepper team explains how!","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:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/","og_locale":"en_US","og_type":"article","og_title":"Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper","og_description":"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code & Pepper team explains how!","og_url":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/","og_site_name":"Code &amp; Pepper","article_publisher":"https:\/\/www.facebook.com\/codeandpepper\/","article_published_time":"2021-03-04T08:00:00+00:00","article_modified_time":"2023-10-11T14:17:19+00:00","og_image":[{"width":864,"height":450,"url":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg","type":"image\/jpeg"}],"author":"Piotr Moszkowicz","twitter_card":"summary_large_image","twitter_creator":"@codeandpepper","twitter_site":"@codeandpepper","twitter_misc":{"Written by":"Piotr Moszkowicz","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#article","isPartOf":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/"},"author":{"name":"Piotr Moszkowicz","@id":"https:\/\/codeandpepper.com\/#\/schema\/person\/67d5307274f0bb28bbf08bd331215f8a"},"headline":"Simple Context Passing With AsyncLocalStorage in Node.js","datePublished":"2021-03-04T08:00:00+00:00","dateModified":"2023-10-11T14:17:19+00:00","mainEntityOfPage":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/"},"wordCount":753,"commentCount":0,"publisher":{"@id":"https:\/\/codeandpepper.com\/#organization"},"image":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage"},"thumbnailUrl":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg","keywords":["Node.js","Software development process"],"articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/","url":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/","name":"Context Passing with AsyncLocalStorage in Node.js | Code &amp; Pepper","isPartOf":{"@id":"https:\/\/codeandpepper.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage"},"image":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage"},"thumbnailUrl":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg","datePublished":"2021-03-04T08:00:00+00:00","dateModified":"2023-10-11T14:17:19+00:00","description":"AsyncLocalStorage in Node.js can solve problems have been encountering for years. Piotr Moszkowicz from the Code & Pepper team explains how!","breadcrumb":{"@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#primaryimage","url":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg","contentUrl":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2021\/03\/Simple-Context-Passing-With-AsyncLocalStorage-in-Node-js.jpg","width":864,"height":450,"caption":"Context Passing With AsyncLocalStorage in Node.js"},{"@type":"BreadcrumbList","@id":"https:\/\/codeandpepper.com\/asynclocalstorage-in-node-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/codeandpepper.com\/"},{"@type":"ListItem","position":2,"name":"Simple Context Passing With AsyncLocalStorage in Node.js"}]},{"@type":"WebSite","@id":"https:\/\/codeandpepper.com\/#website","url":"https:\/\/codeandpepper.com\/","name":"Code & Pepper","description":"FinTech Developers","publisher":{"@id":"https:\/\/codeandpepper.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/codeandpepper.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/codeandpepper.com\/#organization","name":"Code & Pepper","url":"https:\/\/codeandpepper.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codeandpepper.com\/#\/schema\/logo\/image\/","url":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/06\/logo.png","contentUrl":"https:\/\/codeandpepper.com\/wp-content\/uploads\/2019\/06\/logo.png","width":319,"height":144,"caption":"Code & Pepper"},"image":{"@id":"https:\/\/codeandpepper.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/codeandpepper\/","https:\/\/x.com\/codeandpepper"]},{"@type":"Person","@id":"https:\/\/codeandpepper.com\/#\/schema\/person\/67d5307274f0bb28bbf08bd331215f8a","name":"Piotr Moszkowicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codeandpepper.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/22c3001bb6c952ae63844021b0de8c19044c26bfa86a493ad20bf88ba2ed1712?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/22c3001bb6c952ae63844021b0de8c19044c26bfa86a493ad20bf88ba2ed1712?s=96&d=mm&r=g","caption":"Piotr Moszkowicz"},"description":"Senior TypeScript FullStack Developer at Code &amp; Pepper. A co-host of the \u201cKernel\u201d Academic Circle at the AGH University of Science and Technology. During his studies, he created software for CERN and in his free time, he plays the piano and collects ASG replica guns.","sameAs":["https:\/\/www.linkedin.com\/in\/piotr-moszkowicz-2608ab146"],"url":"https:\/\/codeandpepper.com\/author\/p-moszkowicz\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/posts\/22826","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/users\/20417"}],"replies":[{"embeddable":true,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/comments?post=22826"}],"version-history":[{"count":33,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/posts\/22826\/revisions"}],"predecessor-version":[{"id":50979,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/posts\/22826\/revisions\/50979"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/media\/22845"}],"wp:attachment":[{"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/media?parent=22826"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/categories?post=22826"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeandpepper.com\/wp-json\/wp\/v2\/tags?post=22826"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}