{"id":1943,"date":"2013-10-03T09:00:00","date_gmt":"2013-10-03T16:00:00","guid":{"rendered":""},"modified":"2024-01-22T22:49:09","modified_gmt":"2024-01-23T06:49:09","slug":"concurrency-control-in-the-in-memory-oltp-engine","status":"publish","type":"post","link":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/","title":{"rendered":"Concurrency Control in the In-Memory OLTP Engine"},"content":{"rendered":"<p><span style=\"font-size:small;\">We believe that the In-Memory OLTP engine advances the industry state of the art with respect to concurrency control. The main reason for this advancement is due to the <i>combination<\/i> of lock free algorithms and the row-versioned architecture of the engine. <\/span><\/p>\n<p><span style=\"font-size:small;\">This post examines what we precisely mean when we describe the In-Memory OLTP engine as being \u2018lock free\u2019, both in abstract terms but more importantly in terms of impact on user workloads.<\/span><\/p>\n<p><span style=\"font-size:small;\">Let\u2019s start with a brief definition capturing the core attributes implied by the term \u2018lock free\u2019 in In-Memory OLTP: <\/span><\/p>\n<p><span style=\"font-size:small;\">\u201cAt <i>steady state<\/i>, <i>transaction carrying threads<\/i> executing in the <i>context of the<\/i> <i>In-Memory OLTP<\/i> <i>engine<\/i> are designed to require no blocking operation.\u201d <\/span><\/p>\n<p><span style=\"font-size:small;\">Element by element, this definition implies the following exclusions:<\/span><\/p>\n<ul>\n<ul>\n<li><span style=\"font-size:small;\"><i>Steady state \u2013 <\/i>we explicitly do not claim that execution will be lock free when the system ramps up or shuts down or when it goes through significant fluctuations in the workload. In particular for instance, the In-Memory OLTP engine allocates large pages of memory from the SQL Server host (and implicitly from the host OS). Clearly these operations will acquire locks since neither the OS nor SQL Server in general are \u2018lock free\u2019. The engine does implement its own lock free small block allocator (currently capped at 8K blocks), so once a page is obtained from the host process, future block allocations will be serviced without the need to acquire any subsequent locks, but the workload ramp-up \u2013 characterized as it is by page acquisition from the host \u2013 will incur some locking overhead.<\/span><\/li>\n<\/ul>\n<\/ul>\n<ul>\n<ul>\n<li><span style=\"font-size:small;\"><i>Transaction carrying threads<\/i> \u2013 we use this term to differentiate between threads doing work on behalf of the user workload from threads doing work on behalf of the system itself. Examples of system (or worker) threads include threads involved in checkpoint, some GC maintenance, file allocation \u2013 and so on. Since these threads are never visible to the end user and since their responsiveness does not impact the end user workload, execution of these system threads is not designed to be entirely lock free.<\/span><\/li>\n<\/ul>\n<\/ul>\n<ul>\n<ul>\n<li><span style=\"font-size:small;\">E<i>xecution in the context of the In-Memory OLTP<\/i> <i>engine<\/i>. We use this phrase to distinguish between execution that takes place within the context of the engine and execution that takes place in the SQL host, in the OS or even in the client stack. One example triggering this exclusion was presented above: acquiring large pages from the SQL host will occasionally acquire locks. Similarly, file access in the context of checkpoint or logging will incur OS level locking; waiting for log IO before acknowledging a transaction commit will also incur some form of waiting; clearing of transaction dependencies &#8211; which is required for correctness &#8211; will also cause a thread to stall, and so on. These examples all demonstrate that locking is still present in SQL Server running In-Memory OLTP. However, it also remains true that we have eliminated all locks or waits <i>within the engine itself<\/i> \u2013 and that is precisely the location where locks (or in our case their absence) have the most impact on the end user.<\/span><\/li>\n<\/ul>\n<\/ul>\n<p><span style=\"font-size:small;\">Once we agree on the definitions above, we note that in the context of any database system, locking behavior always implies two distinct considerations: we use locks for logical data protection (also known as transactional isolation) and for physical data protection. <\/span><\/p>\n<p><span style=\"font-size:small;\">One example of <b>logical data protection<\/b> is row payload protection. Row payload protection means that while a user modifies a row another user does not modify the same row. This is what logical (transactional) locks are used for in traditional SQL Server (row locks, page locks, database locks and even app locks can be used for the same purpose). With In-Memory OLTP we rely on row versioning to ensure that row content is never modified by two users at the same time \u2013 in other words we don\u2019t use transactional locks because we never update data in place. If two or more users try to update the same row at the same time, one will succeed while the others will fail due to a write\/write conflict. Note that this can be achieved without any locking by creating a new version for each user and then trying to install each version atomically in the same index location (by using \u2018<\/span><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ff471479(v=vs.85).aspx\"><span style=\"font-size:small;\">InterlockedCompareExchange<\/span><\/a><span style=\"font-size:small;\">\u2019 \u2013 or ICX). Out of the multiple users that try to update the same row at the same time, one will succeed and the others will fail this hardware level ICX operation \u2013 and that translates directly into the behavior reported back by the system.<\/span><\/p>\n<p><span style=\"font-size:small;\"><b>Physical data protection<\/b> is a different problem altogether. In traditional database systems (<\/span><a href=\"http:\/\/www.bing.com\/search?q=database+latch+contention\"><span style=\"font-size:small;\">SQL Server but also more broadly in the industry<\/span><\/a><span style=\"font-size:small;\">) we protect internal data structures via spinlocks and latches. Broadly speaking (and oversimplifying), the difference between spinlocks and latches is that a thread trying to acquire a spinlock will spin when the lock is found to be currently held by a different thread whereas for latches the acquiring thread will yield its CPU time back to the OS if the latch is found to be currently held by a different thread. Given this difference, traditional SQL uses latches for waits that could take a while (getting a page in the buffer pool) while spinlocks are used for short term waits (waiting for a memory only linked list traversal for instance). However, both locks and latches have in common the fact that they are \u2018region locks\u2019. We use the term \u2018region lock\u2019 to describe the mechanism used to protect a region of code or data structures against simultaneous thread access. Region locks implement an \u2018Acquire\/Release\u2019 pattern \u2013 where a lock (either latch or spinlock) is first <b>acquired<\/b>, the protected region executes, and then the lock is <b>released<\/b>. The problem with that approach is that it does not scale. In a system with many cores or very high concurrency the region being protected becomes a bottleneck. For instance, in Windows Server the scheduling quantum is around 180ms, so if a thread that holds a spinlock gets preempted, that spinlock will be held for 180ms regardless of how short the protected region would be otherwise. There are other negative side effects from region locks because they all involve writing to shared cache lines even when the lock is acquired for read access \u2013 which becomes problematic in many-core and NUMA systems or under high concurrency. The lock free engine avoids these issues by implementing all operations in an atomic fashion. In other words, the In-Memory OLTP engine does not define any protected regions in transaction executing paths. The data structures and algorithms are structured such that state transitions are atomic and therefore are not subject to the whims of the scheduling subsystem. In addition, many operations are done without any shared-cache line modifying instructions at all (meaning that the entire operation does not even use ICX but rather touches in write mode only cache lines that are private to the local processor) which improves scalability and concurrency to the limits supported by the hardware. <\/span><\/p>\n<p><span style=\"font-size:small;\">The prime example of that is index traversal: the engine walks both hash and range indices without any locks or ICX instructions. In the process the engine detects if the underlying data structure has changed in a manner that could invalidate the current traversal and re-attempts the small portion of the traversal that was invalidated. These re-traversal are extremely rare even at very high concurrency (in the early days of the In-Memory OLTP engine we have measured under 100 retries for million tx \/ sec workload) \u2013 so their measurable performance impact is virtually non-existent. When the engine needs to modify one of these lock free data structures it does so via ICX \u2013 which makes the modification visible atomically.<\/span><\/p>\n<p><span style=\"font-size:small;\">A careful observation of current hardware trends presents overwhelming evidence that the number of available cores in any given computing platform is likely to rise with time. In this context, concurrency control that is at its core lean and efficient is absolutely crucial to achieving first-rate performance. With In-Memory OLTP we have taken these insights to heart and built an engine that relies on no locks, waits, latches or other synchronization primitives to ensure consistency of execution. We believe this approach removes locking and latching as a concern for even our most demanding users.<\/span><\/p>\n<p>For more information, <a href=\"http:\/\/technet.microsoft.com\/en-US\/evalcenter\/dn205290?WT.mc_id=Blog_SQL_InMem_SQL2014\">download SQL Server CTP1<\/a>and get started today, or see more blogs in the <a href=\"http:\/\/blogs.technet.com\/b\/dataplatforminsider\/archive\/2013\/06\/26\/sql-server-2014-in-memory-technologies-blog-series-introduction.aspx\">series introduction and index here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We believe that the In-Memory OLTP engine advances the industry state of the art with respect to concurrency control. The main reason for this advancement is due to the combination of lock free algorithms and the row-versioned architecture of the engine.<\/p>\n","protected":false},"author":1457,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","footnotes":""},"post_tag":[],"product":[],"content-type":[2445],"topic":[],"coauthors":[2487],"class_list":["post-1943","post","type-post","status-publish","format-standard","hentry","content-type-thought-leadership"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server 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.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server Blog\" \/>\n<meta property=\"og:description\" content=\"We believe that the In-Memory OLTP engine advances the industry state of the art with respect to concurrency control. The main reason for this advancement is due to the combination of lock free algorithms and the row-versioned architecture of the engine.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft SQL Server Blog\" \/>\n<meta property=\"article:publisher\" content=\"http:\/\/www.facebook.com\/sqlserver\" \/>\n<meta property=\"article:published_time\" content=\"2013-10-03T16:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-23T06:49:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2018\/08\/cropped-microsoft_logo_element.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"SQL Server Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@SQLServer\" \/>\n<meta name=\"twitter:site\" content=\"@SQLServer\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"SQL Server Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 min read\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\"},\"author\":[{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/author\/sql-server-team\/\",\"@type\":\"Person\",\"@name\":\"SQL Server Team\"}],\"headline\":\"Concurrency Control in the In-Memory OLTP Engine\",\"datePublished\":\"2013-10-03T16:00:00+00:00\",\"dateModified\":\"2024-01-23T06:49:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\"},\"wordCount\":1401,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\",\"name\":\"Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#website\"},\"datePublished\":\"2013-10-03T16:00:00+00:00\",\"dateModified\":\"2024-01-23T06:49:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Concurrency Control in the In-Memory OLTP Engine\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#website\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/\",\"name\":\"Microsoft SQL Server Blog\",\"description\":\"Official News from Microsoft\u2019s Information Platform\",\"publisher\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization\",\"name\":\"Microsoft SQL Server Blog\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"contentUrl\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"width\":259,\"height\":194,\"caption\":\"Microsoft SQL Server Blog\"},\"image\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"http:\/\/www.facebook.com\/sqlserver\",\"https:\/\/x.com\/SQLServer\",\"https:\/\/www.youtube.com\/user\/MSCloudOS\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server 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.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/","og_locale":"en_US","og_type":"article","og_title":"Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server Blog","og_description":"We believe that the In-Memory OLTP engine advances the industry state of the art with respect to concurrency control. The main reason for this advancement is due to the combination of lock free algorithms and the row-versioned architecture of the engine.","og_url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/","og_site_name":"Microsoft SQL Server Blog","article_publisher":"http:\/\/www.facebook.com\/sqlserver","article_published_time":"2013-10-03T16:00:00+00:00","article_modified_time":"2024-01-23T06:49:09+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2018\/08\/cropped-microsoft_logo_element.png","type":"image\/png"}],"author":"SQL Server Team","twitter_card":"summary_large_image","twitter_creator":"@SQLServer","twitter_site":"@SQLServer","twitter_misc":{"Written by":"SQL Server Team","Est. reading time":"6 min read"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#article","isPartOf":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/"},"author":[{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/author\/sql-server-team\/","@type":"Person","@name":"SQL Server Team"}],"headline":"Concurrency Control in the In-Memory OLTP Engine","datePublished":"2013-10-03T16:00:00+00:00","dateModified":"2024-01-23T06:49:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/"},"wordCount":1401,"commentCount":6,"publisher":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/","url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/","name":"Concurrency Control in the In-Memory OLTP Engine - Microsoft SQL Server Blog","isPartOf":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#website"},"datePublished":"2013-10-03T16:00:00+00:00","dateModified":"2024-01-23T06:49:09+00:00","breadcrumb":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/2013\/10\/03\/concurrency-control-in-the-in-memory-oltp-engine\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/"},{"@type":"ListItem","position":2,"name":"Concurrency Control in the In-Memory OLTP Engine"}]},{"@type":"WebSite","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#website","url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/","name":"Microsoft SQL Server Blog","description":"Official News from Microsoft\u2019s Information Platform","publisher":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#organization","name":"Microsoft SQL Server Blog","url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","contentUrl":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","width":259,"height":194,"caption":"Microsoft SQL Server Blog"},"image":{"@id":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/#\/schema\/logo\/image\/"},"sameAs":["http:\/\/www.facebook.com\/sqlserver","https:\/\/x.com\/SQLServer","https:\/\/www.youtube.com\/user\/MSCloudOS"]}]}},"msxcm_display_generated_audio":false,"msxcm_animated_featured_image":null,"_links":{"self":[{"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/posts\/1943","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/users\/1457"}],"replies":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/comments?post=1943"}],"version-history":[{"count":0,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/posts\/1943\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/media?parent=1943"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/post_tag?post=1943"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/product?post=1943"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/content-type?post=1943"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/topic?post=1943"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/sql-server\/blog\/wp-json\/wp\/v2\/coauthors?post=1943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}