<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Felix Gessert on Medium]]></title>
        <description><![CDATA[Stories by Felix Gessert on Medium]]></description>
        <link>https://medium.com/@felix.gessert?source=rss-233cc61c4b11------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*z9kVxlSs1eZkF1kizI9Ihw.png</url>
            <title>Stories by Felix Gessert on Medium</title>
            <link>https://medium.com/@felix.gessert?source=rss-233cc61c4b11------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 20:50:05 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@felix.gessert/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[The Core Web Vital “Largest Contentful Paint” just changed dramatically]]></title>
            <link>https://medium.com/baqend-blog/the-core-web-vital-largest-contentful-paint-just-changed-dramatically-b7bf5b7f17f3?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/b7bf5b7f17f3</guid>
            <category><![CDATA[seo]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Thu, 04 Feb 2021 18:16:35 GMT</pubDate>
            <atom:updated>2021-02-08T12:59:29.898Z</atom:updated>
            <content:encoded><![CDATA[<h3>Largest Contentful Paint is about to drop by 20% in Chrome 88</h3><p>In this quick summary we present a finding around the central Google Core Web Vital <strong>Largest Contentful Paint </strong>(LCP) that is expected to change in a drastic way with the recent release of Chrome 88. Overall, we found that the LCP is likely to drop by as much as 20%. Given Google’s upcoming ranking changes for May 2021, the LCP is more important than ever.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sZwwITf_AAlnDaNc1TPZZw.png" /></figure><h4>Background: What are the Core Web Vitals?</h4><p>The <a href="https://web.dev/vitals/#core-web-vitals">Core Web Vitals</a> are an initiative by Google, to provide better metrics to evaluate page performance and user experience. While previously it had already been possible to somehow capture the “felt page speed” of websites using metrics such as the Speed Index (the average time to visibility of page elements) pioneered by WebPagetest or the First Meaningful Paint (the time of the biggest visual change in page rendering), these methods had one severe problem: they rely on a synthetic testing environment and video analysis. So, they cannot be measured through browser APIs and with actual “field data”. Previous metrics that were available from the browser and navigation timing APIs like the time-to-first-byte and the first paint on the other hand do not fully reflect the real <em>experience of speed</em>.</p><p>Google introduced three core web vitals: the <strong>Largest Contentful Paint</strong> (LCP), the <strong>First Input Delay</strong> (FID) and the <strong>Cumulative Layout Shift </strong>(CLS). For each of these metrics, Google also proposes a “traffic light” essentially putting page views into three buckets <em>good</em>, <em>ok</em>, <em>bad</em> based on thresholds.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3foVCyiTopFghZYehDVodg.png" /><figcaption>The three Core Web Vitals (image taken from <a href="https://web.dev/vitals/#core-web-vitals">web.dev</a>).</figcaption></figure><p>This is what the Core Web Vitals capture:</p><ul><li><strong>LCP</strong>: measures <strong>how fast the page loads</strong>. For this, it captures the moment during the rendering process where the largest element containing content (e.g. text of images) is rendering on the user’s screen.</li><li><strong>FID</strong>: measures <strong>how quickly the page responds to user interaction</strong>. It is evaluated as the time between the first interaction (e.g. click or screen tap) until the event is processed in a JavaScript handler.</li><li><strong>CLS</strong>: measures <strong>how stable the page is rendering</strong>. The calculation is a bit complicated but evolves around how much content is jumping/moving by what distance during the rendering process. There are <a href="https://web.dev/better-layout-shift-metric/">ongoing discussions</a> on how to optimize the calculation to best reflect user-felt “annoyingness”.</li></ul><p>Naturally, many consider the LCP as the central metric as it reflects the overall loading time of a page. Currently, the Largest Contentful Paint API is <a href="https://caniuse.com/?search=largest">available</a> in Chromium-based browsers, so covering around 70% of end users. In a second, we will explain why many websites might have scored badly in the LCP without actually doing anything wrong or being slow.</p><h4>Measuring the Web Vitals</h4><p>Today the main sources for the Web Vitals are <a href="https://developers.google.com/web/tools/lighthouse">Lighthouse</a> respectively <a href="https://developers.google.com/speed/pagespeed/insights/?hl=de">Page Speed Insights</a> for synthetic (“bot”) performance measurements as well as the <a href="https://developers.google.com/web/tools/chrome-user-experience-report">Chrome User Experience Report </a>(CRUX). CRUX is a highly valuable public data set that contains anonymous real-user performance data from Chrome browsers for Millions of top domains. It is not only a great tool for performance analysis but also the basis for Google incorporating end-user speed as a ranking factor into its search.</p><p>For example, one interesting thing you can do is to rank the top 10 global e-commerce companies by their LCP:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wVcFIccOcdL3CFen-fQOJg.png" /><figcaption>Ranking of top 10 e-commerce players (by revenue) ordered by share of fast LCP page views (source: Pagespeed Insights CRUX data as of Feb 4 2021)</figcaption></figure><h4>Google Page Experience Update is around the corner</h4><p>The web vitals were presented in May 2020. By the end of last year, Google announced that starting from May 2021 the Web Vitals will become part of the Google Search ranking. Since its <a href="https://webmasters.googleblog.com/2018/01/using-page-speed-in-mobile-search.html">Mobile Speed Update</a> from 2018, Google has been considering speed in the rank and — unlike in the old days — speed is no longer measured by the Google bot but instead <a href="https://moz.com/blog/google-chrome-usage-data-measure-site-speed">based on CRUX</a>. Besides the organic ranking, speed also plays a <a href="https://developers.google.com/web/updates/2018/07/search-ads-speed">role for SEA/ad placement</a>.</p><p>While the quantitative impact of speed on SEO is of course a well-kept secret, there are some studies. For example, Pinterest has seen <a href="https://medium.com/pinterest-engineering/driving-user-growth-with-performance-improvements-cfc50dafadd7#.wwimdmkpp">an additional 15% organic search engine traffic</a> after improving page speed by 40%.</p><p>If even before the web vitals update speed has already played such a crucial role, it is very likely to become a lot more important. Many of our e-commerce customers at Baqend for example have recently invested into getting as fast a possible in the LCP before the May update comes.</p><h4>The finding: for JavaScript-heavy websites the LCP was not accurate</h4><p>Since a while we noticed, that the LCP seemed to be unreasonably high on some sites that relied heavily on JavaScript for client-side rendering. We then noted that a change to the LCP was launching for Chrome 88 that potentially changes a lot.</p><h3></h3><p>Just saw the LCP changes in Chrome 88 (https://t.co/Fmuoj6ui8S) fixing a huge problem we see where LCP is wrongly increased when images are placed in containers by SSR rehydration or slider code.Suspect this will almost halve the LCPs reported to CRUX for a lot of top sites.</p><p>Essentially, what we observed was this: when the element that makes up the LCP is changed by JavaScript in the DOM, the LCP is reset even if the page is visually not changing at all. For example, as on <a href="https://testpage.app.baqend.com/">this test page</a>, if we change the hero image after 3 seconds, the LCP will be reset and reported to be more than 3 seconds, even though nothing has changed!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sEDwOzxkGlzCI4CY" /></figure><h4>Why is this important?</h4><p>The problem is that many websites rely on client-side JavaScript to modify elements that are defining the LCP. For example, if you change a product image slider in a shop during rendering, you can display the image as early as you want, the LCP will still be bad.</p><p>The issue is even more systematic for websites relying on modern frontend frameworks such as React, Angular, Svelte, and Vue: as soon as server-side rendering is used (usually for performance reasons!) the client-side rehydration is changing the DOM and resetting the LCP. Rehydration is simply the process of “booting up JavaScript views on the client such that they reuse the server-rendered HTML’s DOM tree and data” (see <a href="https://developers.google.com/web/updates/2019/02/rendering-on-the-web">this article</a> for more details).</p><p>Bottom line: if your JavaScript is modifying your frontend you might have been looking at very <strong>skewed LCP numbers</strong>.</p><h4>Give me data: what has changed?</h4><p>Since Chrome 88 has been out for a few weeks now, we actually have the <strong>data</strong> to underpin our hypotheses. At Baqend, we are building <a href="https://www.baqend.com/">Speed Kit</a>, a SaaS plugin solution to speed up websites based on JavaScript and Service Workers. Our approach relies on measuring the achieved performance uplift through real-user monitoring and A/B testing. Therefore, we have lots of data, since Speed Kit comes with a performance monitoring tool that measures speed metrics for every page view and in particular captures the Core Web Vitals.</p><p>Here are the changes we observed between<strong> January 20 and February 4</strong>, when comparing Chrome browser with version &lt;88 to the current version 88. The data set consists of <strong>122 Million page views</strong> from Chrome browsers across roughly 45 e-commerce customer websites. Around 70% of the traffic comes from Europe the rest is spread across all continents. Overall, 51.1% of traffic came from Chrome browsers with a version &lt;88, 48.9% were coming from Chrome 88.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pPAtB800zSwXwUhpTREYlA.png" /><figcaption>Analysis of the LCP changes across 122 Million Page Views and different quantiles.</figcaption></figure><p>As expected, the impact varies heavily across customers — this seems logical since not all of them a modifying LCP-relevant elements with JavaScript. The following scatter plot shows the impact across all analyzed customers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2pw66FwIefioOTGCUA3mPg.png" /><figcaption>Scatter plot of LCP change across customers.</figcaption></figure><p><strong>Key Findings:</strong></p><ul><li>Across the median, 75th, 90th, and 95th percentile, the LCP has consistently become <strong>~20% faster</strong> in Chrome 88.</li><li>For the<strong> 99th percentile</strong> (so the slowest 1% of page views) the change is a whopping <strong>43.75%.</strong></li><li>Not all websites are alike, however, with very few exceptions the new LCP calculation has led to an <strong>improvement</strong>. There seems to be <em>no </em>correlation between the traffic/size of the site and the LCP change.</li></ul><h4>Conclusions</h4><p>From this preliminary analysis, we expect drastic changes in the LCP. Whether this warrants to adapt the — already quite generous — threshold of up to 2.5 seconds considered as a “fast LCP” remains to be seen. For now, the good news is, that JavaScript-heavy sites need not longer fear a negative skew for the LCP. We will get back with an update once the CRUX data (updated once per month) allow a first confirmation of our findings in the “official” data sources.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b7bf5b7f17f3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/the-core-web-vital-largest-contentful-paint-just-changed-dramatically-b7bf5b7f17f3">The Core Web Vital “Largest Contentful Paint” just changed dramatically</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[E-Commerce Loading Times in the COVID-19 Crisis]]></title>
            <link>https://medium.com/baqend-blog/e-commerce-loading-times-in-the-covid-19-crisis-c4e210f0c0be?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/c4e210f0c0be</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[e-commerce-business]]></category>
            <category><![CDATA[covid19]]></category>
            <category><![CDATA[web-performance]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Thu, 16 Apr 2020 08:04:39 GMT</pubDate>
            <atom:updated>2020-04-16T08:50:06.034Z</atom:updated>
            <content:encoded><![CDATA[<h4>Not a Luxury Problem, But Existential</h4><h4><strong>With overloaded networks and frustrated users, it becomes vital for online shops to ensure fast and stable page loads.</strong></h4><p>Due to the corona crisis, e-commerce is facing massive challenges. People are staying at home. The increasing traffic threatens to overwhelm the networks — Netflix and others are already throttling, while the loading times of many online shops are increasing. At the same time, anxiety and tension are rising. Therefore, not only the overall consumption drops. According to a study by Google, customers perceive all page loads as being dramatically slower.</p><p>In the current situation there are <strong>two types of online shops</strong>. The first type are shops fighting for survival because customers stay away or buy significantly less. The others are downright overwhelmed by customers, so that loading times are brought to their knees by overloaded backends and networks. For the former, fast loading times are crucial in order to convert customers despite their anxiety through a frictionless user experience. For the latter, stable loading times are a basic prerequisite, for customers to be able to buy in the first place and not move away to faster competitors.</p><h3>Will the network infrastructure and shop systems handle the load?</h3><p>In addition to the concerns of many online shops, there is currently the nagging question whether the network operators will be able to cope with the increasing traffic. After all, Netflix, YouTube, Facebook, Instagram and Amazon are already reducing the quality of their media to reduce the growing load. At the same time, Internet usage in large parts of the world has increased by more than 50% since the outbreak of the COVID-19 pandemic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rHtXkiPZZ8Viit77C9RwJQ.png" /><figcaption>How Corona has effected shop performance for the largest German online shops.</figcaption></figure><p>As an example, we analyzed data from the largest German online shops to answer whether <strong>load times have increased since the outbreak of the COVID-19 crisis</strong>. As the above chart shows, the answer is clearly “yes”. Comparing January to March, <strong>85% of the shops have seen a steep performance decline</strong>, in some cases to a dramatic extent. It is also striking that the effect is not only affecting the smaller or larger shops, but is <strong>spread across the entire e-commerce industry</strong>. The data comes from Google’s so-called “Chrome User Experience Report” and contains usage data from a large number of real users. Another <a href="https://www.fastly.com/blog/how-covid-19-is-affecting-internet-performance">analysis by Fastly</a> found country-specific traffic changes between +32% and +109% associated with dropping download speeds up to 35%.</p><p>Even though the major network operators are assuring that sufficient capacity and bandwidth are available, it is clear that 85% of all shops need to take action to compensate for the slump in loading times in March. According to current figures from the German E-Commerce Association (BEVH), March sales in online retail have slumped by almost 20%. With a few exceptions (e.g. food, drugstore articles and medicine), all sectors are affected — just as with the drop in loading times.</p><h3>How customer behavior is linked to loading times during the crisis</h3><p>Many people know it from their own experience in home office: If “the Internet” does not work in the usual quality, patience can snap quickly. And that it is what millions of customers are facing at the moment. But page speed is by no means just a problem for those who have to share their 10 Mbit/s home network connection with partners and children. Often without realizing it themselves, <strong>customers react to the smallest differences in performance</strong> with significantly different behavior — and always to the disadvantage of the shop operator.</p><blockquote>Under stress, 44% of users perceive websites as slower.</blockquote><blockquote><strong>Performance study by Google and Awwwards</strong></blockquote><p>The following chart provides a summary of the most important <strong>studies and findings that online retailers should know</strong> in the current situation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1Kor0VerGWweMRFhNd01Qg.png" /><figcaption>Selected Studies on how performance impacts e-commerce user behavior (more on <a href="http://speedstudy.info/">speedstudy.info</a>).</figcaption></figure><p>The studies are only a small selection, but one thing is obvious: Slow loading sites lose users, while fast sites increase sales. How strong this correlation is, seems astonishing. If for example the top 10 shops in Germany were to load one second faster, this would correspond to 187 million Euros of additional revenue every month (according to EHI sales figures for 2019 and the Amazon statistics mentioned above). Interestingly, the additional revenue does not have to be “bought” through marketing channels, but is generated solely by customers who are more willing to buy. In addition, the better performance has a long-term effect on organic search engine traffic, as Google has started incorporating the end-user’s performance into the SEO rank in the past 2 years.</p><h3>What retailers and manufacturers have to do for performance now</h3><p>Performance is of course only one of many factors for a good conversion rate. But unlike the consumer climate, speed is a factor that every shop operator has completely in his own hands. In general, there are three areas that need to be optimized:</p><ol><li><strong>Frontend</strong>: The rendering of a website runs in a series of steps, some of which can be executed in parallel and some of which build on each other. The <em>Critical Rendering Path</em> describes the part of this process that has to run sequentially, i.e. step by step. For optimal loading times, this critical path should be kept as short as possible (few JavaScript and CSS resources) and executed in an optimal order (avoid blocking).</li><li><strong>Network</strong>: It is crucial for network performance that as few different domains as possible are integrated and that the correct protocols are used. This includes both basics (e.g. HTTP/2 instead of HTTP/1.1) and very complex details (e.g. OCSP stapling in the TLS protocol). The browser cache must also be used by appropriate HTTP headers to avoid unnecessary requests.</li><li><strong>Backend</strong>: The most complex area is the backend, since many different system are involved — from the shop system to the CMS to the ERP, PIM and database system. Therefore, there are hardly any generic solutions in this area.</li></ol><p>Classic performance optimization according to the above criteria requires a lot of time and resources. However, there is an elegant shortcut that we have developed at Baqend.</p><h3><strong>Ensure fast page loads with Speed Kit</strong></h3><p>The Hamburg-based research spin-off Baqend enables market-leading loading times with just a few simple steps. The performance plugin <a href="https://www.baqend.com/"><strong>Speed Kit</strong></a> was developed specifically for the acceleration of e-commerce websites. Speed Kit is based on innovative caching algorithms and is designed for websites of all sizes.</p><p>The installation of Speed Kit usually takes only a few hours. Speed Kit is integrated into the shop as a JavaScript code snippet and then runs in the user’s browser. Most shops benefit particularly from the fast delivery of HTML responses that often save a second of “dead time” and more. With these time savings in the Time to First Byte (TTFB), many shops are able to load as fast as the global top players. Images are automatically optimized and all data is stored in the browser cache and a distributed caching infrastructure for maximum performance.</p><p>As an example of how Speed Kit helps, check out <a href="https://drive.google.com/a/baqend.com/file/d/14Piyk8iQhDfFYuyG2jxK8s5KpohVIJsP/view?usp=sharing">this case study</a> for the world’s largest online sports retailers <strong>Decathlon:</strong></p><blockquote>The Baqend team has done an amazing job with Speed Kit and not only <strong>accelerated our site by 2.5x</strong>, but also been a <strong>reliable partner</strong> during the result analysis. There is no doubt about the <strong>great ROI</strong>. They have become a strategic part in our online growth plans.</blockquote><blockquote><strong>Florian Bischoff, Director E-Commerce, Decathlon Germany</strong></blockquote><p>Baqend provides Speed Kit as an <strong>immediate measure</strong> for online shops affected by COVID-19. <a href="https://www.baqend.com/covid-speed-offer-en/"><strong>Get in touch here</strong></a> to learn more and let us provide you with an offer and a performance assessment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ULn-Gl18d52Ri5ZCWUItVQ.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c4e210f0c0be" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/e-commerce-loading-times-in-the-covid-19-crisis-c4e210f0c0be">E-Commerce Loading Times in the COVID-19 Crisis</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Video: Mobile Site Speed and the Impact on E-Commerce]]></title>
            <link>https://medium.com/baqend-blog/video-mobile-site-speed-and-the-impact-on-e-commerce-a94709c01333?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/a94709c01333</guid>
            <category><![CDATA[user-experience]]></category>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[e-commerce-business]]></category>
            <category><![CDATA[revenue]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Sat, 07 Dec 2019 17:10:36 GMT</pubDate>
            <atom:updated>2019-12-07T17:13:13.517Z</atom:updated>
            <content:encoded><![CDATA[<p><em>A few weeks ago, we were at code.talks 2019 and presented the key insights of </em><a href="https://speedstudy.info/"><em>our web performance study with Google and the University of Hamburg</em></a><em>. Check out the video and abstract below to find out more.</em></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FRTt1RfMUvOQ%3Ffeature%3Doembed&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DRTt1RfMUvOQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FRTt1RfMUvOQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/88df58d05e49153b9d1834525be86f27/href">https://medium.com/media/88df58d05e49153b9d1834525be86f27/href</a></iframe><p>Last summer, the Google Speed Update made it official: If you don’t invest into mobile speed now, you will pay for it later — because poor mobile performance drags down your search rank. But how do you measure mobile web performance? What can you do to improve it? And when do you know you are making a dent? We will cover the gist of current research on mobile performance to find out what makes up a great mobile experience — and what you have to do to get there. First, we focus on user expectations to answer the question when they are most likely to engage or buy. We then assume the business perspective and explore the correlation between technical performance measures (TTFB, first paint, etc.) and pivotal business KPIs (e.g. conversion rates, bounce rates). Having thus established the business impact of web performance, we turn to the challenge of measuring it correctly. To this end, we highlight the differences between technical and user-centric metrics and then compare traditional synthetic performance tests, tracking, and log analysis with more advanced approaches like CRUX data analysis and real-user monitoring. As the main takeaway, we conclude with an overview of the most effective performance best-practices to increase web performance and drive up user engagement.</p><p>Check out <a href="https://speedstudy.info/"><strong>speedstudy.info</strong></a> to subscribe for new research on web performance — or if you want to join our study and <strong>boost your business</strong>!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kS564qlaCVzBv9628yRrxQ.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a94709c01333" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/video-mobile-site-speed-and-the-impact-on-e-commerce-a94709c01333">Video: Mobile Site Speed and the Impact on E-Commerce</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AppelrathCüpper]]></title>
            <link>https://medium.com/baqend-blog/appelrathc%C3%BCpper-c587f4c88ec?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/c587f4c88ec</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[progressive-web-app]]></category>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[e-commerce-business]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Mon, 11 Mar 2019 15:14:36 GMT</pubDate>
            <atom:updated>2019-04-23T18:54:26.679Z</atom:updated>
            <content:encoded><![CDATA[<h4>How Speed Kit Helps in Fashion E-Commerce</h4><blockquote><a href="https://www.baqend.com/speedkit.html">Speed Kit</a> provides an uplift of 3.9x in page load times and more than 50% in conversions for <a href="https://www.appelrath.com/">appelrath.com</a>.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V3p-XSwOeuN2b-k40Dl3BA.png" /></figure><h3>Problem</h3><p>With AppelrathCüpper, a success story that started 130 years ago, continues online. Through Speed Kit, AppelrathCüpper was able to bring its performance and user experience to a level that used to be exclusive to the large-scale market leaders. With the new level of page load times below one second, appelrath.com is the in the top tier of the best-performing online shops worldwide.</p><ul><li><strong>Challenge</strong>: delivering the best online user experience &amp; performance for a retail brand that has built over 100 years of trust and recognition.</li><li><strong>Approach</strong>: adding Speed Kit as a JavaScript tool to the existing OXID-based online shop for a fast and snappy experience across the site.</li><li><strong>Result I</strong>: 3.9x faster page loads</li><li><strong>Result II</strong>: 55% more conversions</li><li><strong>Result III</strong>: 16% longer session length</li></ul><blockquote>“Speed Kit does not only give us a 3.9x page speed <strong>boost you can feel</strong>, but a 55% conversion <strong>uplift we can measure</strong>.”</blockquote><blockquote>Jerrit Kube, Head of Digital &amp; Marketing, AppelrathCüpper</blockquote><h4>About AppelrathCüpper — From Stationary to E-Commerce</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/436/1*Ii5sOyLZTIGsNWKsnx6DQg.png" /></figure><p>Founded in the 19th century, AppelrathCüpper is one of Germany’s oldest fashion commerce labels and known for high-quality women clothing. <a href="https://www.appelrath.com/">Appelrath.com</a> was launched in 2015 in order to start the transition from purely stationary commerce to a 24/7 online business. Being in <strong>direct competition with big players</strong> like Zalando and Amazon, AppelrathCüpper’s goal is nothing less than transforming their well-trusted fashion retail brand into a leader in fashion e-commerce, too. To address this challenge on a technical level, Speed Kit comes into play.</p><h3>Technical Setup</h3><p><a href="https://www.appelrath.com/"><strong>Appelrath.com</strong></a> is running on OXID for its shop backend. Since AppelrathCüpper has the same high standards for their online business as for their products, they work with <a href="https://www.superreal.de/">Dept</a> (formerly Superreal) for building and operating their online shop. Dept is an international web development agency with more than 1000 experts in all fields related to online commerce, including marketing, design, and technical execution. With their expertise in e-commerce and as a Baqend partner, performance is something they take very seriously.</p><p>To bring user experience to the best possible state on a technical <strong>performance</strong> level, Speed Kit was chosen for appelrath.com as the solution for tackling page load time. <a href="https://www.baqend.com/speedkit.html"><strong>Speed Kit</strong></a> is a web performance insurance: added as a JavaScript snippet, it typically accelerates websites by more than 50%. With its automatic optimizations, Speed Kit improves the user experience, increases the conversion rate and SEO ranking, offloads the server, and dramatically reduces marketing costs through lower bounce rates.</p><p>As a first step, Dept analyzed by how much Speed Kit would accelerate appelrath.com. To this end, they used the <a href="https://test.speed-kit.com/"><strong>Page Speed Analyzer</strong></a>, a simple layer on top of the well-known <em>WebPagetest</em>. The Page Speed Analyzer accurately predicts the uplift achievable through Speed Kit by measuring and comparing (1) baseline performance of the website under test against (2) performance of the same site when loaded through Speed Kit. A few simple tests quickly showed that Speed Kit could provide a tremendous uplift across landing pages, product lists, and product detail pages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qec0A70uLcHSDfUP3ky8eA.png" /></figure><h3>Approach</h3><p>To obtain quick but sustainable results in performance, Dept decided to integrate Speed Kit into Appelrath.com. The process of accelerating the website is very simple:</p><ol><li>Speed Kit leverages the novel <strong>Service Worker</strong> browser technology. Speed Kit’s sw.js file is simply uploaded to the backend (in this case: OXID).</li><li>Speed Kit’s <strong>whitelist &amp; blacklist</strong> control which requests are accelerated and which ones are left untouched. On appelrath.com, Speed Kit delivers both first-party content (e.g. the HTML website itself) as well as slow third-parties (e.g. the Google tag manager).</li><li>Speed Kit keeps the site <strong>up-to-date</strong> automatically by checking for content changes frequently. In Speed Kit’s dashboard, the corresponding rules can be added and configured.</li><li>To speed up <strong>personalized content </strong>(e.g. the shopping cart and recommendations), a data attribute is added to elements in the page that might change based on users.</li><li>To <strong>activate </strong>Speed Kit, a JavaScript snippet is finally included into the site by adding it to the HTML template (a tag manager also works).</li></ol><p>With those 5 steps done, Speed Kit can be tested in a pre-production environment. The whole process took less than two developer days for AppelrathCüpper, Dept, and the Speed Kit team combined.</p><blockquote>“AppelrathCüpper shows how <strong>smooth Speed Kit integrations</strong> typically are: We used the basic setup for Appelrath.com, without any bells and whistles, and achieved incredible performance improvements <strong>out-of-the-box</strong>. Since the teams at AppelrathCüpper and Dept have been super-helpful and quick with their feedback, configuring Speed Kit only took us <strong>a few hours</strong>. All in all, we went from the initial tests to production in less than three weeks.”</blockquote><blockquote>Erik Witt, Head of Speed Kit Development</blockquote><h3>Test Methodology</h3><p>To quantify the performance uplift for real user of appelrath.com, a split test was conducted. Speed Kit natively supports A/B testing by capturing anonymized performance data from users browsing the site.</p><ul><li><strong>Group A </strong>(50% of users) used Speed Kit</li><li><strong>Group B</strong> (the other 50%) loaded the regular website without Speed Kit activating itself</li></ul><p>The raw performance data and the group information were sent to the scalable analytic systems of Baqend in realtime so that performance and conversions could be tracked. Then we all had to wait: usually, it takes a few days to obtain statistically significant results, since a sufficient amount of traffic and users have to be observed. But the empirical results quickly spoke for themselves…</p><h3>Results</h3><blockquote>“I have helped companies to understand and measure the immense <strong>ROI of web performance</strong> for over 10 years. However, the challenge for them has always been the implementation of web performance optimization. Today, I’m awestruck by how easy it is to achieve these huge ROIs using Speed Kit. Appelrath.com is the perfect example for why I joined Baqend: we disrupt the web performance market by delivering such unbelievable results and <strong>not just talking about it</strong>.”</blockquote><blockquote>Kristian Sköld, Chief Strategy Officer, Baqend</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DxFG9_ronxm8MG9bpdxgCQ.png" /></figure><p>As always for the initial analysis, we looked at the raw technical performance metrics for page load times (median values):</p><ul><li><strong>Server Response Time</strong> (time-to-first-byte from the backend):<br><strong>1200% Faster</strong> (3.25 s vs. 0.25 s)</li><li><strong>First paint</strong> (this is when the browser renders for the first time):<br><strong>387% Faster</strong> (3.65 s vs. 0.75 s)</li><li><strong>Time-to-interactive</strong> (this is when links can be clicked)<br><strong>305% Faster </strong>(3.85 s vs. 0.95 s)</li></ul><p>The perceived loading time of a website is captured well by the first paint which showed a <strong>3.9x improvement</strong> for the group of users with Speed Kit.</p><p>It is common knowledge that better performance leads to <strong>improved sales</strong>. In a famous A/B test, Amazon found that 100 ms of load time improvement translated to a 1% conversion rate improvement on their site. So the interesting question is: what is the actual conversion uplift on appelrath.com for real users?</p><p>This is exactly what Speed Kit tracks: the conversions and engagement of users surfing the site with Speed Kit.</p><ul><li><strong>Conversion Rate</strong> (share of user sessions during which something was bought):<br><strong>55% Higher</strong></li><li><strong>Engagement/Session Length </strong>(number of pages visited per user session):<br><strong>16% Higher</strong></li></ul><p>To <strong>validate the results</strong>, we turned to one of the largest independent parties: Google.</p><p>Ever since the “mobile speed update” announced for its ranking algorithm last summer, Google has declared war on slow websites — by ranking them down in search results. To make this downranking transparent, Google collects performance data from all Chrome browsers that captures the user-experienced page Speed. This data is made publicly available in the <a href="https://developers.google.com/web/tools/chrome-user-experience-report/"><strong>Chrome User Experience</strong> <strong>Report</strong></a><strong> </strong>(CRUX). While Google only tracks this data at the level of complete months and domains, it is a great tool to observe long-term performance trends.</p><p>So while it cannot replace a proper A/B test, we analyzed the CRUX data in order to answer the question: <strong>how does a month with Speed Kit compare to a month when Speed Kit was not active, yet?</strong></p><p>The <a href="https://en.wikipedia.org/wiki/Histogram">histogram</a> below illustrates the share of users experiencing a given page load time in a month with Speed Kit (blue) against a month without Speed Kit (orange): Since lower is better for page loads, it is best to have a huge spike on the left and a flat line to the right. As can be seen in the plot, most users with Speed Kit (blue) saw <strong>page load times below 1 s </strong>compared to 2–4 s for users without Speed Kit (orange).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zjouQDTN3t-Nha-vfOdK8A.png" /></figure><p>The CRUX data is particularly interesting, as Google has explicitly <a href="https://moz.com/blog/google-chrome-usage-data-measure-site-speed">admitted to use this data</a> for its ranking algorithm. This means that the obtained performance improvement also has a direct SEO impact.</p><h3>Outlook</h3><blockquote>“Performance is one of the most important topics for any e-commerce website right now. AppelrathCüpper showed how performance can be turned into a true <strong>differentiator in a market</strong> with an increasingly demanding user base. We are looking forward to a long and fruitful partnership — load times are already <strong>below one second on appelrath.com</strong> now, but we are only done when they have become imperceptible.”</blockquote><blockquote>— Felix Gessert, CEO, Baqend</blockquote><h4>The Team Behind Speed Kit</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/242/1*qshj8rHBnNEPySBAu57AiA.png" /></figure><p><a href="https://www.baqend.com/">Baqend</a> develops Speed Kit as a performance add-on that uses innovative caching algorithms to minimize loading times of e-commerce websites. This helps shops and brands to turn page speed into their competitive advantage. Baqend’s technology is already leveraged by more than 5000 websites such as Baur.de in the Otto Group. With a team of 15 people, Baqend’s goal is to deliver performance that feels instant for each of their customers’ websites.</p><p>There is also a <a href="https://medium.com/@Wolle/appelrathc%C3%BCpper-7378ac2213bb">German version</a> of this article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c587f4c88ec" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/appelrathc%C3%BCpper-c587f4c88ec">AppelrathCüpper</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[New-Generation Travel Websites Load 7 Times Faster Than Traditional Hotel Sites]]></title>
            <link>https://medium.com/baqend-blog/new-generation-travel-websites-load-7-times-faster-than-traditional-hotel-sites-d04ffebc5027?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/d04ffebc5027</guid>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[travel]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[performance]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Fri, 12 Jan 2018 14:34:38 GMT</pubDate>
            <atom:updated>2018-01-15T22:45:33.994Z</atom:updated>
            <content:encoded><![CDATA[<p>The festive season is just behind us and the new year has already begun. For many people, it is time to plan this year’s holidays. Numerous travel destination and accommodation sites are racing for their favor. <strong>Page speed</strong> has become a defining factor in this race, as over 40% of users abandon a site if it has not loaded within the<a href="https://www.akamai.com/de/de/about/news/press/2009-press/akamai-reveals-2-seconds-as-the-new-threshold-of-acceptability-for-ecommerce-web-page-response-times.jsp"> first three seconds</a>. According to The New York Times, even waiting just a little longer than the <a href="http://www.nytimes.com/2012/03/01/technology/impatient-web-users-flee-slow-loading-sites.html?pagewanted=all">blink of an eye</a> (just over 400 milliseconds) can cause unrest to users. At Baqend we are working on a faster web. We tested the 10 travel destination and accommodation sites with the highest market share in the US for their performance.</p><h4>Results</h4><p>Tech companies in the travel industry seem to take the issue seriously. The site of market share leader <strong>TripAdvisor</strong> loads within 0.7 seconds. Only <strong>Airbnb</strong> is faster, loading in under 0.5 seconds, thus coming close to the famous blink of an eye. This is particularly noteworthy, as the private rental site is over seven times faster than its rivals in the traditional hotel industry. Marriott International and Hilton Hotels Online are coming in last in the ranking and are the only two sites scoring over 3 seconds on the speed index with an average load time of 3.5 and 4.4 seconds, respectively.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UDlZz-lIM-EIDc3rN5kuxQ.jpeg" /></figure><h4>Conclusions</h4><p>Most of the travel sites we tested are quite fast and already performing at a high level. Especially the page load time of the frontrunners Airbnb and TripAdvisor are barely noticeable to users. This puts slower sites even more under pressure. Marriott and Hilton Hotels need to step up to avoid losing ground against the new generation of travel booking sites. With load times of over three seconds, they are losing a lot of customers before the site has even finished loading — potentially to faster competitors such as Airbnb.</p><h4>Methodology</h4><p>Baqend tested the 10 travel destination and booking websites with the most market share according to <a href="https://www.statista.com/statistics/265771/most-popular-travel-websites-in-the-us-based-on-market-share/">Statista</a> in November 2016. The test was conducted using the <a href="https://test.speed-kit.com/">Baqend Page Speed Analyzer</a> using the well-known <a href="https://www.webpagetest.org/">WebPageTest</a> suite. All sites were accessed from Washington DC. Baqend tested the performance metrics <a href="https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index">speed index</a> and <a href="https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint">time to first meaningful paint</a>. The provided data is averaged over 5 tests for each site.</p><h4>About</h4><p><a href="https://www.baqend.com/">Baqend</a> develops a cloud service that uses innovative caching algorithms to minimize loading times of websites. Publishers, shops, startups, and SMEs all face the challenge of competing with giants such as Amazon, Facebook, and Google. Baqend provides them with a technical platform to not only catch up with the market leaders but to turn page speed into their competitive advantage. Baqend’s <a href="https://www.baqend.com/speedkit.html">Speed Kit</a> is integrated into a website as a simple script to accelerate it by 50–300%. With <a href="https://www.baqend.com/platform.html">Baqend Platform</a>, new websites and mobile apps can be developed directly against a distributed cloud backend to achieve optimal performance right from the start. The mission of the research spin-off is to enable a web without loading times. Baqend is based in Hamburg, Germany.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d04ffebc5027" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/new-generation-travel-websites-load-7-times-faster-than-traditional-hotel-sites-d04ffebc5027">New-Generation Travel Websites Load 7 Times Faster Than Traditional Hotel Sites</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building Static Sites in 2017: Cloud-Hosted, CMS-Backed, and API-Driven]]></title>
            <link>https://medium.com/baqend-blog/building-static-sites-in-2017-cloud-hosted-cms-backed-and-api-driven-f68b5debc396?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/f68b5debc396</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[static-site]]></category>
            <category><![CDATA[cms]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Tue, 27 Jun 2017 09:50:06 GMT</pubDate>
            <atom:updated>2017-07-04T11:39:09.354Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this post, we survey modern static site generators and how they work with content management and APIs for dynamic data. As an example, we’ll develop a content site using Jekyll for templating, Jekyll Admin as a CMS and <a href="https://www.baqend.com/">Baqend</a>’s real-time API for syncing comments.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jPfyiktr54kTVD8QscNM3w.png" /></figure><h3>TL;DR</h3><p>Static sites provide an unmatched level of scalability and performance by completely avoiding an active backend. Modern static site generators such as Jekyll, Hugo and Hexo make it very easy to build static sites from template languages and largely technology-agnostic. For content-driven use cases like blogs and publishing sites, content management systems for editing static sites have evolved. And for the use cases that require integration of 3rd party services, data storage, and user management, Backend- and Function-as-a-Service APIs provide an option for implementing server-side logic with little code. This survey gives an overview of the<strong> static site technology</strong> stack that incorporates static site generation, content management and opt-in APIs for dynamic content. We will review the different approaches and walk through a real-world example of using the stack.</p><h3>Introduction</h3><p>Frontend, network, and backend performance used to be tough. But with the right technologies (e.g., CDNs, build tools, and HTTP/2) things are getting much easier (see our <a href="https://medium.baqend.com/hosting-lessons-learned-6010992eb257">survey</a>). However, most performance problems stem from single-node systems such as <strong>Wordpress </strong>or <strong>Magento</strong>. Both are based on server-side rendering and data storage in a single MySQL instance and are therefore notoriously hard to scale.</p><p>It’s not unusual for a Wordpress site to have a time-to-first-byte (TTFB) of 1–3 seconds. At the same time, 49% of users expect websites to load in <strong>2 seconds or less</strong>, according to a <a href="https://www.akamai.com/us/en/multimedia/documents/content/%20akamai-performance-matters-key-consumer-insights-ebook.pdf,">survey by Akamai</a>. And if that time is already spent for server-side rendering, there is little chance of hitting that performance goal. What makes it worse: Google uses the <a href="https://moz.com/blog/how-website-speed-actually-impacts-search-ranking">TTFB as a metric for their search ranking</a>.</p><p>The good news is: you can go from your existing Wordpress, Drupal, etc. to a fully static site that is still <strong>CMS-backed</strong>, as we’ll survey in this article.</p><h3>Going Static</h3><p><strong>Static sites </strong>have a significant advantage: They do not require server-side rendering or database queries, can be deployed virtually anywhere and are great for caching.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ExZH08Hcv09xCfUc16HNGQ.png" /><figcaption>Static Website Architecture</figcaption></figure><p><strong>Static site generators</strong> are great tools for building static sites that use rich templating in order to keep code clean and avoid duplication. They run on your local machine and compile a static site from a bunch of <strong>content files</strong> stored in your file system. The most popular ones are:</p><ul><li><a href="https://jekyllrb.com/"><strong>Jekyll </strong></a>(Ruby-based, 30132 Github Stars) is the most popular static site generator. It has a huge community, many plugins and great support for blogs.</li><li><a href="http://gohugo.io/"><strong>Hugo</strong></a><strong> </strong>(Go-based, 18057 Github Stars) excels in building speed: complete projects can be generated in milliseconds. It uses a single binary, making it easy to install for blogs and documentation.</li><li><a href="https://hexo.io/"><strong>Hexo </strong></a>(Node.js-based, 16875 Github Stars) is getting more and more popular as it fits nicely into the Node ecosystem and is easy to integrate with Octopress and Jekyll plugins.</li><li><a href="https://github.com/gatsbyjs"><strong>Gatsby</strong></a><strong> </strong>(Node.js-based, 10041 Github Stars) builds single-page application blogs based on React.js with reusable components.</li><li><a href="http://www.metalsmith.io/"><strong>Metalsmith</strong></a><strong> </strong>(Node.js-based, 5948 Github Stars) is very low-level and highly extensible, so with the right tweaking it can build almost any kind of website.</li><li><a href="http://gitbook.com/"><strong>GitBook</strong></a><strong> </strong>(JavaScript-based, 15605 Github Stars) publishes ebooks from markdown upon pushes to Github.</li><li><a href="http://www.mkdocs.org/"><strong>MkDocs</strong></a><strong> </strong>(Python-based, 4135 Github Stars) is a static site generator specifically made for building technical documentations from markdown.</li><li><a href="http://octopress.org/"><strong>Octopress</strong></a><strong> </strong>(Ruby-based, 1576 Github Stars) is a Jekyll fork particularly geared towards hackers.</li></ul><p>In our example, we will use <strong>Jekyll</strong>, which is the system that also powers <a href="http://jmcglone.com/guides/github-pages/">Github Pages</a>. In fact, it was created by Github co-founder Tom Preston-Werner back in 2008 as an engine for building static blogs. It is based on the <strong>Ruby </strong>toolchain and uses the <a href="https://shopify.github.io/liquid/"><strong>Liquid </strong>templating language</a>.</p><h3>Building a Jekyll-based Content Site</h3><p>What we’d like to build as an example is a simple content site where we maintain a repository of bachelor and master thesis topics for computer science students:</p><p><a href="https://thesis.app.baqend.com/">Themen</a></p><p>So here is how you build a Jekyll site:</p><ol><li>Do you have a static website? Then you already have a <strong>valid Jekyll project</strong>.</li><li><a href="https://jekyllrb.com/docs/installation/"><strong>Install </strong>Jekyll</a>. I’m running Windows, so what I did was: a) install the package manager <a href="https://chocolatey.org/install">Chocolatey</a>, b) install Ruby: choco install ruby -y c) install Jekyll: gem install jekyll</li><li>As I found Jekyll’s default theme a little boring, I opted for the nice-looking <strong>theme </strong>called <a href="https://github.com/mmistakes/minimal-mistakes">Minimal Mistakes</a>. Jekyll has a large ecosystem of <a href="http://jekyllthemes.org/">designs and boilerplate projects</a>.</li></ol><p>To use and extend the example setup of this article, check out the <a href="https://github.com/Baqend/thesis"><strong>Github</strong></a> project:</p><pre>git clone git@github.com:Baqend/thesis.git</pre><h4>Project Structure</h4><p>Here is what the Jekyll project structure looks like. The most important files and folders are:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/285/1*FZZbnxappuESfLxSsfcwWA.png" /></figure><ul><li>The<strong> _config.yml</strong> contains global configurations settings in the <a href="https://en.wikipedia.org/wiki/YAML">YAML</a> format, e.g. the site’s title</li><li><strong>_site </strong>contains the rendered static site</li><li><strong>_posts </strong>stores all the the blog-type content files and <strong>_pages </strong>the content for individual pages</li><li><strong>assets </strong>holds your images, videos, etc.</li><li>In <strong>_data, </strong>YAML data is shared across views, e.g. author information</li><li><strong>_layouts, _includes, _sass</strong> contain the design and templates</li></ul><p>The great thing about Jekyll is that it not only builds your static site, but also comes with a local, live-reloading server.</p><h4>Running Jekyll</h4><p>Let’s run the Jekyll <strong>live server</strong>:</p><pre>bundle exec jekyll serve</pre><p>The command will start a server on port 4000 that serves your current version.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d-TbELZXgWm1BFL6YwjrcQ.png" /></figure><h4>Adding Content Management</h4><p>The reason why many people use Wordpress, Drupal, Joomla etc. is that these frameworks are great for <strong>Content Management</strong>. Even unskilled users can easily create articles and landing pages using Wordpress. The good news is: There are Content Management Systems (CMS) for static sites, too. Let’s add <a href="https://github.com/jekyll/jekyll-admin"><strong>Jekyll Admin</strong></a> to the project.</p><p>To add a Jekyll plugin, the Gemfile is extended, which is Ruby’s equivalents to Node’s package.json: gem &#39;jekyll-admin&#39;, group::jekyll_plugins</p><p>Append <em>/admin</em> to the URL and you have your CMS:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e-a0XF46S9NhwFFcKwinig.png" /><figcaption>Jekyll Admin CMS Interface</figcaption></figure><p>Jekyll is based on <strong>Markdown</strong>. When you create a post in the CMS, it will simply create a <em>&lt;post&gt;.md </em>file in your <em>_posts</em> folder.</p><p>Let’s walk through how Jekyll works, indepedent from how content is managed. The upper portion in a content file is called <strong>front matter</strong>. It contains (YAML) metadata used in the template, for example, tags of the post. The body will be rendered from markdown.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1gCTYpYHfbwphmNcLwWpAQ.png" /></figure><p>We specified to use the <strong>layout</strong> <em>single </em>which will use the Liquid templating engine to render to HTML:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QRmxvPNoH06YI14-XQcdfw.png" /></figure><p>This uses the<em>&lt;post&gt;.md </em>files’s<em> </em>front matter and body to output the static HTML page. For example, to add the post’s title, render markdown, and strip HTML and line breaks, we can use a Liquid variable and pipe it through helpers:</p><pre>{{ page.title | markdownify | strip_html | strip_newlines }}</pre><p>Adding <strong>media </strong>can be done by using the <em>Static Files</em> section in Jekyll Admin or by copying files into your asset folder. You can then reference them from you markdown to include them.</p><p>Liquid (developed by Shopify) does not allow any code in the template, so if more advanced logic is required, you need to create helper classes.</p><p>Jekyll Admin is also not the only CMS for Jekyll. For example, <a href="https://forestry.io/%20Cloudcannon">Forestry</a> and <a href="http://cloudcannon.com/">Cloudcannon</a> are SaaS solutions for doing static content management on top of Jekyll.</p><h4>Building the Jekyll Site</h4><p>Time to output a rendered site:</p><pre>bundle exec jekyll build</pre><p>This will put a deployable version into the <em>_site</em> folder. It uses many subfolders with containing an index.html to allow pretty navigation and permalinks. The _site folder can be deployed to almost any platform, for example, an Nginx Webserver or Amazon S3.</p><h4>Deploying and Hosting the Static Site</h4><p>Now, we simply have to upload the Jekyll project. Baqend has CDN-backed file hosting with automatic cache invalidation so let’s upload it there. All we need is the Baqend CLI, which can be installed from <a href="https://www.npmjs.com/package/baqend">npm</a> (alternatively you could also drag &amp; drop the files in the dashboard).</p><pre><strong>npm install -g baqend</strong> #install CLI</pre><pre><strong>baqend register</strong> #create a new app backend</pre><pre><strong>bundle exec jekyll build</strong> #build the Jekyll project</pre><pre><strong>baqend deploy -f _site thesis</strong> #deploy the _site folder to Baqend</pre><pre><strong>baqend open thesis </strong>#open the deployed site in the browser</pre><h3>Adding APIs to Jekyll: Real-Time User Comments</h3><p>The limitation of any static site is, of course, <strong>user-generated content</strong> (e.g., comments) and <strong>protected business logic</strong> (e.g., a shop checkout). This is where APIs of third-party services come into play, for exmaple, Disqus for comments, or Facebook for social data. If more backend logic is required, <strong>serverless </strong>architectures are the paradigm of choice: The frontend orchestrates different services (e.g., Paypal, Disqus, AWS Lambda) and contains most of the business logic.</p><p>What we want to have for our example, is a customizable comment section, where users can <strong>post comments</strong> and see any new comments from others users in <strong>real-time</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*aKEIrpk8MlFG2fZ-zYUCig.gif" /></figure><h4>Storing Data from Jekyll</h4><p>Combining Jekyll with <strong>JavaScript APIs</strong> is very powerful. You can use Jekyll to generate page information into your scripts and handle input data dynamically:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lS2s6W1D9BdFykgBuVp5iw.png" /></figure><p>Therefore, let’s look at how we can use a Backend-as-a-Service to store and query data from Jekyll.</p><p><strong>Backend-as-a-Service</strong> systems are designed to make serverless development easy, by having server-side code execution combined with standard APIs for things such as:</p><ul><li><strong>Registering</strong> and <strong>logging in</strong> users</li><li>Running scalable, <strong>server-side business logic</strong> (<em>Function-as-a-Service</em>)</li><li>Giving access to a <strong>database-(as-a-service)</strong></li><li><strong>Authorizing</strong> users and protecting content</li><li>Sending <strong>push notifications</strong> and performing <strong>synchronization</strong></li><li>Hosting and delivering <strong>files</strong></li></ul><p>We are building <a href="https://www.baqend.com/">Baqend</a>, which is Backend-as-a-Service geared towards web performance. Baqend is a spin-off from database research and heavily based on <a href="https://medium.baqend.com/how-to-develop-a-backend-as-a-service-from-scratch-lessons-learned-a9fac618c2ce">caching algorithms</a>.</p><p>Let’s add a <strong>commenting system</strong> to our static site using a Backend-as-a-Service. In order to display and post comments we have to do three things:</p><ol><li>Set up a<strong> data model</strong> of how to store comments in our backend.</li><li><strong>Save a comment</strong>, when the comment form is submitted.</li><li><strong>Sync the comments</strong> of a post across browsers in real-time.</li></ol><h4>Setting up the Data Model</h4><p>Configuring the data model is extremely simple. Just head of to the dashboard of your <a href="https://dashboard.baqend.com/register?_ga=2.4100272.185221066.1498471928-1170005436.1469980676">Baqend <strong>App</strong></a>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XTdMxc5U8unxRfFw83ktBQ.png" /></figure><p>Now, expand the <strong>Data Section</strong> and hit <strong>+ </strong>to create a new model. Let’s give it just a few String properties to store the poster, the (markdown) message, and the page (slug). A <em>created_at</em> and <em>updated_at </em>property are maintained automatically.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*52_-6e06y6fYZYp_-faa5g.png" /></figure><p>That’s it. We can now save comments. To try it, let’s open the data tab and <strong>add a few comments</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6SSsSyh3Wp2hrt0-tTnIEw.png" /></figure><h4>Saving Comments from the Static Site</h4><p>Now let’s head back to our Jekyll project and add the code to post a comment in the <em>custom.html</em> file for custom comment handling.</p><p>First, let’s include the Baqend <strong>SDK </strong>and library for rendering Markdown and connect to our app. This will transparently download the schema and caching information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nn3M1TqAD83jeMevnSViBA.png" /></figure><p>Now let’s add the (plain old jQuery) code to take input from the comment form and <strong>save it as a new object</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*B8_lYnBm5qro-VYP7e26Mw.png" /></figure><p>Here we use the Liquid templating syntax with {{ page.slug }} to generate the current page id into the script on each post. The save() call simply inserts the new object over the REST API.</p><h4>Querying and Syncing Comments</h4><p>Now that we have the data in the database, we need to query it. There are two ways to do this:</p><ul><li>A standard, <a href="https://www.baqend.com/guide/topics/queries/"><strong>pull-based query</strong></a> fetches data from the database and allows us to render it in the client (with jQuery, React, Angular, etc.).</li><li>With a real-time query, we establish a websocket connection to the server, perform a full-fledged MongoDB query and receive any updates to the result set in real-time. We call this a <a href="https://www.baqend.com/guide/topics/realtime/#real-time-queries"><strong>self-maintaing query</strong></a>.</li></ul><p>The great thing is: Both look exactly the same in the code and are very easy to handle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MQjqzRWmS0eA9CuinDs-8g.png" /></figure><p>So as soon as we are connected (DB.ready callback), we use the query builder to retrieve comments for the current page, order them by creation date and call our UI-handler each time the set of comments is changed (e.g. a comment is inserted, removed, updated etc.).</p><p>And that’s it: Now we have our realtime-capable comment system that we can customize and extend however we like, while still having the abilities and simplcity of Jekyll for creating and content and generating the site.</p><p>Let’s deploy the commenting logic:</p><pre><strong>bundle exec jekyll build; baqend deploy -f _site</strong></pre><p>So there it is: our static website, with a local CMS, and APIs for on-demand dynamic functionalities. If you look at the developer console you can see comment updates coming in via <strong>websockets</strong> and static data being loaded via <strong>HTTP/2</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G5kREZrQ-pESWuYq2G4RbA.png" /></figure><p>You can also configure your <a href="https://www.baqend.com/guide/topics/hosting/#custom-domains"><strong>custom domain</strong></a> in the dashboard and let Baqend provision the SSL certificates for HTTP/2. By default you have an &lt;app&gt;.app.baqend.com domain that is already SSL-protected.</p><h4>Securing Access</h4><p>There is one last thing: we do not want to allow everyone to delete or update other people’s comments. So let’s secure the app by adding a <strong>schema ACL</strong> to only allow inserts and queries. You can do this in the ACL tab:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R1vZqPOnhwLN5MpIwsyF1Q.png" /></figure><p>The last question is: How can we <strong>scale this project</strong> across many developers and many content editors?</p><h4>Collaborating on a Static Site Project</h4><p>Since a static website has all its context in the file system, sharing it is very easy. Content editors need to have Jekyll installed to use the Jekyll Admin CMS UI and they also need some way of sharing content files. The two wide-spread mechanisms to share the static project are:</p><ul><li><strong>Share the project folder</strong> via Dropbox, Google Drive, etc. This has the advantage of being very easy for non-technical users. However, there is no proper versioning, rollbacks, commits, etc.</li><li><strong>Using Git</strong> with Github, Gitlab, etc. For obvious reasons, this is usually the preferred choice for developers and tech-savvy users.</li></ul><p>The Baqend/API part is also easy to share, as you can simply add developers to the app. Each of the collaborating developers can edit the data model, view data, deploy the site, etc. Throug <strong>build tools</strong> (e.g., Gulp, Grunt, Webpack, npm scripts), the building, staging and deploying of the site can be made very accessible.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2W74RXUUyTvLDBVECGYJyA.png" /></figure><h4>Migrating to Jekyll from Another Project or CMS</h4><p>If you already have a static site project, you can simply start using the jekyll commad line for static site generation. You can simply embed Liquid templates in your HTML e.g.,{{page.title}}.</p><p>If you are coming from another CMS, Jekyll has <a href="http://import.jekyllrb.com/docs/home/"><strong>importers</strong></a><strong> </strong>that generate markdown files in your <em>_posts</em> folders. This works for Behance, Blogger, CSV, Drupal 6, Drupal 7, EasyBlog, Enki, Ghost, Google Reader, Joomla, Joomla 3, Jrnl, Marley, Mephisto, Movable Type, Posterous, RSS, S9Y, S9Y Database, Textpattern, Third-party, Tumblr, Typo, WordPress, WordPress.com.</p><p>For example, say you already have a Wordpress blog. Simply run this locally, to pull content data from Wordpress’s MySQL:</p><pre>ruby -rubygems -e &#39;require &quot;jekyll-import&quot;; JekyllImport::Importers::WordPress.run({})&#39;</pre><p>That will import <strong>posts </strong>and <strong>pages</strong>. You can then use them in any of the numerous Jekyll themes or build a new frontend.</p><h4>Resources on Static Site Generators</h4><p>To learn more about static site generators, have a look at these:</p><ul><li>A detailed blog post: <a href="https://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/">Static Site Generators Reviewed: Jekyll, Middleman, Roots, Hugo — Smashing Magazine</a></li><li>A free <a href="http://www.oreilly.com/web-platform/free/static-site-generators.csp">O’Reilly book on Static Site Generators</a> and a longer version as a <a href="http://shop.oreilly.com/product/0636920051879.do#tab_04_2">regular O’Reilly book released in March 2017</a></li><li>Another long-form <a href="https://www.smashingmagazine.com/2016/08/using-a-static-site-generator-at-scale-lessons-learned/">post on running static site generators at scale</a></li><li>This nice <a href="https://www.youtube.com/watch?v=_cuZcnJIjls">talk “Static Sites go all Hollywood” by Phil Hawksworth on Youtube</a></li></ul><h3>Summary</h3><p>The message of this post is: Static websites are much more flexible than their name indicates and inherently scalable. They can be combined with content management systems for creating posts and pages and with cloud APIs for handling non-static concerns like comments, payment, and user login.</p><p>The stack we proposed in the example project uses three central technologies:</p><ul><li><a href="http://jekyllrb.com/"><strong>Jekyll</strong></a> as a versatile static site generator with rich templating.</li><li><a href="https://github.com/jekyll/jekyll-admin"><strong>Jekyll Admin</strong></a> as a dead-simple local CMS.</li><li><a href="https://www.baqend.com/"><strong>Baqend</strong></a> for storing and querying data and hosting the site.</li></ul><p>To use and see the stack in action, simply clone the example project from<a href="https://github.com/Baqend/thesis"> this Github repo</a>.</p><p>Don’t want to miss our next post on building static websites? Get it conveniently delivered to your inbox by joining our <a href="http://www.baqend.com/#newsletter">newsletter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f68b5debc396" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/building-static-sites-in-2017-cloud-hosted-cms-backed-and-api-driven-f68b5debc396">Building Static Sites in 2017: Cloud-Hosted, CMS-Backed, and API-Driven</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Lessons Learned Building a Backend-as-a-Service: A Technical Deep Dive]]></title>
            <link>https://medium.com/baqend-blog/how-to-develop-a-backend-as-a-service-from-scratch-lessons-learned-a9fac618c2ce?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/a9fac618c2ce</guid>
            <category><![CDATA[baas]]></category>
            <category><![CDATA[scalability]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Wed, 17 May 2017 13:42:42 GMT</pubDate>
            <atom:updated>2017-06-20T11:09:14.717Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this post we share our technical learnings from building a multi-tenant Backend-as-a-Service (BaaS). We cover how a BaaS works, how it fits into the serverless paradigm and how performance and scalability can be achieved with tools such as Docker Swarm, MongoDB, AWS, Redis, Varnish and CDNs.</h4><h3>TL;DR</h3><p>At <a href="https://www.baqend.com/">Baqend</a>, we are building a Backend-as-a-Service (BaaS) service that is geared towards scalability and web performance. Coming from <a href="https://www.baqend.com/#final-remark">research</a>, we try to be open about the architecture of our platform and therefore would love to share how everything works at a technical level. This post is a combined writeup of different talks we gave.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wG58WkQdRBvH0WAhhW40rg.png" /></figure><h3>Challenges of Modern Applications</h3><p>Engaging web and mobile applications have to fulfill several requirements:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eiO92eLtIuL2blUJO7Fe8Q.png" /></figure><p>Each one individually may appear easy, but achieving them in combination turns out to be quite difficult in practice.</p><blockquote>“Over 30 percent of web development teams deliver projects late or over-budget.” (<em>Survey by New Bamboo)</em></blockquote><h4>The Classic 3-Tier Architecture</h4><p>Today, the most common way of implementing web applications is a 3-tier architecture with a client, a server and a database tier. This design poses some difficulties regarding the requirements:</p><ul><li>A typical website consists of more than <strong>100 resources</strong> fetched from the server, which makes <strong>latency </strong>critical for performance (see <a href="http://httparchive.org/">HTTP archive</a>).</li><li>With <strong>server-rendering</strong>, the client has to wait until the server has assembled the data through database queries and <strong>rendered </strong>it in a language such as Java, PHP or Python.</li><li>The database must be <strong>highly available</strong>, which is extremely difficult if you also like consistency, according to <a href="https://medium.baqend.com/nosql-databases-a-survey-and-decision-guidance-ea7823a822d">the CAP theorem</a>.</li><li>The server needs to be <strong>scalable</strong>, which is difficult when shared state such as user sessions are involved.</li><li>In many cases, <strong>business logic</strong> is duplicated between the client and server, as well as communication overhead between frontend and backend teams, making projects more difficult and delaying the time-to-market.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aY26EPyZTT6upCYXrieNhQ.png" /></figure><h4>2-Tier Architectures to the Rescue</h4><p>An alternative to the 3-tier architecture is to leave out the server tier and talk directly to a cloud service, e.g. a Database-as-a-Service (DBaaS). This has two major advantages:</p><ul><li>You can <strong>render the site progressively</strong> in the client to make the UX interactive and enganging.</li><li>Much of the business logic can happen in <strong>client-side JavaScript, </strong>i.e. you get less hassle between backend and frontend team.</li></ul><p>While there are good frameworks and technologies for building these application frontends (e.g. Angular and React) and storing the data (e.g. DynamoDB, or MongoDB hosters), some problems remain:</p><ul><li>You still have to do <strong>many latency-sensitive requests</strong>, somestimes even more than before, since data comes in small, separate JSON requests.</li><li>All the heavy lifting involved with <strong>scalability and high availability</strong> is now shifted to the Database-as-a-Service.</li><li>Cloud databases are usually not equipped to handle <strong>User Management, Access Control, Server-side Business Logic.</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gQL2h_dgk0uGCnntGp24tw.png" /></figure><h4>The Serverless Paradigm</h4><p>The two common forms of serverless architectures are Function-as-a-Service (e.g. AWS Lambda, Google Cloud Functions) and Backend-as-a-Service (e.g. Baqend, Firebase).</p><p>The great thing about <strong>Function-as-a-Service (FaaS)</strong> is that the business logic hosted there, e.g. in the form of a Node.js script, is rapidly scalable and easy to operate. However, FaaS only covers stateless code execution which means that you have to orchestrate different cloud services to handle data storage, user management, push notifications, etc. Thus, the client has to talk to many different APIs. Or the FaaS has to wrap and expose various services, which quickly becomes infeasible to manage.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ix3L4aKzAdBJAHA6d70Ocw.png" /></figure><p>This is where <strong>Backend-as-a-Service (BaaS) </strong>enters the stage: the idea is to combine the easiness of Function-as-a-Service with all the APIs and capabilities a typical website or mobile app requires.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ebxv4WVRzx_pElKLiGxA9g.png" /></figure><h3>How a BaaS Works</h3><p>Any BaaS will typically be composed of three layers.</p><p>The <strong>API </strong>is what makes the BaaS useful, as it allows to store and query data, run server-side code, authenticate users, and more. This is usually implemented as a multi-tenant cloud service on an Infrastructure-as-a-Service (IaaS) provider such as AWS.</p><p>A BaaS also takes care of <strong>hosting and delivery</strong>. In case of web applications, this means that it will store your HTML files and other assets and deliver them to users.</p><p>As a developer, build your website or mobile app using either a <strong>REST API or an SDK</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qUgPeI9Q_5AChC4dl4U-7Q.png" /><figcaption>Components of a Backend-as-a-Service platform.</figcaption></figure><p>Let’s look at how a BaaS-backed website works.</p><ol><li>First, the browser will load the <strong>HTML and the assets</strong>, including your JavaScript application logic written in the framework-of-the-month (Angular, React, Vue, Aurelia, …).</li><li>Next, your <strong>JavaScript </strong>will make calls using the BaaS SDK to load the data and render the site, e.g. by fetching the latest posts.</li><li>The browser will resolve any further references like <strong>images </strong>that were inserted into the DOM.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ko5PxttdygTGGPL7UDo13w.png" /></figure><h3>How is BaaS different from PaaS and IaaS?</h3><p>BaaS basically pulls up the <em>abstraction level</em>, so as a developer you do not need to manage a full-blown application and database stack. PaaS gives you full control over the server, e.g. your Rails or Django application. In an IaaS, you can basically run any kind of application but it leaves you with the full complexity of manging and scaling it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ukHkdXd4l9nBrt8yvQ3zEQ.png" /></figure><p>The high abstraction layer of BaaS often comes at a cost: <strong>performance, expressiveness and scalability </strong>are usually quite limited. But this does not have to be the case. Let’s look at how to actually build a BaaS.</p><h3>Performance</h3><p>I bet everyone of us has stared at blank loading screens and cursed whoever is responsible for that.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VWE5LhyeLTVSDWRffyTVpQ.png" /></figure><p>49% of users expect websites to load in <strong>2 seconds or less</strong>, according to a <a href="https://www.akamai.com/us/en/multimedia/documents/content/%20akamai-performance-matters-key-consumer-insights-ebook.pdf,">survey by Akamai</a>. These expectations are not matched in practice: the median top 500 e-commerce website has a page load time of 9.3 seconds (see <a href="https://blog.radware.com/applicationdelivery/applicationaccelerationoptimization/2014/02/report-sotu-for-ecommerce-page-speed-web-performance-winter-2013-14/">source</a>).</p><p>My three favourite findings relating web performance to user behaviour are these (there are <a href="http://www.soasta.com/wp-content/uploads/2015/09/Time_Is_Money_Preview_Ed_SOASTA.pdf">many more</a>):</p><ul><li><strong>Amazon </strong>found that 100 ms of additional loading time decrease sales revenue by 1%. With Amazon’s current revenue, the impact is over 1 billion USD per year.</li><li><strong>Yahoo!</strong> saw 9% of visitors dropping out, when the site was 400ms slower.</li><li>When comparing user reactions to showing 30 search results instead of 10 , <strong>Google</strong> measured a 20% drop in traffic. The decrease in engagement was caused by 500ms of additional latency for the search query.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CORURWRlyFoPFqVm7E6ENw.png" /></figure><h4>What makes websites slow?</h4><p>Let’s say a user from the US visits our BaaS-backed application hosted in Europe. There are two performance bottlenecks:</p><ol><li>The server has to do database queries, rendering, etc. which causes <strong>processing overhead</strong>.</li><li>We need to transfer more than 100 resources over a <strong>high-latency network connection</strong>, delaying the moment where the browser has enough data to show something meaningful.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*q1gFBczNylO2AZblQo43uQ.png" /></figure><p>Interestingly, bandwidth is usally not the bottleneck. If you observe page load time under increasing bandwidth, you’ll notice that it doesn’t get <strong>any faster above 5 Mbps</strong>. However, if you are able to decrease access latency, you will see a proportional decrease in page load time.</p><p>Or put differently:</p><blockquote><strong>2× Bandwidth</strong> <strong>= </strong>Same Load Time<br><strong>½ Latency</strong> <strong>≈</strong> ½ Load Time</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*4LN2bqPCNC9pgZDP6ji_UQ.png" /><figcaption>The effect of bandwidth vs. latency on page load time. See <a href="https://hpbn.co/primer-on-web-performance/">source</a>.</figcaption></figure><h4>State of the Art: How to improve web performance?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/1*cWmiy3w13mYxUANPgGCmOA.png" /></figure><p>Let’s look at one example of how web performance can be improved: <strong>Google‘s </strong><a href="https://www.ampproject.org/"><strong>Accelerated Mobile Pages</strong></a><strong> (AMP)</strong>.</p><p>In a nutshell, AMP prescribes the following:</p><ul><li><strong>Stripped down </strong>HTML + AMP tags (e.g. <em>amp-img</em>) rendered asynchronously by AMP JS runtime</li><li>CSS must be <strong>inlined and below 50 KB</strong></li><li>No <strong>custom JS </strong>(except in iframes)</li><li>Only static sizes for DOM elements → <strong>no repaints</strong></li><li>Limited to <strong>mobile pages</strong> and forces a Google bar</li><li><strong>Cached</strong> in Google CDN, as long as it is crawled the next time<br> → only suited for <strong>static</strong> media, e.g. news</li></ul><p>So the basic idea of AMP is to enforce performance best pratices and use CDN caching. However, there is no reason to limit these techniques to proprietary Google technology with uncertain motiviations.</p><h4><strong>Tackling latency</strong></h4><p>So we know that we have to reduce latency in order to be fast. What is the oldest technique to achieve that? <strong>Caching</strong>!</p><p>This is the main idea behind the Baqend BaaS: reducing latency through web caching. And since interesting applications do not only use static data, we have to make <strong>dynamic data cacheable</strong>.</p><p>If you can cache dynamic data, you get two things:</p><ul><li><strong>Low Latency</strong>, since every request can be answered by a nearby web cache (e.g. your browser cache or a CDN edge node)</li><li><strong>Less Processing</strong> overhead in the backend, as only the cache misses will hit the server</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V6qZsgK4OoErZS5tB3JZxA.png" /></figure><h4>How to cache dynamic content?</h4><p>The idea is quite simple. We have to keep track of every response and invalidate it upon changes in both <strong>expiration-based caches</strong> (e.g. the browser cache) and <strong>invalidation-based caches</strong> (e.g. CDNs like Akamai and Fastly).</p><p>As expiration-based caches simply use the <strong>time-to-live</strong> provided in the server’s Cache-Control HTTP header, we have to use a trick: we let the client know, when something needs to be revalidated. As the full list of stale URLs can get quite, long we compress it using <a href="https://en.wikipedia.org/wiki/Bloom_filter"><strong>Bloom filters</strong></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rOnw4xo7c91ATy_4wye0Fg.png" /></figure><p>The concrete algorithms to handle this are not some secret sauce, it is all <a href="https://vsis-www.informatik.uni-hamburg.de/vsis/members/look/1264">published research</a>. Here is how it works.</p><h4>Caching everything, not just assets</h4><p>The tricky thing when using web caches is that you must specify a time-to-live (TTL) when you first deliver the data from the server. After that you do not have any chance to kick the data out. It will be served by the browser cache up to the moment the TTL expires. For static assets, it is not such a complex thing, since they usually only change when you deploy a new version of your web application. Therefore, you can use tools like <a href="https://github.com/smysnk/gulp-rev-all">gulp-rev-all</a> and <a href="https://github.com/yeoman/grunt-filerev">grunt-filerev</a> to hash the assets. By renaming the assets at deployment time, you ensure that all users will see the latest version of your page while using caches at their best.</p><p>But wait! What do you do with all the data which is loaded and changed by your application at runtime? Changing user profiles, updating a post or adding a new comment are seemingly impossible to combine with the browsers cache, since you cannot estimate when such updates will happen in the future. Therefore, caching is usually just disabled or very low TTLs are used.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HxPC9Xw4DDzpnsbWGxxJPg.png" /></figure><h4>The Bloom filter trick</h4><p>We need to check the staleness of any data before we actually fetch them. At the begin of each user session, the connectcall therefore fetches a Bloom filter, which is a highly compressed representation of all recently changed resources. Before making a request, the SDK first checks the Bloom filter to know if it contains an entry for the resource we fetch.</p><p>An entry in the Bloom filter indicates that the content was changed in the near past and that the content may be stale. In such cases the SDK bypasses the browser cache and fetches the content from the nearest CDN edge server. In all other cases the content is served directly from the browsers cache. Using the browser cache saves network traffic, bandwidth and is rocket-fast.</p><p>In addition, we ensure that the CDN always contains the most recent data, by instantly purging data when it becomes stale.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N-ssExu65YTwWpbcuehq8w.png" /></figure><h4>How useful and fast is this in practice?</h4><p>Here is a small example of the effects using a simple news application as an <a href="https://github.com/Baqend/news-benchmark">open-source benchmark</a>. You can also run it <a href="http://benchmark.baqend.com/">in your browser</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6RqiyySl74lmmtbOjMPCkg.png" /></figure><p>This means: caching dynamic content leads to a performance advantage of roughly <strong>15x</strong>. If you want to learn how this work’s for real applications, check out our findings from a high-traffic e-commerce scenario:</p><p><a href="https://medium.baqend.com/building-a-shop-with-sub-second-page-loads-lessons-learned-4bb1be3ed07">Building a Shop with Sub-Second Page Loads: Lessons Learned</a></p><h4>Optimizing the Network</h4><p>We’ve seen that caching optimizes latency. But there are more networking topics to take care of.</p><p>Baqend uses a CDN (<a href="https://www.fastly.com/">Fastly</a>) to improve several networking aspects:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NgKm5NrqGuwFZnp7ifatqA.png" /></figure><p>Arguably the most important optimization is HTTP/2. For a typical use case and in particular combined with caching, it can improve performance drastically:</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*HH2lLsrrrFdTxrESgWYLYw.png" /></figure><p>HTTP/2 does three important things better than HTTP/1.1:</p><ol><li><strong>Multiplexing</strong> requests over one single TCP connection (no head-of-line blocking)</li><li>Server <strong>Push </strong>allows you to send data before the user requests it</li><li><strong>Header Compression </strong>saves bandwidth, e.g. for repeatedly sent cookies</li></ol><h4>BaaS Performance: Summary</h4><p>So in a nutshell, Baqend does two things to tackle the web performance problem:</p><ul><li>Latency is reduced by <strong>caching dynamic content</strong> (e.g. queries).</li><li>Using <strong>HTTP/2</strong> and <strong>CDN delivery</strong>, data is transferred faster.</li></ul><h3>Scaling a Backend-as-a-Service</h3><p>How can we scale the backend? There are a few performance best practices that any scalable backend should address:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KRbBNjI_3dF0Iym8agCYBQ.png" /></figure><p>This is how <a href="https://www.baqend.com/">Baqend Cloud</a> implements these:</p><ul><li>Data is stored in a set of different scalable <strong>NoSQL databases </strong>(MongoDB, Redis, ElasticSearch), depending on what data store suits the application best.</li><li>Java-based Baqend <strong>servers</strong> expose the BaaS REST API and can be scaled independently. Each tenant has its own server and a Node.js instance for running server-side business logic. This pair of servers is hosted on Docker and is scaled using Docker Swarm by adding more containers per tenant on demand.</li><li>All types of <strong>web cache</strong> (reverse-proxy caches, CDNs, ISP caches, forward proxies and browser caches) are allowed to cache the responses.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DYzBKBg8LISJ4jYQ5KF9OA.png" /></figure><h4>Scalability &amp; Performance Wrap-up</h4><p>All in all, there are some things that Baqend can optimize and there things that you as a developer need to take care of:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pWLwLNjr9chZTEdbq_qhzA.png" /></figure><h3>How do I use a BaaS from a development perspective?</h3><p>To add Baqend to an application, you just include the SDK and connect it to your app. Then you can start loading and storing data:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1Wu3DDx9oU9PQg4mGg-YyQ.png" /></figure><p>The three major interfaces you will be using with any BaaS is usally the Service <strong>Dashboard</strong>, the <strong>CLI</strong> and the <strong>SDK</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9vs3XH_Dq11vm-KSywHOyg.png" /></figure><p>The <a href="https://www.baqend.com/guide/">Baqend SDK</a> is compatible with all major frameworks and also works for hybrid apps and in Node.js. Besides wrapping the REST API, the SDK does a few useful things:</p><ul><li>Abstracts from <strong>caching</strong> logic, and has an intelligent <strong>object-identity</strong></li><li>Completely <strong>ES6</strong>- and <strong>TypeScript</strong>-compatible (support for Maps, Sets, Arrays, models can be ES6-classes)</li><li><strong>Promise</strong>-based</li><li>Powerful<strong> query builder </strong>for doing search &amp; retrieval of data</li><li>Automatic <strong>change-</strong> and <strong>dependency-Tracking, </strong>so objects are only sent to the server when they actually change</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sBjz5cAR8Bh6YSyxl6LvJA.png" /></figure><h4>Data Modeling</h4><p>Baqend combines schemaful and schemaless data modelling: you can use and check data types wherever you need strict validation and fallback to plain JSON, where the structure is not known in advance.</p><ul><li><strong>Types</strong>: Boolean, Integer, String, DateTime, Time, Date, GeoPoint, List, Map, Set, JSON-Object, JSON-Array</li><li><strong>Files, references, embedded</strong> types &amp; <strong>inheritance</strong></li></ul><p>Documents can be nested or have references to other objects. Each field can be indexed and efficiently queried, even nested documents and schemaless JSON.</p><p>For example, when building a todo list, you can choose between <strong>embedding </strong>and <strong>referencing </strong>depending on whether query or update performance is more important and what the access patterns look like.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/1*OIBnWzs-Ft1tVmtNtmxZLw.png" /></figure><p>The CRUD API makes it very easy to interact with objects and files.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rk4vuxTwPYzxrCNl1bDJzA.png" /></figure><p>Every request issued from the SDK is mapped to the REST API and automatically uses the client-side Bloom filter-logic and the server-side cache invalidations:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x6Fro_spHyh53zXFNPoFQg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*BTxUdzSy84iZRCAckRUCvw.png" /></figure><p>The REST API is specified using <a href="https://dashboard.baqend.com/swagger-ui/?url=https%3A%2F%2Ftoodle-bq.global.ssl.fastly.net%2Fv1%2Fspec&amp;_ga=2.155943987.980756354.1494415275-1170005436.1469980676">Swagger</a>, which also makes it browsable and allows to generate simple SDKs for other languages.</p><p>The server exposing the REST API is built in Java and Jetty. It is highly tuned towards throughput and latency efficiency: a single server can handle roughly 15K requests per second on commodity cloud hardware.</p><h4>User Management</h4><p>There are simple APIs to handle users of your application. Users can be registered using classic email validation or through OAuth providers like Facebook or Google.</p><p>User can have <strong>roles. Acess rights</strong> can be set on user and role level. The <strong>User-schema</strong> is extensible and <strong>sessions</strong> for returning users are handled automatically.</p><h4>How are ACL-protected ressources handled internally?</h4><p>When an end user performs a requests, a token is attached to it. This token contains the roles of the user and a signature. First, the <strong>schema-level ACLs</strong> are checked (e.g., checking that anonymous read access is allowed). If they pass, the next step is to validate the <strong>object-level ACLs</strong>. This is efficiently handled by constructing a query predicate on indexed ACL-attributes that is pushed down to the database for every operation.</p><p>One of the coolest things about this ACL-scheme, is that the ACLs are already checked in the CDN if the data is cached, allowing high cache hit rates, even on private data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BBf5cs-1Ajo8RQmBSI0soQ.png" /></figure><h4>Backend Code</h4><p>Most applications have some business logic that cannot be done in the client, e.g. the checkout in an e-commerce shop. Baqend allows you to execute server-side code using the same SDK as in the client.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UBwpLjoul5xMCX8BpgjX9g.gif" /></figure><p>The code can be called as a microservice similar to a Function-as-a-Service providers or be triggered based on operations such as update, insert, delete, etc.:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dYc4vMyg_VYgyiRb-Oy5XQ.png" /></figure><h4>Going Real-Time</h4><p>While triggers are useful, they are also pretty limited in their expressiveness and not the right tool for complex reactive applications. This is why we built InvaliDB, a streaming system for <strong>real-time queries on MongoDB</strong>. For registered real-time queries, result updates are pushed to clients and caches alike.</p><p>As illustrated below, incoming database updates are matched in an Apache Storm cluster against queries.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CP5aNbc9UeF-pHpLIRrDlw.png" /></figure><p>The unique feature of this architecture is that it <strong>scales with both queries and updates</strong> — unlike RethinkDB, Meteor and Parse that all have centralized bottlenecks that break with increasing throughput.</p><p>The coolest part is, how easy it is to use this feature: it is used exactly like regular queries. You simply <strong>subscribe </strong>to any MongoDB query (including complex predicates, sorting, limit, etc.) and the SDK maintains the result in realtime (&lt; 30ms end-to-end latency):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/927/1*Dqeq31o-v9hNrqApiLsRYw.png" /></figure><h4>Accelerating Legacy Sites: Going Beyond BaaS</h4><p>A limitation of any Backend-as-a-Service is that you have to built your app or website around its APIs in order to use it. Moving an existing application to a BaaS is a lot of work.</p><p>Fortunately, there’s a funky new browser technology to cicrumvent this problem: <a href="https://developer.mozilla.org/de/docs/Web/API/Service_Worker_API"><strong>Service Workers</strong></a>. What they do is:</p><ul><li>They <strong>proxy </strong>any HTTP request and allow you to change the browser’s default behaviour</li><li>They provide an <strong>Offline Cache </strong>for „progessive web apps“ — if the client is disconnected, you can choose to serve a cached copy for an offline mode</li></ul><h4>How can we use this to make legacy sites easily use a BaaS?</h4><p>The idea is simple:</p><ol><li>You <strong>include </strong>our <strong>Service Worker</strong> on your site, quite similar to aGoogle Analytics snippet</li><li>The Service Worker gets a <strong>list of patterns</strong> of what to intercept and redirect to our CDN</li><li>Baqend <strong>pulls the data from the original site</strong> and stores its metadata and content</li><li>The legacy system (e.g. Wordpress) simply triggers a <strong>refresh </strong>when something changes → Baqend iterates over all cached files and revalidates them against the origin. If something changed, it is updated in the CDN and the Bloom filter.</li><li>Caching in the Service Worker uses the <strong>Bloom filter </strong>logic to determine when to bypass the cache</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k0uOAVLDtkvvPEZqKybaxA.png" /></figure><p>We will release this feature soon. On sites we have tested so far, performance can often be tripled without changing the current backend architecture.</p><h3>Summary: Lessons Learned</h3><p>Our main learnings from building Baqend are: database systems and distributed systems are hard. Some of these complexities should be exposed to developers (e.g. indexing) and some should be hidden (e.g. scalable stream processing).</p><p>All in all, of the three categories <strong>frontend</strong>, <strong>network </strong>and <strong>backend</strong>, a BaaS can optimize many things of the network and backend that are really hard work on traditional platforms.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RFvov8uhpV9xD5xc9ZYWbA.png" /></figure><h4>Curious? Try it.</h4><p>Learn how to develop with a Backend-as-a-Serivce, it is a fun experience:</p><ol><li><a href="https://dashboard.baqend.com/register"><strong>Create a Baqend app</strong></a> (or do: npm install -g baqend followed by baqend register)</li><li><strong>Upload </strong>your assets (HTML, images, etc.) to Baqend<strong>.</strong> <a href="https://www.baqend.com/guide/gettingstarted/">Learn how to deploy a simple web app in the <strong>quickstart</strong></a><strong>.</strong></li><li>Use the <strong>Baqend SDK</strong> to easily store &amp; query data, register users, etc. <a href="https://www.baqend.com/guide/topics/setup/">Learn how to <strong>include the SDK</strong></a>.</li><li>Start building your <strong>website or app</strong>. Check out our <a href="https://www.baqend.com/guide/starters/"><strong>starter kits</strong></a> and <a href="https://www.baqend.com/guide/">the <strong>guide</strong></a>.</li></ol><p>Don’t want to miss our next post on Backend-as-a-Service topics? Get it conveniently delivered to your inbox by joining our <a href="http://www.baqend.com/#newsletter">newsletter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a9fac618c2ce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/how-to-develop-a-backend-as-a-service-from-scratch-lessons-learned-a9fac618c2ce">Lessons Learned Building a Backend-as-a-Service: A Technical Deep Dive</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The AWS and MongoDB Infrastructure of Parse: Lessons Learned]]></title>
            <link>https://medium.com/baqend-blog/parse-is-gone-a-few-secrets-about-their-infrastructure-91b3ab2fcf71?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/91b3ab2fcf71</guid>
            <category><![CDATA[backend]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[baas]]></category>
            <category><![CDATA[parse]]></category>
            <category><![CDATA[serverless]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Tue, 31 Jan 2017 16:37:07 GMT</pubDate>
            <atom:updated>2017-02-09T20:09:43.669Z</atom:updated>
            <content:encoded><![CDATA[<p>This is the extended form of a comment that got some interest on Hackernews. After a grace period of one year, Parse is now offline. This is a collection of learnings and technical decisions that might be useful for other companies running cloud services. At least, it directly affects the design of our own Backend-as-a-Service <a href="https://www.baqend.com/">Baqend</a>.</p><p>So here are some facts and trivia that are not so well-known or published that I collected by talking to Parse engineers that now work at Facebook. As I am unsure about whether they were allowed to share this information, I will not mention them by name.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wn9UHchp1Kn_4h7jV99uzQ.png" /><figcaption>Parse is <a href="https://status.parse.com/incidents/6mpkbscqw6p9">offline</a></figcaption></figure><h4>Users and Traction</h4><ul><li><strong>1 million apps</strong> were deployed to Parse.</li><li>The largest Parse app had <strong>40M users.</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/660/0*W8nWVqOx426ape19.jpg" /><figcaption>The largest Parse customer only used it for Push notifications</figcaption></figure><ul><li>Parse was one of the world’s <strong>largest MongoDB user</strong></li><li>Clash of Kings used Parse for <strong>push notifications</strong> and made up roughly half of all pushes that went through Parse. They never moved any other parts to Parse, due to scalability concerns.</li><li>Original reason for Facebook to acquire Parse was to <strong>push their mobile SDKs</strong> and to create synergies with mobile ads. Parse was often sold as a package deal with Facebook advertising.</li><li>Static pricing model measured in guaranteed <strong>requests per second</strong> did not work well.</li><li>Business problem: people tended to remain in the <strong>free-tier</strong>.</li><li>Technical problem I: complicated <strong>rate limiting</strong>. If limit exceeded by a factor of 60 for a minute, requests were dropped. Limits were tracked using a shared <strong>Memcache</strong> instance. Consequence: when developers experienced rate limits in the API, they added retries. The retries incurred enormous load in the Parse backend.</li><li>Technical problem II: the real problem and bottleneck was not the API servers but almost always the <strong>shared MongoDB database cluster</strong>.</li></ul><h4>Parse Server</h4><ul><li>Server was <strong>Rails</strong> at first (with 24 threads max. concurrency) with very little throughput per server (~15–30 requests per second)</li><li>The server was later <strong>rewritten in Go</strong>. The open-source <a href="https://github.com/ParsePlatform/parse-server">Parse server</a> is written Node.js and lacks many functionalities of the original Parse server in Go.</li><li>Backend was completely on <strong>Amazon Web Services</strong></li><li>It was planned to migrate Parse to <strong>Facebook’s infrastructure</strong> (e.g. <a href="https://code.facebook.com/posts/685565858139515/needle-in-a-haystack-efficient-storage-of-billions-of-photos/">Haystack</a>, <a href="https://www.usenix.org/node/174510">Tao</a>, <a href="https://www.usenix.org/conference/osdi14/technical-sessions/presentation/muralidhar">F4</a>, <a href="https://www.facebook.com/notes/facebook-engineering/scaling-apache-giraph-to-a-trillion-edges/10151617006153920/">Extended Apache Giraph</a>, <a href="http://www.vldb.org/pvldb/vol8/p1816-teller.pdf">Gorilla</a>) but the project was abandoned</li><li>Roughly 8 developers working on SDKs, 8 on the server, 8 DevOps + a few more engineers</li></ul><h4>Database</h4><ul><li>&gt;40 MongoDB Replica Sets with 3 nodes each</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0L4CwRaqRHJS6DrbCnwiGg.png" /><figcaption>Parse went for RocksDB as their primary storage engine.</figcaption></figure><ul><li>Storage Engine: <strong>RocksDB</strong> (i.e. <a href="https://github.com/mongodb-partners/mongo-rocks">MongoRocks</a>), an append-only engine based on <a href="https://en.wikipedia.org/wiki/Log-structured_merge-tree">log-structured merge trees</a> (similar to e.g. Cassandra, HBase, CouchDB, LevelDB, WiredTiger, TokuDB). Reason: there is better handling of <strong>many collections</strong> — in contract to WiredTiger that uses one file for each collection. Compression was better by a factor of 2–3 in terms of space. Writes and replication also were more efficient in terms of latency/lag. The move to MongoRocks from MMap was done by adding a replica with MongoRocks that was later promoted as the new master.</li><li>Used only <strong>instance storage with SSDs</strong>, no EBS.</li><li>No sharding: each tenant was mapped statically to <strong>exactly one replica set </strong>using MongoDB’s primary database logic.</li><li>The Mongo <strong>Write Concern was 1</strong> (!), i.e. writes were confirmed before they were replicated. Some people complained about lost data and stale reads</li><li><strong>Slave reads</strong> were allowed for performance reasons</li><li><strong>Partial updates</strong> were problematic as small updates to large docs got “<a href="https://en.wikipedia.org/wiki/Write_amplification">write amplification</a>” when being written to oplog</li><li>Frequent (daily) <strong>master reelections</strong> on AWS EC2. Rollback files were discarded and let to data loss</li><li>Developed a special “<strong>flashback” tool</strong> that recorded workloads that could later be rerun for internal load and functional testing</li><li>JS ran in <strong>forked V8 engine</strong> to enforce 15 second execution limit for user-provided code</li><li><strong>No sharding automation</strong>: manual, error-prone process for largest customers</li><li><strong>Indexing not exposed</strong>: automatic rule-based generation from slow query logs. Did not work well for larger apps.</li><li><strong>Slow queries</strong> killed by cron job that polled Mongos currentOp and maintained a limit per (API-key, query template) combination</li><li><strong>Backups</strong>: if important customers lost data due to human error, Facebook engineers would manually recover it from periodic backups</li><li>The <strong>object-level ACL system</strong> was highly inefficient. Numerours indexes were required that could sometimes surpass the actual data size by a factor of 3–4.</li><li>As there was no mechanism for <strong>concurrency control</strong> (except for minimal support for things like counters), applications were often inconsistent</li></ul><h3>What Parse should have done differently</h3><p>Parse did a lot of things right. The documentation was great, the mobile SDKs were solid and the web UIs well-designed. However, they had an unspoken value system of not trusting their users to deal with complex database and architectural problems.</p><p>Coming from a database background, our idea is that developers should know about details such as schemas and indexes (the Parse engineers strongly agreed in hindsight). Also, we think that backend services are not limited to mobile apps but very useful for the web.</p><p>I think that providers should be open about their infrastructure and trade-offs, which Parse only was after it had already failed.</p><p>If this idea sounds interesting to you, have a look at <a href="https://www.baqend.com/">Baqend</a>. It is a high-performance BaaS that focuses on web performance through transparent caching and scalability through auto-sharding and polyglot persistence.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vxmo1QCyZStg6eplzmzWTw.png" /><figcaption>We strongly believe that architecture should not be a secret.</figcaption></figure><p>Don’t want to miss our next post on Backend-as-a-Service topics? Get it conveniently delivered to your inbox by <a href="http://www.baqend.com/#newsletter">joining our newsletter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=91b3ab2fcf71" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/parse-is-gone-a-few-secrets-about-their-infrastructure-91b3ab2fcf71">The AWS and MongoDB Infrastructure of Parse: Lessons Learned</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[NoSQL Databases: a Survey and Decision Guidance]]></title>
            <link>https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/ea7823a822d</guid>
            <category><![CDATA[big-data]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[scalability]]></category>
            <category><![CDATA[nosql]]></category>
            <category><![CDATA[data]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Mon, 15 Aug 2016 11:02:55 GMT</pubDate>
            <atom:updated>2019-07-31T09:12:13.768Z</atom:updated>
            <content:encoded><![CDATA[<p>(At the bottom of this page, you find a <a href="#598d"><strong>BibTeX reference</strong></a> to cite this article.)</p><p>Together with our colleagues at the University of Hamburg, we — that is <a href="http://www.baqend.com/">Felix Gessert</a>, <a href="https://vsis-www.informatik.uni-hamburg.de/vsis/members/look/1316">Wolfram Wingerath</a>, <a href="https://vsis-www.informatik.uni-hamburg.de/vsis/members/look/1317">Steffen Friedrich</a> and <a href="https://vsis-www.informatik.uni-hamburg.de/vsis/members/look/209">Norbert Ritter</a> — presented an overview over the NoSQL landscape at <a href="http://www.summersoc.eu/">SummerSOC’16</a> last month. Here is the written gist. We give our best to convey the condensed NoSQL knowledge we gathered building <a href="https://www.baqend.com/">Baqend</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XzNUrV1IpNpkPNyEIvaFkA.png" /></figure><h3>TL;DR</h3><p>Today, data is generated and consumed at unprecedented scale. This has lead to novel approaches for scalable data management subsumed under the term “NoSQL” database systems to handle the ever-increasing data volume and request loads. However, the heterogeneity and diversity of the numerous existing systems impede the well-informed selection of a data store appropriate for a given application context. Therefore, this article gives a top-down overview of the field: Instead of contrasting the implementation specifics of individual representatives, we propose a comparative classification model that relates functional and non-functional requirements to techniques and algorithms employed in NoSQL databases. This NoSQL Toolbox allows us to derive a simple decision tree to help practitioners and researchers filter potential system candidates based on central application requirements.</p><h3>1. Introduction</h3><p>Traditional relational database management systems (RDBMSs) provide powerful mechanisms to store and query structured data under strong consistency and transaction guarantees and have reached an unmatched level of reliability, stability and support through decades of development. In recent years, however, the amount of useful data in some application areas has become so vast that it cannot be stored or processed by traditional database solutions. User-generated content in social networks or data retrieved from large sensor networks are only two examples of this phenomenon commonly referred to as <strong>Big Data</strong>. A class of novel data storage systems able to cope with Big Data are subsumed under the term <strong>NoSQL databases</strong>, many of which offer horizontal scalability and higher availability than relational databases by sacrificing querying capabilities and consistency guarantees. These trade-offs are pivotal for service-oriented computing and as-a-service models, since any stateful service can only be as scalable and fault-tolerant as its underlying data store.</p><p>There are dozens of NoSQL database systems and it is hard to keep track of where they excel, where they fail or even where they differ, as implementation details change quickly and feature sets evolve over time. In this article, we therefore aim to provide an overview of the NoSQL landscape by discussing employed concepts rather than system specificities and explore the requirements typically posed to NoSQL database systems, the techniques used to fulfil these requirements and the trade-offs that have to be made in the process. Our focus lies on key-value, document and wide-column stores, since these NoSQL categories cover the most relevant techniques and design decisions in the space of scalable data management.</p><p>In Section 2, we describe the most common high-level approaches towards categorizing NoSQL database systems either by their data model into key-value stores, document stores and wide-column stores or by the safety-liveness trade-offs in their design (CAP and PACELC). We then survey commonly used techniques in more detail and discuss our model of how requirements and techniques are related in Section 3 , before we give a broad overview of prominent database systems by applying our model to them in Section 4 . A simple and abstract decision model for restricting the choice of appropriate NoSQL systems based on application requirements concludes the paper in Section 5.</p><h3>2. High-Level System Classification</h3><p>In order to abstract from implementation details of individual NoSQL systems, high-level classification criteria can be used to group similar data stores into categories. In this section, we introduce the two most prominent approaches: data models and CAP theorem classes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SIDPgNDxvBOcXNiiQrfa5A.png" /></figure><h4>2.1 Different Data Models</h4><p>The most commonly employed distinction between NoSQL databases is the way they store and allow access to data. Each system covered in this paper can be categorised as either key-value store, document store or wide-column store.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*swUK-eLWsk-wudXSXRgyYQ.png" /><figcaption>Figure 1: Key-value stores offer efficient storage and retrieval of arbitrary values.</figcaption></figure><p><strong>2.1.1 Key-Value Stores. </strong>A key-value store consists of a set of key-value pairs with unique keys. Due to this simple structure, it only supports get and put operations. As the nature of the stored value is transparent to the database, pure key-value stores do not support operations beyond simple CRUD (Create, Read, Update, Delete). Key-value stores are therefore often referred to as <strong>schemaless</strong>: Any assumptions about the structure of stored data are implicitly encoded in the application logic (<em>schema-on-read</em>) and not explicitly defined through a data definition language (<em>schema-on-write</em>).</p><p>The obvious advantages of this data model lie in its simplicity. The very simple abstraction makes it easy to partition and query the data, so that the database system can achieve low latency as well as high throughput. However, if an application demands more complex operations, e.g. range queries, this data model is not powerful enough. <a href="#fig:data_models_key-value">Figure 1</a> illustrates how user account data and settings might be stored in a key-value store. Since queries more complex than simple lookups are not supported, data has to be analyzed inefficiently in application code to extract information like whether cookies are supported or not (cookies: false).</p><p><strong>2.1.2 Document Stores. </strong>A document store is a key-value store that restricts values to semi-structured formats such as JSON documents. This restriction in comparison to key-value stores brings great flexibility in accessing the data. It is not only possible to fetch an entire document by its ID, but also to retrieve only parts of a document, e.g. the age of a customer, and to execute queries like aggregation, query-by-example or even full-text search.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gdxUo2ojiTX2JQIkA2hxcQ.png" /><figcaption>Figure 2: Document stores are aware of the internal structure of the stored entity and thus can support queries.</figcaption></figure><p><strong>3.1.3 Wide-Column Stores </strong>Wide-column stores inherit their name from the image that is often used to explain the underlying data model: a relational table with many sparse columns. Technically, however, a wide-column store is closer to a distributed multi-level sorted map: The first-level keys identify rows which themselves consist of key-value pairs. The first-level keys are called <strong>row keys</strong>, the second-level keys are called <strong>column keys</strong>. This storage scheme makes tables with arbitrarily many columns feasible, because there is no column key without a corresponding value. Hence, null values can be stored without any space overhead. The set of all columns is partitioned into so-called <strong>column families</strong> to colocate columns on disk that are usually accessed together. On disk, wide-column stores do not colocate all data from each row, but instead values of the same column family <em>and</em> from the same row. Hence, an entity (a row) cannot be retrieved by one single lookup as in a document store, but has to be joined together from the columns of all column families. However, this storage layout usually enables highly efficient data compression and makes retrieving only a portion of an entity very efficient. The data are stored in lexicographic order of their keys, so that data that are accessed together are physically co-located, given a careful key design. As all rows are distributed into contiguous ranges (so-called <strong>tablets</strong>) among different <strong>tablet servers</strong>, row scans only involve few servers and thus are very efficient.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jvxgAtqWADL8E43gs0p8jw.png" /><figcaption>Figure 3: Data in a wide-column store.</figcaption></figure><p><a href="http://static.googleusercontent.com/media/research.google.com/de//archive/bigtable-osdi06.pdf">Bigtable</a>, which pioneered the wide-column model, was specifically developed to store a large collection of webpages as illustrated in <a href="#fig:data_models_wide-column">Figure 3</a>. Every row in the webpages table corresponds to a single webpage. The row key is a concatenation of the URL components in reversed order and every column key is composed of the column family name and a column qualifier, separated by a colon. There are two column families: the “contents” column family with only one column holding the actual webpage and the “anchor” column family holding links to each webpage, each in a separate column. Every cell in the table (i.e. every value accessible by the combination of row and column key) can be versioned by timestamps or version numbers. It is important to note that much of the information of an entity lies in the keys and not only in the values .</p><h4>2.2 Consistency-Availability Trade-Offs: CAP and PACELC</h4><p>Another defining property of a database apart from how the data are stored and how they can be accessed is the level of consistency that is provided. Some databases are built to guarantee strong consistency and serializability (<a href="http://www.minet.uni-jena.de/dbis/lehre/ws2005/dbs1/HaerderReuter83.pdf">ACID</a>), while others favour availability (<a href="http://queue.acm.org/detail.cfm?id=1394128">BASE</a>). This trade-off is inherent to every distributed database system and the huge number of different NoSQL systems shows that there is a wide spectrum between the two paradigms. In the following, we explain the two theorems CAP and PACELC according to which database systems can be categorised by their respective positions in this spectrum.</p><p><strong>CAP</strong>. Like the famous <a href="https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf">FLP Theorem</a>, the <a href="https://people.eecs.berkeley.edu/~brewer/PODC2000.pdf">CAP Theorem</a>, presented by Eric Brewer at PODC 2000 and later <a href="https://www.comp.nus.edu.sg/~gilbert/pubs/BrewersConjecture-SigAct.pdf">proven by Gilbert and Lynch</a>, is one of the truly influential impossibility results in the field of distributed computing, because it places an ultimate upper bound on what can possibly be accomplished by a distributed system. It states that a sequentially consistent read/write register that eventually responds to every request cannot be realised in an asynchronous system that is prone to network partitions. In other words, it can guarantee at most two of the following three properties at the same time:</p><ul><li><strong>Consistency (C)</strong>: Reads and writes are always executed atomically and are strictly consistent (<a href="http://www.cs.cornell.edu/andru/cs711/2002fa/reading/linearizability.pdf">linearizable</a>). Put differently, all clients have the same view on the data at all times.</li><li><strong>Availability (A)</strong>: Every non-failing node in the system can always accept read and write requests by clients and will eventually return with a meaningful response, i.e. not with an error message.</li><li><strong>Partition-tolerance (P)</strong>: The system upholds the previously displayed consistency guarantees and availability in the presence of message loss between the nodes or partial system failure.</li></ul><p>Brewer argues that a system can be both available and consistent in normal operation, but in the presence of a system partition, this is not possible: If the system continues to work in spite of the partition, there is some non-failing node that has lost contact to the other nodes and thus has to decide to either continue processing client requests to preserve availability (AP, <strong>eventual consistent systems</strong>) or to reject client requests in order to uphold consistency guarantees (CP). The first option violates consistency, because it might lead to stale reads and conflicting writes, while the second option obviously sacrifices availability. There are also systems that usually are available and consistent, but fail completely when there is a partition (CA), for example single-node systems. It has been shown that the CAP-theorem holds for any consistency property that is at least as strong as causal consistency, which also includes any recency bounds on the permissible staleness of data (<a href="http://www.cs.utexas.edu/users/dahlin/papers/cac-tr.pdf">Δ-atomicity</a>). Serializability as the correctness criterion of transactional isolation does not require strong consistency. However, similar to consistency, <a href="http://repository.upenn.edu/cgi/viewcontent.cgi?article=1669&amp;context=cis_reports">serializability can also not be achieved under network partitions</a>.</p><p>The classification of NoSQL systems as either AP, CP or CA vaguely reflects the individual systems’ capabilities and hence is widely accepted as a means for high-level comparisons. However, it is important to note that the CAP Theorem actually does not state anything on normal operation; it merely tells us whether a system favors availability or consistency <em>in the face of a network partition</em>. In contrast to the FLP-Theorem, the CAP theorem assumes a failure model that allows arbitrary messages to be dropped, reordered or delayed indefinitely. Under the weaker assumption of reliable communication channels (i.e. messages always arrive but asynchronously and possibly reordered) a CAP-system is in fact possible using the <a href="http://groups.csail.mit.edu/tds/papers/Attiya/TM-423.pdf">Attiya, Bar-Noy, Dolev algorithm</a>, as long as a majority of nodes are up. (Therefore, consensus as used for coordination in many NoSQL systems either natively (e.g. in <a href="http://static.googleusercontent.com/media/research.google.com/de//pubs/archive/36971.pdf">Megastore</a>) or through coordination services like Chubby and <a href="http://static.cs.brown.edu/courses/cs227/archives/2012/papers/replication/hunt.pdf">Zookeeper</a> is even harder to achieve with high availability than strong consistency, see <a href="https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf">FLP Theorem</a>.)</p><p><strong>PACELC</strong>. This lack of the CAP Theorem is addressed in <a href="http://cs-www.cs.yale.edu/homes/dna/papers/abadi-pacelc.pdf">an article by Daniel Abadi</a> in which he points out that the CAP Theorem fails to capture the trade-off between latency and consistency during <em>normal operation</em>, even though it has proven to be much more influential on the design of distributed systems than the availability-consistency trade-off in failure scenarios. He formulates PACELC which unifies both trade-offs and thus portrays the design space of distributed systems more accurately. From PACELC, we learn that in case of a <strong>P</strong>artition, there is an <strong>A</strong>vailability-<strong>C</strong>onsistency trade-off; <strong>E</strong>lse, i.e. in normal operation, there is a <strong>L</strong>atency-<strong>C</strong>onsistency trade-off.</p><p>This classification basically offers two possible choices for the partition scenario (A/C) and also two for normal operation (L/C) and thus appears more fine-grained than the CAP classification. However, many systems cannot be assigned exclusively to one single PACELC class and one of the four PACELC classes, namely PC/EL, can hardly be assigned to any system.</p><h3>3. Techniques</h3><p>Every significantly successful database is designed for a particular class of applications, or to achieve a specific combination of desirable system properties. The simple reason why there are so many different database systems is that it is not possible for any system to achieve all desirable properties at once. Traditional SQL databases such as PostgreSQL have been built to provide the full functional package: a very flexible data model, sophisticated querying capabilities including joins, global integrity constraints and transactional guarantees. On the other end of the design spectrum, there are key-value stores like Dynamo that scale with data and request volume and offer high read and write throughput as well as low latency, but barely any functionality apart from simple lookups.</p><p>In this section, we highlight the design space of distributed database systems, concentrating on sharding, replication, storage management and query processing. We survey the available techniques and discuss how they are related to different functional and non-functional properties (goals) of data management systems. In order to illustrate what techniques are suitable to achieve which system properties, we provide the <strong>NoSQL Toolbox</strong> (<a href="#fig:NoSQL_toolbox">Figure 4</a>) where each technique is connected to the functional and non-functional properties it enables (positive edges only).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Yp10mfavInjDULz5Qz-f-Q.png" /><figcaption>Figure 4: The NoSQL Toolbox: It connects the techniques of NoSQL databases with the desired functional and non-functional system properties they support.</figcaption></figure><h4>3.1 Sharding</h4><p>Several distributed relational database systems such as Oracle RAC or IBM DB2 pureScale rely on a <strong>shared-disk architecture</strong> where all database nodes access the same central data repository (e.g. a NAS or SAN). Thus, these systems provide consistent data at all times, but are also inherently difficult to scale. In contrast, the (NoSQL) database systems focused in this paper are built upon a <strong>shared-nothing architecture</strong>, meaning each system consists of many servers with private memory and private disks that are connected through a network. Thus, high scalability in throughput and data volume is achieved by <strong>sharding</strong> (partitioning) data across different nodes (<strong>shards</strong>) in the system. There are three basic distribution techniques: range-sharding, hash-sharding and entity-group sharding. To make efficient scans possible, the data can be partitioned into ordered and contiguous value ranges by <strong>range-sharding</strong>. However, this approach requires some coordination through a master that manages assignments. To ensure elasticity, the system has to be able to detect and resolve hotspots automatically by further splitting an overburdened shard.</p><p>Range sharding is supported by wide-column stores like <a href="http://static.googleusercontent.com/media/research.google.com/de//archive/bigtable-osdi06.pdf">BigTable</a>, HBase or Hypertable and document stores, e.g. MongoDB, RethinkDB, <a href="http://www.csce.uark.edu/~xintaowu/BDAM/p1135-qiao.pdf">Espresso</a> and <a href="http://www.vldb.org/pvldb/vol8/p1668-shukla.pdf">DocumentDB</a>. Another way to partition data over several machines is <strong>hash-sharding</strong> where every data item is assigned to a shard server according to some hash value built from the primary key. This approach does not require a coordinator and also guarantees the data to be evenly distributed across the shards, as long as the used hash function produces an even distribution. The obvious disadvantage, though, is that it only allows lookups and makes scans unfeasible. Hash sharding is used in key-value stores and is also available in some wide-coloumn stores like <a href="https://www.cs.cornell.edu/projects/ladis2009/papers/lakshman-ladis2009.pdf">Cassandra</a> or <a href="http://sigops.org/sosp/sosp11/current/2011-Cascais/printable/11-calder.pdf">Azure Tables</a>.</p><p>The shard server that is responsible for a record can be determined as serverid = hash(id)%servers, for example. However, this hashing scheme requires all records to be reassigned every time a new server joins or leaves, because it changes with the number of shard servers (servers). Consequently, it infeasible to use in elastic systems like Dynamo, Riak or Cassandra, which allow additional resources to be added on-demand and again be removed when dispensable. For increased flexibility, elastic systems typically use <a href="https://www.akamai.com/es/es/multimedia/documents/technical-publication/consistent-hashing-and-random-trees-distributed-caching-protocols-for-relieving-hot-spots-on-the-world-wide-web-technical-publication.pdf"><strong>consistent hashing</strong></a> where records are not directly assigned to servers, but instead to logical partitions which are then distributed across all shard servers. Thus, only a fraction of the data have to be reassigned upon changes in the system topology. For example, an elastic system can be downsized by offloading all logical partitions residing on a particular server to other servers and then shutting down the now idle machine. For details on how consistent hashing is used in NoSQL systems, see <a href="http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf">the Dynamo paper</a>.</p><p><strong>Entity-group sharding</strong> is a data partitioning scheme with the goal of enabling single-partition transactions on co-located data. The partitions are called entity-groups and either explicitly declared by the application (e.g. in <a href="http://www.cs.ucsb.edu/~sudipto/papers/socc10-das.pdf">G-Store</a> and<a href="http://static.googleusercontent.com/media/research.google.com/de//pubs/archive/36971.pdf">MegaStore</a>) or derived from transactions’ access patterns (e.g. in <a href="http://nms.lcs.mit.edu/papers/relcloud_cidr11.pdf">Relational Cloud</a> and <a href="http://dl.acm.org/citation.cfm?id=2005651">Cloud SQL Server</a>). If a transaction accesses data that spans more than one group, data ownership can be transferred between entity-groups or the transaction manager has to fallback to more expensive multi-node transaction protocols.</p><h4>3.2 Replication</h4><p>In terms of CAP, conventional RDBMSs are often CA systems run in single-server mode: The entire system becomes unavailable on machine failure. And so system operators secure data integrity and availability through expensive, but reliable high-end hardware. In contrast, NoSQL systems like Dynamo, BigTable or Cassandra are designed for data and request volumes that cannot possibly be handled by one single machine, and therefore they run on clusters consisting of thousands of servers. (Low-end hardware is used, because it is substantially more cost-efficient than high-end hardware.) Since <a href="https://www.usenix.org/legacy/event/lisa07/tech/full_papers/hamilton/hamilton_html/">failures are inevitable and will occur frequently in any large-scale distributed system</a>, the software has to cope with them on a daily basis . In 2009, Google fellow <a href="https://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf">Jeff Dean stated</a> that a typical new cluster at Google encounters thousands of hard drive failures, 1,000 single-machine failures, 20 rack failures and several network partitions due to expected and unexpected circumstances in its first year alone. <a href="https://aphyr.com/posts/288-the-network-is-reliable">Many more recent cases of network partitions and outages</a> in large cloud data centers have been reported . Replication allows the system to maintain availability and durability in the face of such errors. But storing the same records on different machines (<strong>replica servers</strong>) in the cluster introduces the problem of synchronization between them and thus a trade-off between consistency on the one hand and latency and availability on the other.</p><p><a href="http://db.cs.berkeley.edu/cs286/papers/dangers-sigmod1996.pdf">Gray et al.</a> propose a two-tier classification of different replication strategies according to <em>when</em> updates are propagated to replicas and <em>where</em> updates are accepted. There are two possible choices on tier one (“when”): <strong>Eager</strong>(<em>synchronous</em>) replication propagates incoming changes synchronously to all replicas before a commit can be returned to the client, whereas <strong>lazy</strong> (<em>asynchronous</em>) replication applies changes only at the receiving replica and passes them on asynchronously. The great advantage of <em>eager</em> replication is consistency among replicas, but it comes at the cost of higher write latency due to the need to wait for other replicas and impaired availability. <em>Lazy</em> replication is faster, because it allows replicas to diverge; as a consequence, stale data might be served. On the second tier (“where”), again, two different approaches are possible: Either a <strong>master-slave</strong> (<em>primary copy</em>) scheme is pursued where changes can only be accepted by one replica (the master) or, in a <strong>update anywhere</strong> (<em>multi-master</em>) approach, every replica can accept writes. In <em>master-slave</em> protocols, concurrency control is not more complex than in a distributed system without replicas, but the entire replica set becomes unavailable, as soon as the master fails. Multi-master protocols require complex mechanisms for prevention or detection and reconciliation of conflicting changes. Techniques typically used for these purposes are versioning, vector clocks, gossiping and read repair (e.g. in <a href="http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf">Dynamo</a>) and <a href="http://hal.upmc.fr/inria-00555588/document">convergent or commutative datatypes</a> (e.g. in Riak).</p><p>Basically, all four combinations of the two-tier classification are possible. Distributed relational systems usually perform <em>eager master-slave</em> replication to maintain strong consistency. <em>Eager update anywhere</em> replication as for example featured in Google’s Megastore suffers from a heavy communication overhead generated by synchronisation and can cause distributed deadlocks which are expensive to detect. NoSQL database systems typically rely on <em>lazy</em>replication, either in combination with the master-slave (CP systems, e.g. HBase and MongoDB) or the update anywhere approach (AP systems, e.g. Dynamo and Cassandra). Many NoSQL systems leave the choice between latency and consistency to the client, i.e. for every request, the client decides whether to wait for a response from any replica to achieve minimal latency or for a certainly consistent response (by a majority of the replicas or the master) to prevent stale data.</p><p>An aspect of replication that is not covered by the two-tier scheme is the distance between replicas. The obvious advantage of placing replicas near one another is low latency, but close proximity of replicas might also reduce the positive effects on availability; for example, if two replicas of the the same data item are placed in the same rack, the data item is not available on rack failure in spite of replication. But more than the possibility of mere temporary unavailability, placing replicas nearby also bears the peril of losing all copies at once in a disaster scenario. An alternative technique for latency reduction is used in <a href="http://www.btw-2015.de/res/proceedings/Hauptband/Wiss/Gessert-The_Cache_Sketch-165.pdf">Orestes</a>, where data is cached close to applications using web caching infrastructure and cache coherence protocols.</p><p>Geo-replication can protect the system against complete data loss and improve read latency for distributed access from clients. <em>Eager geo-replication</em>, as implemented in <a href="http://static.googleusercontent.com/media/research.google.com/de//pubs/archive/36971.pdf">Megastore</a>, <a href="http://static.googleusercontent.com/media/research.google.com/de//archive/spanner-osdi2012.pdf">Spanner</a>, <a href="http://mdcc.cs.berkeley.edu/mdcc.pdf">MDCC</a> and <a href="http://sysnet.ucsd.edu/~yamao/pub/mencius-osdi.pdf">Mencius</a> achieve strong consistency at the cost of higher write latencies (typically 100ms to 600ms). With <em>lazy geo-replication</em> as in Dynamo, <a href="http://www.cs.ucsb.edu/~agrawal/fall2009/PNUTS.pdf">PNUTS</a>, <a href="http://news.cs.nyu.edu/~jinyang/pub/walter-sosp11.pdf">Walter</a>, <a href="https://www.cs.cmu.edu/~dga/papers/cops-sosp2011.pdf">COPS</a>, Cassandra and BigTable recent changes may be lost, but the system performs better and remains available during partitions. <a href="http://dl.acm.org/citation.cfm?id=2172338">Charron-Bost et al. (Chapter 12)</a> and <a href="http://dl.acm.org/citation.cfm?id=293457">Öszu and Valduriez (Chapter 13)</a> provide a comprehensive discussion of database replication.</p><h4>3.3 Storage Management</h4><p>For best performance, database systems need to be optimized for the storage media they employ to serve and persist data. These are typically main memory (RAM), solid-state drives (SSDs) and spinning disk drives (HDDs) that can be used in any combination. Unlike RDBMSs in enterprise setups, distributed NoSQL databases avoid specialized shared-disk architectures in favor of shared-nothing clusters based on commodity servers (employing commodity storage media). Storage devices are typically visualized as a “storage pyramid” (see <a href="#fig:storage_model">Figure 5</a> or <a href="http://db.cs.berkeley.edu/papers/fntdb07-architecture.pdf">Hellerstein et al.</a>). There is also a set of transparent caches (e.g. L1-L3 CPU caches and disk buffers, not shown in the Figure), that are only implicitly leveraged through well-engineered database algorithms that promote data locality. The very different cost and performance characteristics of RAM, SSD and HDD storage and the different strategies to leverage their strengths (storage management) are one reason for the diversity of NoSQL databases. Storage management has a spatial dimension (where to store data) and a temporal dimension (when to store data). Update-in-place and append-only-IO are two complementary spatial techniques of organizing data; in-memory prescribes RAM as the location of data, whereas logging is a temporal technique that decouples main memory and persistent storage and thus provides control over when data is actually persisted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fjEVwivJAJxxvolywt6z3Q.png" /><figcaption>Figure 5: The storage pyramid and its role in NoSQL systems.</figcaption></figure><p>In their seminal paper <a href="http://nms.csail.mit.edu/~stavros/pubs/hstore.pdf">“the end of an architectural era”</a>, Stonebraker et al. have found that in typical RDBMSs, only 6.8% of the execution time is spent on “useful work”, while the rest is spent on:</p><ul><li>buffer management (34.6%), i.e. caching to mitigate slower disk access</li><li>latching (14.2%), to protect shared data structures from race conditions caused by multi-threading</li><li>locking (16.3%), to guarantee logical isolation of transactions</li><li>logging (1.9%), to ensure durability in the face of failures</li><li>hand-coded optimizations (16.2%)</li></ul><p>This motivates that large performance improvements can be expected if RAM is used as primary storage (<strong>in-memory databases</strong>). The downside are high storage costs and lack of durability — a small power outage can destroy the database state. This can be solved in two ways: The state can be replicated over n in-memory server nodes protecting against n-1 single-node failures (e.g. <a href="http://hstore.cs.brown.edu/papers/hstore-demo.pdf">HStore</a>, VoltDB) or by <strong>logging</strong> to durable storage (e.g. Redis or SAP Hana). Through logging, a random write access pattern can be transformed to a sequential one comprised of received operations and their associated properties (e.g. redo information). In most NoSQL systems, the commit rule for logging is respected, which demands every write operation that is confirmed as successful to be logged and the log to be flushed to persistent storage. In order to avoid the rotational latency of HDDs incurred by logging each operation individually, log flushes can be batched together (group commit) which slightly increases the latency of individual writes, but drastically improves throughput.</p><p>SSDs and more generally all storage devices based on NAND flash memory differ substantially from HDDs in various aspects: “(1) asymmetric speed of read and write operations, (2) no in-place overwrite — the whole block must be erased before overwriting any page in that block, and (3) limited program/erase cycles” (<a href="https://www.usenix.org/legacy/events/fast12/tech/full_papers/Min.pdf">Min et al., 2012</a>). Thus, a database system’s storage management must not treat SSDs and HDDs as slightly slower, persistent RAM, since random writes to an SSD are roughly an order of magnitude slower than sequential writes. Random reads, on the other hand, can be performed without any performance penalties. There are some database systems (e.g. Oracle Exadata, Aerospike) that are explicitly engineered for these performance characteristics of SSDs. In HDDs, both random reads and writes are 10–100 times slower than sequential access. Logging hence suits the strengths of SSDs and HDDs which both offer a significantly higher throughput for sequential writes.</p><p>For in-memory databases, an <strong>update-in-place</strong> access pattern is ideal: It simplifies the implementation and random writes to RAM are essentially equally fast as sequential ones, with small differences being hidden by pipelining and the CPU-cache hierarchy. However, RDBMSs and many NoSQL systems (e.g. MongoDB) employ an update-in-place update pattern for persistent storage, too. To mitigate the slow random access to persistent storage, main memory is usually used as a cache and complemented by logging to guarantee durability. In RDBMSs, this is achieved through a complex buffer pool which not only employs cache-replace algorithms appropriate for typical SQL-based access patterns, but also ensures ACID semantics. NoSQL databases have simpler buffer pools that profit from simpler queries and the lack of ACID transactions. The alternative to the buffer pool model is to leave caching to the OS through virtual memory (e.g. employed in MongoDB’s MMAP storage engine). This simplifies the database architecture, but has the downside of giving less control over which data items or pages reside in memory and when they get evicted. Also read-ahead (speculative reads) and write-behind (write buffering) transparently performed with OS buffering lack sophistication as they are based on file system logics instead of database queries.</p><p><strong>Append-only</strong> storage (also referred to as log-structuring) tries to maximize throughput by writing sequentially. Although log-structured file systems have a long research history, append-only I/O has only recently been popularized for databases by BigTable’s use of Log-Structured Merge (LSM) trees consisting of an in-memory cache, a persistent log and immutable, periodically written storage files. LSM trees and variants like Sorted Array Merge Trees (SAMT) and Cache-Oblivious Look-ahead Arrays (COLA) have been applied in many NoSQL systems (Cassandra, CouchDB, LevelDB, Bitcask, RethinkDB, WiredTiger, RocksDB, InfluxDB, TokuDB). Designing a database to achieve maximum write performance by always writing to a log is rather simple, the difficulty lies in providing fast random and sequential reads. This requires an appropriate index structure that is either permanently updated as a copy-on-write (COW) data structure (e.g. CouchDB’s COW B-trees) or only periodically persisted as an immutable data structure (e.g. in BigTable-style systems). An issue of all log-structured storage approaches is costly garbage collection (compaction) to reclaim space of updated or deleted items.</p><p>In virtualized environments like Infrastructure-as-a-Service clouds many of the discussed characteristics of the underlying storage layer are hidden.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cwUuBS3Z_sZK19R0ig5zEA.png" /><figcaption>Table 1: A direct comparison of functional requirements, non-functional requirements and techniques among MongoDB, Redis, HBase, Riak, Cassandra and MySQL according to our NoSQL Toolbox.</figcaption></figure><h4>3.4 Query Processing</h4><p>The querying capabilities of a NoSQL database mainly follow from its distribution model, consistency guarantees and data model. <strong>Primary key lookup</strong>, i.e. retrieving data items by a unique ID, is supported by every NoSQL system, since it is compatible to range- as well as hash-partitioning. <strong>Filter queries</strong> return all items (or projections) that meet a predicate specified over the properties of data items from a single table. In their simplest form, they can be performed as <em>filtered full-table scans</em>. For hash-partitioned databases this implies a <em>scatter-gather</em> pattern where each partition performs the predicated scan and results are merged. For range-partitioned systems, any conditions on the range attribute can be exploited to select partitions.</p><p>To circumvent the inefficiencies of O(n) scans, secondary indexes can be employed. These can either be <strong>local secondary indexes</strong> that are managed in each partition or <strong>global secondary indexes</strong> that index data over all partitions. As the global index itself has to be distributed over partitions, consistent secondary index maintenance would necessitate slow and potentially unavailable commit protocols. Therefore in practice, most systems only offer eventual consistency for these indexes (e.g. Megastore, Google AppEngine Datastore, DynamoDB) or do not support them at all (e.g. HBase, Azure Tables). When executing global queries over local secondary indexes the query can only be targeted to a subset of partitions if the query predicate and the partitioning rules intersect. Otherwise, results have to be assembled through scatter-gather. For example, a user table with range-partitioning over an age field can service queries that have an equality condition on age from one partition whereas queries over names need to be evaluated at each partition. A special case of global secondary indexing is full-text search, where selected fields or complete data items are fed into either a database-internal inverted index (e.g. MongoDB) or to an external search platform such as ElasticSearch or Solr (Riak Search, DataStax Cassandra).</p><p><strong>Query planning</strong> is the task of optimizing a query plan to minimize execution costs. For aggregations and joins, query planning is essential as these queries are very inefficient and hard to implement in application code. The wealth of literature and results on relational query processing is largely disregarded in current NoSQL systems for two reasons. First, the key-value and wide-column model are centered around CRUD and scan operations on primary keys which leave little room for query optimization. Second, most work on distributed query processing focuses on OLAP (online analytical processing) workloads that favor throughput over latency whereas single-node query optimization is not easily applicable for partitioned and replicated databases. However, it remains an open research challenge to generalize the large body of applicable query optimization techniques especially in the context of document databases. (Currently only RethinkDB can perform general Θ-joins. MongoDB’s aggregation framework has support for left-outer equi-joins in its aggregation framework and CouchDB allows joins for pre-declared map-reduce views.)</p><p><strong>In-database analytics</strong> can be performed either natively (e.g. in MongoDB, Riak, CouchDB) or through external analytics platforms such as Hadoop, Spark and Flink (e.g. in Cassandra and HBase). The prevalent native batch analytics abstraction exposed by NoSQL systems is <a href="http://static.googleusercontent.com/media/research.google.com/de//archive/mapreduce-osdi04.pdf">MapReduce</a>. (An alternative to MapReduce are generalized <strong>data processing pipelines</strong>, where the database tries to optimize the flow of data and locality of computation based on a more declarative query language, e.g. MongoDB’s aggregation framework.) Due to I/O, communication overhead and limited execution plan optimization, these batch- and micro-batch-oriented approaches have high response times.<strong>Materialized views</strong> are an alternative with lower query response times. They are declared at design time and continuously updated on change operations (e.g. in CouchDB and Cassandra). However, similar to global secondary indexing, view consistency is usually relaxed in favor of fast, highly-available writes, when the system is distributed. As only few database systems come with built-in support for ingesting and querying unbounded streams of data,<strong>near-real-time analytics</strong> pipelines commonly implement either the <a href="http://lambda-architecture.net/"><strong>Lambda Architecture</strong></a> or the <a href="https://www.oreilly.com/ideas/questioning-the-lambda-architecture"><strong>Kappa Architecture</strong></a>: The former complements a batch processing framework like Hadoop MapReduce with a stream processor such as Storm (see for example <a href="http://www.vldb.org/pvldb/vol7/p1441-boykin.pdf">Summingbird</a>) and the latter exclusively relies on stream processing and forgoes batch processing altogether.</p><h3>4. System Case Studies</h3><p>In this section, we provide a qualitative comparison of some of the most prominent key-value, document and wide-column stores. We present the results in strongly condensed comparisons and refer to the documentations of the individual systems for in-detail information. The proposed NoSQL Toolbox (see <a href="#fig:NoSQL_toolbox">Figure 4</a>) is a means of abstraction that can be used to classify database systems along three dimensions: functional requirements, non-functional requirements and the techniques used to implement them. We argue that this classification characterizes many database systems well and thus can be used to meaningfully contrast different database systems: <a href="#tab:NoSQL_toolbox_table_2">Table 1</a> shows a direct comparison of MongoDB, Redis, HBase, Riak, Cassandra and MySQL in their respective default configurations. A more verbose comparison of central system properties is presented in the large comparison <a href="#tab:NoSQL_toolbox_table_comparison_lscape">Table 2</a> at the end of this article.</p><p>The methodology used to identify the specific system properties consists of an in-depth analysis of publicly available documentation and literature on the systems. Furthermore, some properties had to be evaluated by researching the open-source code bases, personal communication with the developers as well as a meta-analysis of reports and benchmarks by practitioners.</p><p>For detailed descriptions see the slides from our <a href="https://speakerdeck.com/divinetraube/nosql-data-stores-in-research-and-practice-icde-2016-tutorial-extended-version">ICDE 2016 Tutorial</a>, which goes over many details of the different NoSQL systems:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fspeakerdeck.com%2Fplayer%2F8e4bf3847f074b33a2a79845d41c3b50&amp;url=https%3A%2F%2Fspeakerdeck.com%2Fdivinetraube%2Fnosql-data-stores-in-research-and-practice-icde-2016-tutorial-extended-version&amp;image=https%3A%2F%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2Fcac349b010f201324de07ae407783e32%2Fthumb_slide_0.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=speakerdeck" width="710" height="463" frameborder="0" scrolling="no"><a href="https://medium.com/media/6a59c9972eb811f356bb3dadd96a12e3/href">https://medium.com/media/6a59c9972eb811f356bb3dadd96a12e3/href</a></iframe><p>The comparison elucidates how SQL and NoSQL databases are designed to fulfill very different needs: RDBMSs provide an unmatched level of functionality whereas NoSQL databases excel on the non-functional side through scalability, availability, low latency and/or high throughput. However, there are also large differences among the NoSQL databases. Riak and Cassandra, for example, can be configured to fulfill many non-functional requirements, but are only eventually consistent and do not feature many functional capabilities apart from data analytics and, in case of Cassandra, conditional updates. MongoDB and HBase, on the other hand, offer stronger consistency and more sophisticated functional capabilities such as scan queries and — only MongoDB: — filter queries, but do not maintain read and write availability during partitions and tend to display higher read latencies. Redis, as the only non-partitioned system in this comparison apart from MySQL, shows a special set of trade-offs centered around the ability to maintain extremely high throughput at low-latency using in-memory data structures and asynchronous master-slave replication.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qP4HSIx95ZBVla7tjluhLg.png" /><figcaption>Figure 6: A decision tree for mapping requirements to (NoSQL) database systems.</figcaption></figure><h3>5. Conclusions</h3><p>Choosing a database system always means to choose one set of desirable properties over another. To break down the complexity of this choice, we present a binary decision tree in <a href="#fig:NoSQL_tree">Figure 6</a> that maps trade-off decisions to example applications and potentially suitable database systems. The leaf nodes cover applications ranging from simple caching (left) to Big Data analytics (right). Naturally, this view on the problem space is not complete, but it vaguely points towards a solution for a particular data management problem.</p><p>The first split in the tree is along the access pattern of applications: They either rely on fast lookups only (left half) or require more complex querying capabilities (right half). The fast lookup applications can be distinguished further by the data volume they process: If the main memory of one single machine can hold all the data, a single-node system like Redis or Memcache probably is the best choice, depending on whether functionality (Redis) or simplicity (Memcache) is favored. If the data volume is or might grow beyond RAM capacity or is even unbounded, a multi-node system that scales horizontally might be more appropriate. The most important decision in this case is whether to favor availability (AP) or consistency (CP) as described by the CAP theorem. Systems like Cassandra and Riak can deliver an always-on experience, while systems like HBase, MongoDB and DynamoDB deliver strong consistency.</p><p>The right half of the tree covers applications requiring more complex queries than simple lookups. Here, too, we first distinguish the systems by the data volume they have to handle according to whether single-node systems are feasible (HDD-size) or distribution is required (unbounded volume). For common OLTP (online transaction processing) workloads on moderately large data volumes, traditional RDBMSs or graph databases like Neo4J are optimal, because they offer ACID semantics. If, however, availability is of the essence, distributed systems like MongoDB, CouchDB or DocumentDB are preferrable.</p><p>If the data volume exceeds the limits of a single machine, the choice of the right system depends on the prevalent query pattern: When complex queries have to be optimised for latency, as for example in social networking applications, MongoDB is very attractive, because it facilitates expressive ad-hoc queries. HBase and Cassandra are also useful in such a scenario, but excel at throughput-optimised Big Data analytics, when combined with Hadoop.</p><p>In summary, we are convinced that the proposed top-down model is an effective decision support to filter the vast amount of NoSQL database systems based on central requirements. The NoSQL Toolbox furthermore provides a mapping from functional and non-functional requirements to common implementation techniques to categorize the constantly evolving NoSQL space.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iI7vzaOjFWWwZKtTaJCtXQ.png" /><figcaption>Table 2: A qualitative comparison of MongoDB, HBase, Cassandra, Riak and Redis.</figcaption></figure><p>Don’t want to miss our next post on NoSQL topics? Get it conveniently delivered to your inbox by <a href="http://www.baqend.com/#newsletter">joining our newsletter</a>.</p><p>If you want to cite this article, please use this<strong> </strong><a href="https://dblp.uni-trier.de/rec/html/journals/ife/GessertWFR17"><strong>DBLP reference</strong></a>:</p><pre>@article{DBLP:journals/ife/GessertWFR17,<br>  author    = {Felix Gessert and<br>               Wolfram Wingerath and<br>               Steffen Friedrich and<br>               Norbert Ritter},<br>  title     = {NoSQL database systems: a survey and decision guidance},<br>  journal   = {Computer Science - R{\&amp;}D},<br>  volume    = {32},<br>  number    = {3-4},<br>  pages     = {353--365},<br>  year      = {2017},<br>  doi       = {10.1007/s00450-016-0334-3}<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ea7823a822d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d">NoSQL Databases: a Survey and Decision Guidance</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular 2 & 4 by Example]]></title>
            <link>https://medium.com/baqend-blog/angular-2-by-example-e85a09fa6480?source=rss-233cc61c4b11------2</link>
            <guid isPermaLink="false">https://medium.com/p/e85a09fa6480</guid>
            <category><![CDATA[single-page-applications]]></category>
            <category><![CDATA[angular2]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[angularjs]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Felix Gessert]]></dc:creator>
            <pubDate>Tue, 09 Aug 2016 17:36:08 GMT</pubDate>
            <atom:updated>2017-06-06T17:41:57.972Z</atom:updated>
            <content:encoded><![CDATA[<p><strong><em>UPDATE</em>:</strong> This post was originally written to describe the new concepts of Angular 2. It is now <strong>updated to Angular 4</strong>. Note that all described concepts in this post work in both Angular 2 and 4.</p><p><a href="https://angular.io/"><strong>Angular</strong></a><strong> </strong>is one of the most talked-about JavaScript frameworks. In this transcript of a talk held at the <a href="http://www.meetup.com/de-DE/hamburg-js/events/232171453/">HH.JS meetup in Hamburg</a> we give our best to explain the major concepts of Angular using a real application you can play with: SPQR. It’s a collaborative platform for an audience to ask a speaker questions during a talk, and upvote the best of them. Also, it’s synchronized across users in <a href="https://www.baqend.com/guide/topics/realtime/"><strong>real-time</strong></a>.</p><figure><a href="http://plnkr.co/edit/ooymCq"><img alt="" src="https://cdn-images-1.medium.com/max/697/1*iTH5sB-Ur2FVtf04dKMe3g.png" /></a></figure><p>The <a href="http://plnkr.co/edit/ooymCq">code is hosted on Plunkr</a>, an online code editor similar to CodePen with support for Angular, <a href="https://www.typescriptlang.org/">TypeScript</a> and folder structures.</p><figure><a href="http://plnkr.co/edit/ooymCq"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l_bv8GVyByS5ked6gfDUdQ.png" /></a></figure><h3>Angular Basics</h3><p>Let’s start with what Angular is:</p><ul><li>A framework to build <strong>client-side</strong> applications</li><li>Code can be written in Typescript, ES6, Dart or JavaScript (without transpiling)</li><li>Has an expressive template language</li><li>Powerful data binding</li><li>Available as <strong>release 2.0.0 </strong>since<strong> </strong>14/09/2016 and <strong>release 4.0.0</strong> since 24/3/2017</li></ul><p>Okay, so another client-side framework for single page applications, but why?</p><ul><li>Fixes many performance pitfalls of Angular 1</li><li>Modern design using ES6 features, e.g.: Classes, Template strings</li><li>Simplified API and clearer concepts</li><li>Uses Typescript as the primary language for: <em>Interfaces, Type declarations, Decorators and Annotations</em></li></ul><h4>Project Setup</h4><p>For the SPQR app, we use a very simple project structure.</p><ul><li>We use System.js to load ES6 based modules directly in browser</li><li>Webpack is used to build a distribution</li><li>Typescript since it is the recommended language</li><li>Hosted on Baqend (<a href="http://plnkr.co/">http://baqend.com/</a>)</li></ul><h3>The building blocks of an Angular app</h3><p><strong>Components </strong>are the central abstraction of Angular. They are comprised of the template as well as controller methods and properties.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*pyhepFSXD_w87yflhEXKOA.png" /></figure><p>Of course, the heart of every MVC framework is its <strong>templating</strong>, i.e. describing how data is rendered. Angular supports three types of data binding:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*7pfciHnT1w6HQoDmUYZSeA.png" /></figure><p>The control flow of when and how often data is output is controlled via <strong>structural directives</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*7bJFQNTUsZAMYMNOeBqbaQ.png" /></figure><p>Angular.js 1 had this notion of magically binding data from <strong>form </strong>elements into your JavaScript model and back. Angular 2+ handles forms a little differently: you can trigger events from the form, accept data from the model, or both.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*SdJLRzetyq_Mx3dzz94Zng.png" /></figure><h3>Structuring application logic</h3><p>The main part of the business logic usually resides in <strong>services</strong>. They encapsulate functionality that is used across many components.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*aJogzwdj9CcEw-sfcvkUww.png" /></figure><p>To access simple formatting and transformation routines from the templates, <strong>pipes </strong>are used, e.g. to format a date.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*nA22cDO6xykWG1n6DMvHyg.png" /></figure><p><strong>Routers </strong>are used to control the flow through the application with meaningful URLs and a history.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*yQ0Q9bj1wjx3c6D4B8CpBA.png" /></figure><p>Routing is either triggered programmatically or by using <em>routerLink </em>instead of hrefs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*wflOtcMpofr98tQIaXXExg.png" /></figure><p>Components can <strong>subscribe </strong>to route changes to handle transitions more efficiently than redrawing the whole app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*FL7Wug-HRE0QS6LNb-dl0A.png" /></figure><h3>Extending the behaviour of HTML</h3><p><strong>Directives </strong>are the most scary concepts of Angular.js 1. In Agular 2+ they got way simpler. Directives are a clean and easy way to extend HTML with new elements or attributes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*IE7ylQu5_LeKCG6ItCUAFQ.png" /></figure><p>Model data can be the <strong>input </strong>of a directive.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*oZfkNvQPg8laDulwUivzKw.png" /></figure><p>And the directive can also <strong>output </strong>data, e.g. as events.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*n0iwjYwPwTULYuvaMwqqvA.png" /></figure><p>Two-way binding with directives is just a combination of an <strong>input </strong>and an <strong>output</strong>. Note, that the output property must have the same name as the input property with an appended <em>change </em>to work properly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*FOSaCve-_O1RRe4ijjK3tg.png" /></figure><h3>See these concepts in action!</h3><p>Now that you’ve seen all building blocks of Angular (Components, Pipes, Routers, Services, Directives), have a look at the <a href="http://plnkr.co/edit/ooymCq">SPQR app in Plunkr</a> or the hosted version on <a href="http://spqr.app.baqend.com/">Baqend</a>. Get the sources from <a href="https://github.com/Baqend/demo-spqr">GitHub</a>.</p><p>On the left you have all the project files, i.e. the components, the HTML etc. On the right you can directly play with the code and see the results.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OUtJHHgIs9b09XPKq7aIGQ.png" /></figure><p>If you’re starting from scratch, consider using our <a href="http://www.baqend.com/guide/starters/">Angular2 starter kit</a>. It’s hooked up to <a href="http://www.baqend.com/">Baqend</a>, a serverless backend designed to make the development of single page apps as easy and fast as possible.</p><p><a href="https://medium.com/baqend-blog/angular2-and-baqend-starter-e2082978ac92">Angular2 and Baqend Starter</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e85a09fa6480" width="1" height="1" alt=""><hr><p><a href="https://medium.com/baqend-blog/angular-2-by-example-e85a09fa6480">Angular 2 &amp; 4 by Example</a> was originally published in <a href="https://medium.com/baqend-blog">Speed Kit Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>