{"id":7255,"date":"2015-03-11T16:00:50","date_gmt":"2015-03-11T16:00:50","guid":{"rendered":"http:\/\/intercom.com\/blog\/?p=7255"},"modified":"2020-07-30T13:02:23","modified_gmt":"2020-07-30T12:02:23","slug":"keeping-intercom-up","status":"publish","type":"post","link":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/","title":{"rendered":"Keeping Intercom up"},"content":{"rendered":"<p class=\"opening_paragraph\">Our goal for Intercom availability is that each of our public facing endpoints (In-App Messenger, the Intercom web application and public facing APIs) have greater than 99.9% availability &#8211; this means being down for no more than 45 minutes a month.<\/p>\n<p>This is the second of our regular <a href=\"https:\/\/www.intercom.com\/blog\/its-not-personal-when-its-broken\/\">posts<\/a> where we provide an update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve the availability and performance of Intercom. Reminder &#8211; you can get real-time updates and data on our performance from our <a href=\"httpa:\/\/status.intercom.com\/\">status page<\/a>.<\/p>\n<p><strong>Main architecture notes for Q4 2014:<\/strong><\/p>\n<ul>\n<li>We migrated our MongoDB cluster from a third party hosted platform to a self-managed cluster in our own AWS <a href=\"httpa:\/\/aws.amazon.com\/vpc\/\">VPC<\/a>, using <a href=\"httpa:\/\/mms.mongodb.com\">MongoDB\u2019s MMS<\/a> to assist us with building and operating the cluster. We also made changes to our MongoDB client side configuration, and both of these changes have contributed to lower latencies and error rates.<\/li>\n<li>Searches in our UI use ElasticSearch as the backend, significantly speeding up the response time and reliability of searches.<\/li>\n<li>We updated the TLS\/SSL configuration for all our endpoints. <a href=\"https:\/\/www.ssllabs.com\/ssltest\/analyze.html\">SSL Labs<\/a> rates each of our endpoints as \u201cA+\u201d.<\/li>\n<\/ul>\n<p><strong>and here\u2019s our Q4 2014 numbers:<\/strong><\/p>\n<div class=\"post_image_wrapper\"><img decoding=\"async\" src=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/intercom-availability-stats-q4.png\" alt=\"\" \/><\/div>\n<p><i>Note that the In App Messenger endpoint is also known as our Ping or JS API.<\/i><\/p>\n<p>We did not meet our goal of 99.9% availability in Q4 2014. The main two causes of us missing this goal were also the reasons for us having a rough January and February 2015 too. We\u2019ve since made significant progress and discoveries on both causes, so here they are.<\/p>\n<h2 id=\"mysql-performance-issues\"><b>MySQL performance issues<\/b><\/h2>\n<p>In late October\/early November and then in late January\/early February we experienced persistent performance issues with our main MySQL database. Intercom is mostly a monolithic Ruby on Rails application, using ActiveRecord as an ORM backed by MySQL and we use Amazon Web Services\u2019 Relational Database Service to host our MySQL database. Both the application and database have accrued some complexity over time, and we\u2019ve done a number of things to reduce this complexity &#8211; \u00a0for example, our customer\u2019s user data and events are in separate dedicated datastores, and we\u2019ve built a number of smaller services that do standalone functions. However, Intercom is growing fast, and ships frequently. The workload is both difficult to predict and growing fast. On one hand, this is what traditional RDBMs are great at &#8211; they\u2019re versatile swiss army knives capable of dealing with diverse workloads. On the other hand, they\u2019re unpredictable complex beasts that are notoriously difficult to manage.<\/p>\n<p>The nature of the MySQL performance problem was that around the busiest time of our day, \u00a0the number of active threads running would jump by a factor of 1000, throughput would plummet and the reported CPU use would jump from around 10-15% to 90% or so. Failing over the database to a read replica would get things working well again. We repeatedly looked for bad queries or spikes of requests, to no avail.<\/p>\n<p>We worked initially with AWS, and later engaged external MySQL consultants, to assess the general health of the database and assist with stabilising it. AWS disabled transparent huge pages on our RDS instance, we made a number of tweaks to MySQL tunables and how our application was using connection pools to connect to MySQL &#8211; these actions stopped the regular outages. We also started collecting a lot more low-level information about the performance our MySQL instance &#8211; though we were somewhat limited here by the nature of using a managed service.<\/p>\n<p>When the problems returned in the new year, the MySQL metrics suggested lock contention was a problem, and while looking into this we discovered a number of long-running locks and transactions. Some long-running transactions could be expected as the Ruby MRI Virtual Machine that Intercom runs on can pause and do a full Garbage Collection while a thread has a lock open on the database. However we also found some of our codebase was executing other routines and in some cases calling out to external services while transactions were held open. We reduced the number of long-running transactions along with reducing the lock-wait timeout, so that waiting for locks would quickly error out instead of piling up. These made the performance events shorter with less serious impact, and didn\u2019t require a failover to recover.<\/p>\n<p>We also discovered that a large proportion of the transactions being opened on our database were being rolled back. The volume of rollbacks were causing some additional load, and at the very least it was worth ruling out as contributing to the stability problems. The cause was related to how new types of custom data are processed on Intercom\u2019s side &#8211; each custom data field is inserted into a row in a MySQL table, however if the type of custom data couldn\u2019t be determined, our code still attempted to insert the newly discovered custom data with a null value\u2026 which then (correctly!) failed at the MySQL level due to database constraints. A simple check ensured a non-zero custom data would not attempt to be written to the database solved made rollbacks an infrequent occurrence.<\/p>\n<p>One of the problems of working in a fast changing environment is identifying what has changed. On an application, code or infrastructure level, this isn\u2019t too difficult thanks to version control and audit trails. However databases don\u2019t typically log queries, and it\u2019s hard to discover new queries or changes in the frequency of queries, and most importantly the exact origin of them. We built an SQL query fingerprinter by extending Ruby on Rails\u2019 ActiveRecord and built a simple UI to navigate the data collected and make discovering new queries and trends easy. We may consider open-sourcing this at some stage in the future, though it\u2019s a little locked into how we gather and store metrics right now.<\/p>\n<p>Ultimately what got us back to stability was reducing the overall load on the database. It was becoming clear that the problems we were experiencing probably didn\u2019t have a single trigger and that reducing load in general would help. The load on the database was and remains overwhelmingly read-heavy, and while there was some caching in the app, there was no common caching framework used throughout or consistent approach applied. Enter <a href=\"httpa:\/\/www.shopify.com\/\">Shopify<\/a>\u2019s <a href=\"https:\/\/github.com\/Shopify\/identity_cache\">IdentityCache<\/a>. This looked like a great fit for what we were doing &#8211; implementing caching across a large existing Ruby on Rails application, while not wanting to write a lot of new code and retaining full control of what uses caching. To use IdentityCache we had to make numerous changes to our ActiveRecord models and make the callers use IdentityCache\u2019s methods to lookup cached entries. The work here is not yet complete &#8211; but thanks to the SQL query fingerprinting, we\u2019ve been able to focus our efforts on the most common types of database queries.<\/p>\n<h2 id=\"being-robust-against-redis-woes\">Being robust against Redis woes<\/h2>\n<p>Redis is used as a low-latency datastore for transient data by Intercom, mostly for cached data and short-lived counters. It is a reasonably good choice of datastore for these purposes. In late December and mid-February we had two similar events which took some time to resolve, around an hour of downtime each. Both of these events were triggered by the degraded performance of a single Redis node.<\/p>\n<p>Most of the code calling Redis employed<a href=\"httpa:\/\/martinfowler.com\/bliki\/CircuitBreaker.html\"> circuit breakers<\/a> to ensure that a single degraded Redis node would not break Intercom. When tested in isolation the circuit breakers worked as designed, however what they did not protect against was Redis being called a large number of times per API request (over 100 in some cases), and all of those requests being a lot slower than usual. Intercom obviously needs to be robust against the degraded performance of a single Redis node, and we hadn\u2019t anticipated the frequency of Redis being called from our application. To address this we\u2019ll be reducing the frequency of calls made to Redis, improving how the application automatically detects and responds to such problems, and running game-days that verify the correct behaviour (likely using\u00a0<a href=\"httpa:\/\/vaurien.readthedocs.org\/\">Vaurien<\/a> to simulate a slow-running Redis node &#8211; we&#8217;ve already used it successfully to simulate issues with HTTP services).<\/p>\n<h2 id=\"challenging-and-fun\">Challenging and fun<\/h2>\n<p>The summaries above attempt to neatly condense a lot of blood and guts and chaos down to a readable narrative. We tried a lot of things that didn\u2019t work or had minimal impact, and encountered a number of red herrings along the way. We learned more about our product and how to think about data storage and resilience as we continue to grow. It\u2019s challenging and fun to work in environments experiencing high growth and where your work contributes directly to a product that your customers<a href=\"https:\/\/www.intercom.com\/blog\/customers\" target=\"_blank\" rel=\"noopener noreferrer\"> love to use<\/a>. If working on building great things is something you\u2019re interested in, here&#8217;s the obligatory \u201cwe\u2019re hiring\u201d <a href=\"https:\/\/www.intercom.com\/blog\/careers\">link<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Our goal for Intercom availability is that each of our public facing endpoints (In-App Messenger, the Intercom web application and public facing APIs) have greater than 99.9% availability &#8211; this means being down for no more&hellip;<\/p>\n","protected":false},"author":105,"featured_media":7260,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"category":[4],"tags":[309,259,212],"coauthors":[399],"class_list":["post-7255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","tag-availability","tag-data","tag-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Keeping Intercom up - The Intercom Blog<\/title>\n<meta name=\"description\" content=\"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.\" \/>\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.intercom.com\/blog\/keeping-intercom-up\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Keeping Intercom up\" \/>\n<meta property=\"og:description\" content=\"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/\" \/>\n<meta property=\"og:site_name\" content=\"The Intercom Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/intercominc\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-11T16:00:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-07-30T12:02:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png\" \/>\n\t<meta property=\"og:image:width\" content=\"984\" \/>\n\t<meta property=\"og:image:height\" content=\"466\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Brian Scanlan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@brian_scanlan\" \/>\n<meta name=\"twitter:site\" content=\"@intercom\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Brian Scanlan\" \/>\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.intercom.com\\\/blog\\\/keeping-intercom-up\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/\"},\"author\":{\"name\":\"Brian Scanlan\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/person\\\/b1709ce5dd599e9a343f018820261df2\"},\"headline\":\"Keeping Intercom up\",\"datePublished\":\"2015-03-11T16:00:50+00:00\",\"dateModified\":\"2020-07-30T12:02:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/\"},\"wordCount\":1487,\"publisher\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/03\\\/Intercom-Q4-availability-hero.png\",\"keywords\":[\"availability\",\"data\",\"development\"],\"articleSection\":[\"News &amp; Updates\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/\",\"name\":\"Keeping Intercom up - The Intercom Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/03\\\/Intercom-Q4-availability-hero.png\",\"datePublished\":\"2015-03-11T16:00:50+00:00\",\"dateModified\":\"2020-07-30T12:02:23+00:00\",\"description\":\"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/keeping-intercom-up\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/03\\\/Intercom-Q4-availability-hero.png\",\"contentUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/03\\\/Intercom-Q4-availability-hero.png\",\"width\":984,\"height\":466},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/\",\"name\":\"The Intercom Blog\",\"description\":\"Articles and Podcasts on Customer Service, AI and Automation, Product, and more\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#organization\",\"name\":\"The Intercom Blog\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/Intercom-logo-sq-black-trans.png\",\"contentUrl\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/Intercom-logo-sq-black-trans.png\",\"width\":1000,\"height\":1000,\"caption\":\"The Intercom Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/intercominc\",\"https:\\\/\\\/x.com\\\/intercom\",\"https:\\\/\\\/www.instagram.com\\\/intercom\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/2491343\",\"https:\\\/\\\/www.pinterest.ie\\\/intercom\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCJG0MvLP03kyzzAkD-w98aQ\",\"https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/Intercom_(company)\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/#\\\/schema\\\/person\\\/b1709ce5dd599e9a343f018820261df2\",\"name\":\"Brian Scanlan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg97554399c095ae58633cba361b67ea03\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg\",\"caption\":\"Brian Scanlan\"},\"description\":\"Brian leads Intercom's developer infrastructure efforts, helping teams make products resilient to failure and scalable to customers' needs. Formerly with HEAnet and Amazon.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/scanlanb\\\/\",\"https:\\\/\\\/x.com\\\/brian_scanlan\"],\"url\":\"https:\\\/\\\/www.intercom.com\\\/blog\\\/author\\\/brian_scanlan\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Keeping Intercom up - The Intercom Blog","description":"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.","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.intercom.com\/blog\/keeping-intercom-up\/","og_locale":"en_US","og_type":"article","og_title":"Keeping Intercom up","og_description":"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.","og_url":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/","og_site_name":"The Intercom Blog","article_publisher":"https:\/\/www.facebook.com\/intercominc","article_published_time":"2015-03-11T16:00:50+00:00","article_modified_time":"2020-07-30T12:02:23+00:00","og_image":[{"width":984,"height":466,"url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","type":"image\/png"}],"author":"Brian Scanlan","twitter_card":"summary_large_image","twitter_creator":"@brian_scanlan","twitter_site":"@intercom","twitter_misc":{"Written by":"Brian Scanlan","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/#article","isPartOf":{"@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/"},"author":{"name":"Brian Scanlan","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/person\/b1709ce5dd599e9a343f018820261df2"},"headline":"Keeping Intercom up","datePublished":"2015-03-11T16:00:50+00:00","dateModified":"2020-07-30T12:02:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/"},"wordCount":1487,"publisher":{"@id":"https:\/\/www.intercom.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/#primaryimage"},"thumbnailUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","keywords":["availability","data","development"],"articleSection":["News &amp; Updates"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/","url":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/","name":"Keeping Intercom up - The Intercom Blog","isPartOf":{"@id":"https:\/\/www.intercom.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/#primaryimage"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/#primaryimage"},"thumbnailUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","datePublished":"2015-03-11T16:00:50+00:00","dateModified":"2020-07-30T12:02:23+00:00","description":"The latest update on our operational performance and some of the technical detail on what we\u2019ve been doing to improve Intercom availability and performance.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.intercom.com\/blog\/keeping-intercom-up\/#primaryimage","url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","contentUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","width":984,"height":466},{"@type":"WebSite","@id":"https:\/\/www.intercom.com\/blog\/#website","url":"https:\/\/www.intercom.com\/blog\/","name":"The Intercom Blog","description":"Articles and Podcasts on Customer Service, AI and Automation, Product, and more","publisher":{"@id":"https:\/\/www.intercom.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.intercom.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.intercom.com\/blog\/#organization","name":"The Intercom Blog","url":"https:\/\/www.intercom.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/08\/Intercom-logo-sq-black-trans.png","contentUrl":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2019\/08\/Intercom-logo-sq-black-trans.png","width":1000,"height":1000,"caption":"The Intercom Blog"},"image":{"@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/intercominc","https:\/\/x.com\/intercom","https:\/\/www.instagram.com\/intercom\/","https:\/\/www.linkedin.com\/company\/2491343","https:\/\/www.pinterest.ie\/intercom\/","https:\/\/www.youtube.com\/channel\/UCJG0MvLP03kyzzAkD-w98aQ","https:\/\/en.wikipedia.org\/wiki\/Intercom_(company)"]},{"@type":"Person","@id":"https:\/\/www.intercom.com\/blog\/#\/schema\/person\/b1709ce5dd599e9a343f018820261df2","name":"Brian Scanlan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg97554399c095ae58633cba361b67ea03","url":"https:\/\/secure.gravatar.com\/avatar\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/557ac9be8a2b4e8abd5ff0d77470ded5591d3b056dedb68cbde898233ef5170e?s=96&d=mm&r=pg","caption":"Brian Scanlan"},"description":"Brian leads Intercom's developer infrastructure efforts, helping teams make products resilient to failure and scalable to customers' needs. Formerly with HEAnet and Amazon.","sameAs":["https:\/\/www.linkedin.com\/in\/scanlanb\/","https:\/\/x.com\/brian_scanlan"],"url":"https:\/\/www.intercom.com\/blog\/author\/brian_scanlan\/"}]}},"jetpack_featured_media_url":"https:\/\/www.intercom.com\/blog\/wp-content\/uploads\/2015\/03\/Intercom-Q4-availability-hero.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts\/7255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/users\/105"}],"replies":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/comments?post=7255"}],"version-history":[{"count":0,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/posts\/7255\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/media\/7260"}],"wp:attachment":[{"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/media?parent=7255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/category?post=7255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/tags?post=7255"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.intercom.com\/blog\/wp-json\/wp\/v2\/coauthors?post=7255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}