{"id":822,"date":"2026-01-30T09:55:29","date_gmt":"2026-01-30T09:55:29","guid":{"rendered":"https:\/\/productive.io\/engineering\/?p=822"},"modified":"2026-01-30T09:55:29","modified_gmt":"2026-01-30T09:55:29","slug":"a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day","status":"publish","type":"post","link":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/","title":{"rendered":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day"},"content":{"rendered":"<p   > <a href='https:\/\/productive.io\/engineering\/category\/backend\/'>Backend<\/a><\/p> &#8211; <p   > {{minutes}} min read<\/p> <h1   > A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day<\/h1> <a href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/2024\/02\/profi-e1708437204597.jpeg\"  alt=\"\" loading=lazy \/> <\/a> <a href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"> <p   > Nikola Buhini\u010dek<\/p><\/a> Backend Tech Lead at Productive. Pretty passionate about working on one product and taking part in decision-making. When I\u2019m not coding, you\u2019ll probably find me chilling with my friends and family.<p   > January 30, 2026<\/p> <a aria-hidden=\"false\"   href=https:\/\/www.facebook.com\/sharer.php?u=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/twitter.com\/intent\/tweet?text=A%20Close%20Call%20with%20Real-Time%3A%20How%20Rethinking%20Pub-Sub%20Saved%20the%20Day&amp;url=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/www.linkedin.com\/shareArticle?mini=true&amp;url=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\"  alt=\"\" loading=lazy \/> <p   > Sometimes the easy way is not the most obvious way. And this was <strong>one of those times. <\/strong><\/p> <p   > All of this started while I was working on our new feature &#8211;\u00a0<strong>Automations<\/strong>\u00a0\ud83e\udd16. In a nutshell, Automations allow customers to set up actions triggered under specific conditions. Some of the currently implemented actions are sending slack messages, creating and updating tasks, or posting comments on objects.<br><br>I wanted that actions that modify tasks and comments would send a message over our real-time system so that our frontend clients (browser, mobile, desktop app) could pick that up and show those changes as they occur.<br><br>Currently, our app\u2019s real-time updates are tied to POST\/PATCH\/DELETE requests. We have a controller extension\u00a0 <code>Extensions::Broadcastable<\/code>\u00a0that hooks on\u00a0<code>save_form<\/code>\u00a0and\u00a0<code>destroy_resource<\/code>\u00a0methods and sends a real-time event if the action was successful. However, this approach wasn&#8217;t suitable for my automation actions, as they don&#8217;t go through controllers.<\/p> <p   > As I was digging into this topic, I somehow changed the scope of my task from making the automations actions \u201clive\u201d to revamping our whole broadcasting architecture. I wanted to move that logic out of controllers to a place where I could catch all the changes &#8211; which would also catch the automations actions.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-17-at-13.00.38.png\"  alt=\"\" loading=lazy \/> <h2   > <strong>Exploring Different Approaches<\/strong><\/h2> <h3   > <strong>1. Callbacks<\/strong><\/h3> <p   > Yeah&#8230; although we all know callbacks are a hassle, I couldn\u2019t NOT think about them, just for a moment&#8230;<\/p> <h3   > <strong>2. Forms instead of Controllers<\/strong><\/h3> <p   > Both the controller actions and my automation actions use the same forms to handle our data. So, why wouldn&#8217;t I hook on forms and send my real-time messages from there?<br><br>This approach was bugging me a bit as we don&#8217;t use Form objects in all the places we are actually changing our data. So this wouldn&#8217;t make the whole app feel &#8220;live&#8221; but I would cover more places than what we have currently. That sounded promising to me.<br><br>Wanted to pitch my thoughts to the rest of the Core team and that discussion turned on a lightbulb above my head.<\/p> <h3   > <strong>3. Embracing Pub\/Sub<\/strong><\/h3> <p   > That was exactly what I was looking for.<br><br>Publishing events happens for every change. Of course, except the places we are using methods that skip callbacks (update_column, update_all, &#8230;) as Pub\/Sub and the aspect of publishing changes essentially is hooked to callbacks &#8211; but that\u2019s a story for another day.<\/p> <h2   > <strong>Making a PoC<\/strong><\/h2> <p   > As things go with every big change in our codebase, and generally in our product, I was putting this code behind a <a href=\"https:\/\/dev.to\/productive\/decoupling-deployment-from-release-with-feature-toggles-7lo\" target=\"_blank\" rel=\"noreferrer noopener\">Feature Flag (FF)<\/a>.<br><br>Putting it simply, when one would have the <code>pubSubBroadcasting<\/code> FF enabled I would skip sending the real-time events from the controller actions and I would handle the published events accordingly. If you didn&#8217;t have that FF, nothing would have changed.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-15-at-12.16.04.png\"  alt=\"\" loading=lazy \/> <p   > I made a few Subscribers that would listen for all the <strong>task and comment related changes<\/strong> and simply handle them as sending a real-time event.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-15-at-12.16.13.png\"  alt=\"\" loading=lazy \/> <p   > And of course, I added RSpec tests and set up some widgets on New Relic to cover the difference in number of events that we are sending now &#8211; as we knew we would be sending more events now.<br><br>Basically that was it. The next step was to slowly propagate this FF over all organizations, check our New Relic metrics and see if anything breaks. Once we release the change to the entirety of our user base, we should cover the remaining objects and make subscribers for their Pub\/Sub events too.<\/p> <h2   > <strong>Showing it off<\/strong><\/h2> <p   > As I was pretty proud of this solution, I kinda talked about it a lot and naturally it popped up in a 1on1 meeting with my Engineering Manager. He wanted to discuss it a bit more so I told him the same thing I wrote here: <em>&#8220;Isn&#8217;t that great? Our APP will be LIVE, all the data would be in sync.&#8221;<\/em><br><br>His response was &#8220;But do we really want that?&#8221;.<br><br>That wasn&#8217;t the response that I was looking for\u2026<br><br>What I didn&#8217;t know was that our frontend client, once it gets socket messages, depending on the screen the user is, has to make additional API calls so that all the required data could be fetched again. So, a great deal of my real-time events actually end up generating additional requests to our server and in a way, we are just generating a lot more traffic (self DDoSing?). As I didn&#8217;t know about this, I wasn&#8217;t even paying attention to those metrics along the way.<\/p> <h2   > <strong>One step forward, two steps back<\/strong><\/h2> <p   > We decided to get better data so that we could make a better call for this situation.<br><br>I took a time frame of one week from our logs and checked the number of the POST\/PATCH\/DELETE requests versus the number of dispatched publish events. This, in the end, would roughly be the same number as the events we are sending over the socket in the current and in the new way.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-15-at-12.16.28.png\"  alt=\"\" loading=lazy \/> <p   > I wasn&#8217;t really aware of how badly this could end. I was making a PoC out of this for <strong>tasks<\/strong> and <strong>comments<\/strong> and you can see here that there wasn&#8217;t such a big difference. 25% more events was okay, I knew it would be more.<br><br>But look at our <strong>deals<\/strong> endpoint for example &#8211; 55 times more events would be sent. That would add up to the traffic we sent over sockets, to our infrastructure bill for that services, and I don&#8217;t want to imagine the number of API calls generated as a result of this &#8211; by ourselves&#8230;<\/p> <p   > &#8220;Deals have that much traffic because a lot of other objects update financial data on deals so that was understandable too, it immediately came to us&#8230;&#8221;<\/p> <h2   > <strong>Back to the drawing board<\/strong><\/h2> <h3   > <strong>1.<\/strong> <strong>Pub\/Sub shouldn&#8217;t be a bad call for this<\/strong><\/h3> <p   > As this is the part of our code that gets all the changes in our data, when wanting to make a frontend client to be as live as it gets, this should be a good call. The solution would be not sending all the changes over sockets but filter them by relevant and not relevant. This way we would surely see a drop of those insane <strong>company<\/strong> and <strong>deal<\/strong> numbers.<\/p> <h3   > <strong>2.<\/strong> <strong>Send all the needed data to front?<\/strong><\/h3> <p   > As mentioned before, each real-time message already contains the object that was changed. The issue here is that there are a lot of screens in our client and we can&#8217;t know all the contexts our users are in and what additional data should be sent &#8211; which is exactly why our client makes API calls when receiving some socket messages.<\/p> <h3   > <strong>3.<\/strong> <strong>Why didn&#8217;t I just resolve the problem I had<\/strong>?<\/h3> <p   > To make those actions &#8220;live&#8221; in our frontend clients (browser, mobile, desktop APP), I wanted to plug them into our real-time system. So, why didn&#8217;t I just put a bit of explicit calls to the code of my automations actions where I would just call the class that sends the real-time message. But no, I wanted to act smart and fix a problem that wasn&#8217;t really there in the first place &#8211; to make everything more live <em>while no one was asking for it<\/em>.<\/p> <h2   > <strong>The Aftermath<\/strong><\/h2> <p   > So yeah, the Pub\/Sub usage in our real-time part of the app is on hold until we leverage things up.<br><br>I went on with the <strong>3rd solution<\/strong> and added 5 lines of code &#8211; a call to the Broadcaster class is one line and I have 5 events over 4 classes to send&#8230;<br>This was a nice learning opportunity for me and I would say that:<\/p> <ul   > <li>When having concrete problems, stick to handling them and resolve them first<\/li><li>I had the data the whole time in New Relic, I should&#8217;ve prepare better<\/li><li>It&#8217;s not bad to be explicit in code, not everything should be an abstraction, generalization, metaprogramming, &#8230; <em>Hope to write on this point a bit more soon<\/em><\/li><\/ul> <p   > The good thing is that we didn&#8217;t actually do any damage with this and we didn&#8217;t lose a lot of time during this \u201clearning opportunity\u201d.<br><br>Anyone faced similar problems? If yes, how did you deal with them? Feel free to reach out to me!<\/p> <a aria-hidden=\"false\"   href=https:\/\/www.facebook.com\/sharer.php?u=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/twitter.com\/intent\/tweet?text=A%20Close%20Call%20with%20Real-Time%3A%20How%20Rethinking%20Pub-Sub%20Saved%20the%20Day&amp;url=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/www.linkedin.com\/shareArticle?mini=true&amp;url=https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day target=_blank rel=\"noopener noreferrer\" > <\/a> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/2024\/02\/profi-e1708437204597.jpeg\"  alt=\"\" loading=lazy \/> <p   > Nikola Buhini\u010dek<\/p> Backend Tech Lead at Productive. Pretty passionate about working on one product and taking part in decision-making. When I\u2019m not coding, you\u2019ll probably find me chilling with my friends and family.<a   href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\" > More From This Author <\/a> <h2   > Related articles<\/h2> <a href=\"https:\/\/productive.io\/engineering\/testing-the-test\/\"   > <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2022\/11\/BP_format-768x322.png\"  alt=\"\" loading=lazy \/> <p   > Engineering \u2022 Testing<\/p> <h2   > Testing the Test<\/h2> <\/a><a href=\"https:\/\/productive.io\/engineering\/custom-fields-give-your-customers-the-fields-they-need\/\"   > <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2022\/11\/Asset_11-768x322.png\"  alt=\"\" loading=lazy \/> <p   > Backend \u2022 Engineering<\/p> <h2   > Custom Fields: Give Your Customers the Fields They Need<\/h2> <\/a> <h2   > Related jobs<\/h2> <a href=\"https:\/\/productive.io\/careers\/open-job-application\/\"  > <p  > Open Job Application<\/p><p  > <\/p> <\/a>","protected":false},"excerpt":{"rendered":"Sometimes the easy way is not the most obvious way. And this was one of those times. ","protected":false},"author":40,"featured_media":926,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"es_utils_meta_schema":"","footnotes":""},"categories":[11,13],"tags":[],"class_list":["post-822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backend","category-testing"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day - Building Productive<\/title>\n<meta name=\"description\" content=\"Sometimes the easy way is not the most obvious way. And this was one of those times.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day\" \/>\n<meta property=\"og:description\" content=\"Sometimes the easy way is not the most obvious way. And this was one of those times.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\" \/>\n<meta property=\"og:site_name\" content=\"Building Productive\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-30T09:55:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1901\" \/>\n\t<meta property=\"og:image:height\" content=\"797\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Nikola Buhini\u010dek\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nikola Buhini\u010dek\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\"},\"author\":{\"name\":\"Nikola Buhini\u010dek\",\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\"},\"headline\":\"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day\",\"datePublished\":\"2026-01-30T09:55:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\"},\"wordCount\":11,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\",\"articleSection\":[\"Backend\",\"Testing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\",\"url\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\",\"name\":\"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day - Building Productive\",\"isPartOf\":{\"@id\":\"https:\/\/productive.io\/engineering\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\",\"datePublished\":\"2026-01-30T09:55:29+00:00\",\"author\":{\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\"},\"description\":\"Sometimes the easy way is not the most obvious way. And this was one of those times.\",\"breadcrumb\":{\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage\",\"url\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\",\"contentUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png\",\"width\":1901,\"height\":797},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/productive.io\/engineering\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/productive.io\/engineering\/#website\",\"url\":\"https:\/\/productive.io\/engineering\/\",\"name\":\"Building Productive\",\"description\":\"Just another Productive Sites site\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/productive.io\/engineering\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\",\"name\":\"Nikola Buhini\u010dek\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"caption\":\"Nikola Buhini\u010dek\"},\"url\":\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day - Building Productive","description":"Sometimes the easy way is not the most obvious way. And this was one of those times.","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:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/","og_locale":"en_US","og_type":"article","og_title":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day","og_description":"Sometimes the easy way is not the most obvious way. And this was one of those times.","og_url":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/","og_site_name":"Building Productive","article_published_time":"2026-01-30T09:55:29+00:00","og_image":[{"width":1901,"height":797,"url":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","type":"image\/png"}],"author":"Nikola Buhini\u010dek","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nikola Buhini\u010dek","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#article","isPartOf":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/"},"author":{"name":"Nikola Buhini\u010dek","@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29"},"headline":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day","datePublished":"2026-01-30T09:55:29+00:00","mainEntityOfPage":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/"},"wordCount":11,"commentCount":0,"image":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage"},"thumbnailUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","articleSection":["Backend","Testing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/","url":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/","name":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day - Building Productive","isPartOf":{"@id":"https:\/\/productive.io\/engineering\/#website"},"primaryImageOfPage":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage"},"image":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage"},"thumbnailUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","datePublished":"2026-01-30T09:55:29+00:00","author":{"@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29"},"description":"Sometimes the easy way is not the most obvious way. And this was one of those times.","breadcrumb":{"@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#primaryimage","url":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","contentUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","width":1901,"height":797},{"@type":"BreadcrumbList","@id":"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/productive.io\/engineering\/"},{"@type":"ListItem","position":2,"name":"A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day"}]},{"@type":"WebSite","@id":"https:\/\/productive.io\/engineering\/#website","url":"https:\/\/productive.io\/engineering\/","name":"Building Productive","description":"Just another Productive Sites site","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/productive.io\/engineering\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29","name":"Nikola Buhini\u010dek","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","caption":"Nikola Buhini\u010dek"},"url":"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/"}]}},"featured_image":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x.png","category":"Backend","_links":{"self":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/comments?post=822"}],"version-history":[{"count":10,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/822\/revisions"}],"predecessor-version":[{"id":927,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/822\/revisions\/927"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/media\/926"}],"wp:attachment":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/media?parent=822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/categories?post=822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/tags?post=822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}