{"id":1835,"date":"2014-12-16T17:37:33","date_gmt":"2014-12-16T17:37:32","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1835"},"modified":"2017-04-19T13:59:17","modified_gmt":"2017-04-19T20:59:17","slug":"why-membase-uses-erlang","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/","title":{"rendered":"Why Membase Uses  Erlang"},"content":{"rendered":"<p>Less and less often (because Erlang is becoming more popular), I\u2019m asked why Membase chose to use <a href=\"https:\/\/www.erlang.org\/\">Erlang<\/a> for our cluster management and process supervision component. Common alternatives people suggest are Java, C++, <a href=\"https:\/\/python.org\">Python<\/a>, <a href=\"https:\/\/ruby-lang.org\">Ruby<\/a>, and, more recently, <a href=\"https:\/\/nodejs.org\/\">node.js<\/a> and <a href=\"https:\/\/clojure.org\/\">Clojure<\/a> (which would be my top choice if Erlang were off limits to me).<\/p>\n<p>There are certainly a lot of disadvantages to using Erlang. First and foremost, it\u2019s another runtime environment to build, bundle, and support &#8211; we depend on the system Python on Linux and OS X and use <a href=\"https:\/\/www.py2exe.org\/\">py2exe<\/a> to build executables for Windows, but we actually build and bundle Erlang. With Java, we could potentially depend on the system\u2019s already having Java installed &#8211; a little harder on Linux but easier on Windows. In addition, we\u2019ll eventually need a Java runtime to be able to run Java NodeCode modules.<\/p>\n<p>In addition, not nearly as many programmers know Erlang as Java or C++, or in fact any of the possible alternatives I mentioned. Its syntax and semantics are unusual given its <a href=\"https:\/\/en.wikipedia.org\/wiki\/Prolog\">Prolog<\/a> roots, concurrent, functional nature, and the fact that it\u2019s a pragmatic language that\u2019s been in use and evolving since 1986. This hasn\u2019t turned out to be a problem for Membase\u2019s engineering team &#8211; four of us can work on the Erlang components, and the Erlang code is small enough that it could easily be maintained by any one of us. However, it definitely sets the bar higher both for our own developers and community contributors to be able to contribute to the cluster management subsystem if they don\u2019t already know Erlang.<\/p>\n<p>It\u2019s totally worth it. Erlang (Erlang\/OTP really, which is what most people mean when they say \u201cErlang has X\u201d) does out of the box a lot of things we would have had to either build from scratch or attempt to piece together existing libraries to do. Its <a href=\"https:\/\/learnyousomeerlang.com\/types-or-lack-thereof\">dynamic type system<\/a> and <a href=\"https:\/\/erlang.org\/doc\/reference_manual\/expressions.html#pattern\">pattern matching<\/a> (ala <a href=\"https:\/\/www.haskell.org\/\">Haskell<\/a> and ML) make Erlang code tend to be even more concise than Python and Ruby, two languages known for their ability to do a lot in few lines of code.<\/p>\n<p>The single largest advantage to us of using Erlang has got to be its built-in support for <a href=\"https:\/\/ulf.wiger.net\/weblog\/2008\/02\/06\/what-is-erlang-style-concurrency\/\">concurrency<\/a>. Erlang models concurrent tasks as \u201c<a href=\"https:\/\/www.erlang.org\/doc\/reference_manual\/processes.html\">processes<\/a>\u201d that can communicate with one another only via message-passing (which makes use of pattern matching!), in what is known as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Actor_model\">actor model<\/a> of concurrency. This alone makes an entire class of concurrency-related bugs completely impossible. While it <a href=\"https:\/\/james-iry.blogspot.com\/2009\/04\/erlang-style-actors-are-all-about_16.html\">doesn\u2019t completely prevent deadlock<\/a>, it turns out to be pretty difficult to miss a potential deadlock scenario when you write code this way. While it\u2019s certainly <a href=\"https:\/\/stackoverflow.com\/questions\/22187\/erlang-style-concurrency-for-other-languages\">possible<\/a> to implement the actor model in most if not all of the alternative environments I mentioned, and in fact such implementations exist, they are either incomplete or suffer from an impedance mismatch with existing libraries that expect you to use threads.<\/p>\n<p>Erlang processes, in addition to being isolated from one another, are very lightweight. One can easily run a quarter million of them in a single Erlang VM. The cost of spawning them is also quite low, making silly hacks to reuse them unnecessary. Since they run in the same memory space and are isolated only by software, message passing between them is extremely fast, and while it does involve copying the data in the message most of the time, messages tend to be small and this allows Erlang processes to be garbage collected independently.<\/p>\n<p>OTP arranges processes into a \u201csupervision tree\u201d where supervisor processes monitor child processes, which can also be supervisors, and restart them and potentially any dependent processes should they crash. Along with process isolation, this makes Erlang applications extremely fault-tolerant: any Erlang process within our cluster management subsystem (other than the root supervisor) can crash without taking Membase down. In fact, we make very good use of this: when unexpected things happen in any of our processes, we generally let them just crash and restart, bringing them back up in a known good state. For example, the process that manages the administrative connection to the local memcached process will simply crash if the connection times out or returns any error it doesn\u2019t expect. This makes error handling exactly the same as startup, which leaves fewer places for bugs to hide and eases testing.<\/p>\n<p>In order to make it easy to structure a complex application as a set of interacting processes, Erlang\/OTP provides a standard set of \u201c<a href=\"https:\/\/www.erlang.org\/doc\/design_principles\/des_princ.html#id60487\">behaviors<\/a>\u201d that modules can implement. The most common of these is <a href=\"https:\/\/www.erlang.org\/doc\/man\/gen_server.html\">gen_server<\/a>, the generic server behavior, which implements a basic server with callbacks for requests. <a href=\"https:\/\/www.erlang.org\/doc\/design_principles\/fsm.html\">Gen_fsm<\/a> implements a finite state machine, and <a href=\"https:\/\/www.erlang.org\/doc\/design_principles\/events.html\">gen_event<\/a> is for implementing event handlers and event managers.<\/p>\n<p>Messages in Erlang can be sent as easily to a process residing on another node as they can to processes on the same node; this is completely transparent to the programmer. Erlang\/OTP has a bunch of modules that help with distributed processing. For example, the \u201cglobal\u201d module provides a common registry of global names and locks, similar to Google\u2019s Chubby lock manager. OTP\u2019s \u201cdistributed applications\u201d provide a way to ensure a given set of processes only starts on one node. Mnesia is a distributed DBMS with strong consistency guarantees that we use for storing statistics.<\/p>\n<p>Erlang provides excellent support for debugging and patching of live systems. After all, it was invented for building systems with five nines of uptime. If you know the cryptographic cookie nodes use to authenticate themselves to one another, it\u2019s trivial to attach another Erlang node to the cluster and execute arbitrary commands on any other node, including \u201creload this module\u201d. This sort of capability is invaluable when you need to fix or work around a bug and can\u2019t take down a cluster or even a single node to replace code. It\u2019s also invaluable for testing or any situation where we (or a customer) want to make changes to the cluster state that haven\u2019t yet been implemented in the REST API.<\/p>\n<p>At the end of the day, the real question isn\u2019t whether it would have been possible for us to implement our cluster management in another language; it\u2019s really a question of effort and maintainability of the result. With any other environment, we would have had to reimplement at least part of what Erlang\/OTP provides, while we haven\u2019t really found ourselves reimplementing features provided by any other environment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Less and less often (because Erlang is becoming more popular), I\u2019m asked why Membase chose to use Erlang for our cluster management and process supervision component. Common alternatives people suggest are Java, C++, Python, Ruby, and, more recently, node.js and [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8985],"class_list":["post-1835","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Why Membase Uses Erlang - The Couchbase Blog<\/title>\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.couchbase.com\/blog\/why-membase-uses-erlang\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Why Membase Uses Erlang\" \/>\n<meta property=\"og:description\" content=\"Less and less often (because Erlang is becoming more popular), I\u2019m asked why Membase chose to use Erlang for our cluster management and process supervision component. Common alternatives people suggest are Java, C++, Python, Ruby, and, more recently, node.js and [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T17:37:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-04-19T20:59:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sean Lynch\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sean Lynch\" \/>\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:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\"},\"author\":{\"name\":\"Sean Lynch\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/74f9c611ecff848513c56c0140eb31cd\"},\"headline\":\"Why Membase Uses Erlang\",\"datePublished\":\"2014-12-16T17:37:32+00:00\",\"dateModified\":\"2017-04-19T20:59:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\"},\"wordCount\":1096,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\",\"name\":\"Why Membase Uses Erlang - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T17:37:32+00:00\",\"dateModified\":\"2017-04-19T20:59:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Why Membase Uses Erlang\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/74f9c611ecff848513c56c0140eb31cd\",\"name\":\"Sean Lynch\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/abc8717cc349562a1fac7cd7e3e5e73c\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/123867b09e058a0cb2e2feee0f87f8bf263115c19fb7f6260f1cdb39ecc45f4d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/123867b09e058a0cb2e2feee0f87f8bf263115c19fb7f6260f1cdb39ecc45f4d?s=96&d=mm&r=g\",\"caption\":\"Sean Lynch\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/sean-lynch\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Why Membase Uses Erlang - The Couchbase Blog","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.couchbase.com\/blog\/why-membase-uses-erlang\/","og_locale":"en_US","og_type":"article","og_title":"Why Membase Uses Erlang","og_description":"Less and less often (because Erlang is becoming more popular), I\u2019m asked why Membase chose to use Erlang for our cluster management and process supervision component. Common alternatives people suggest are Java, C++, Python, Ruby, and, more recently, node.js and [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T17:37:32+00:00","article_modified_time":"2017-04-19T20:59:17+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Sean Lynch","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Sean Lynch","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/"},"author":{"name":"Sean Lynch","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/74f9c611ecff848513c56c0140eb31cd"},"headline":"Why Membase Uses Erlang","datePublished":"2014-12-16T17:37:32+00:00","dateModified":"2017-04-19T20:59:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/"},"wordCount":1096,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/","url":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/","name":"Why Membase Uses Erlang - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T17:37:32+00:00","dateModified":"2017-04-19T20:59:17+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/why-membase-uses-erlang\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Why Membase Uses Erlang"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/74f9c611ecff848513c56c0140eb31cd","name":"Sean Lynch","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/abc8717cc349562a1fac7cd7e3e5e73c","url":"https:\/\/secure.gravatar.com\/avatar\/123867b09e058a0cb2e2feee0f87f8bf263115c19fb7f6260f1cdb39ecc45f4d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/123867b09e058a0cb2e2feee0f87f8bf263115c19fb7f6260f1cdb39ecc45f4d?s=96&d=mm&r=g","caption":"Sean Lynch"},"url":"https:\/\/www.couchbase.com\/blog\/author\/sean-lynch\/"}]}},"authors":[{"term_id":8985,"user_id":12,"is_guest":0,"slug":"sean-lynch","display_name":"Sean Lynch","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/123867b09e058a0cb2e2feee0f87f8bf263115c19fb7f6260f1cdb39ecc45f4d?s=96&d=mm&r=g","author_category":"","last_name":"Lynch","first_name":"Sean","job_title":"","user_url":"","description":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1835"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1835\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1835"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}