536 lines
39 KiB
HTML
536 lines
39 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
|
||
<title>ButterCMS Architecture: a Mission-Critical API Serving Millions of Requests per Month - High Scalability -</title>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="preload" as="style" href="https://highscalability.com/assets/built/screen.css?v=QpNBjlSbNzyRyl6s">
|
||
<link rel="preload" as="script" href="https://highscalability.com/assets/built/source.js?v=uMULaSMoSjM4gY5C">
|
||
|
||
<link rel="preload" as="font" type="font/woff2" href="https://highscalability.com/assets/fonts/inter-roman.woff2?v=OecsB5TBLy27FKD2" crossorigin="anonymous">
|
||
<style>
|
||
@font-face {
|
||
font-family: "Inter";
|
||
font-style: normal;
|
||
font-weight: 100 900;
|
||
font-display: optional;
|
||
src: url(https://highscalability.com/assets/fonts/inter-roman.woff2?v=OecsB5TBLy27FKD2) format("woff2");
|
||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||
}
|
||
</style>
|
||
|
||
<link rel="stylesheet" type="text/css" href="https://highscalability.com/assets/built/screen.css?v=QpNBjlSbNzyRyl6s">
|
||
|
||
<style>
|
||
:root {
|
||
--background-color: #ffffff
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
/* The script for calculating the color contrast has been taken from
|
||
https://gomakethings.com/dynamically-changing-the-text-color-based-on-background-color-contrast-with-vanilla-js/ */
|
||
var accentColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color');
|
||
accentColor = accentColor.trim().slice(1);
|
||
|
||
if (accentColor.length === 3) {
|
||
accentColor = accentColor[0] + accentColor[0] + accentColor[1] + accentColor[1] + accentColor[2] + accentColor[2];
|
||
}
|
||
|
||
var r = parseInt(accentColor.substr(0, 2), 16);
|
||
var g = parseInt(accentColor.substr(2, 2), 16);
|
||
var b = parseInt(accentColor.substr(4, 2), 16);
|
||
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
||
var textColor = (yiq >= 128) ? 'dark' : 'light';
|
||
|
||
document.documentElement.className = `has-${textColor}-text`;
|
||
</script>
|
||
|
||
<link rel="canonical" href="https://highscalability.com/buttercms-architecture-a-mission-critical-api-serving-millio/">
|
||
<meta name="referrer" content="no-referrer-when-downgrade">
|
||
|
||
<meta property="og:site_name" content="High Scalability">
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:title" content="ButterCMS Architecture: a Mission-Critical API Serving Millions of Requests per Month - High Scalability -">
|
||
<meta property="og:description" content="This is a guest post by Jake Lumetta , co-founder and CEO of ButterCMS .
|
||
|
||
ButterCMS lets deve...">
|
||
<meta property="og:url" content="https://highscalability.com/buttercms-architecture-a-mission-critical-api-serving-millio/">
|
||
<meta property="og:image" content="https://c1.staticflickr.com/5/4485/37735288901_1059b76043_m.jpg">
|
||
<meta property="article:published_time" content="2017-10-16T14:56:17.000Z">
|
||
<meta property="article:modified_time" content="2017-10-16T14:56:17.000Z">
|
||
<meta property="article:tag" content="Example">
|
||
|
||
<meta property="article:publisher" content="https://www.facebook.com/ghost">
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:title" content="ButterCMS Architecture: a Mission-Critical API Serving Millions of Requests per Month - High Scalability -">
|
||
<meta name="twitter:description" content="This is a guest post by Jake Lumetta, co-founder and CEO of ButterCMS.
|
||
|
||
ButterCMS lets developers add a content management system to any website in minutes. Our business requires us to deliver near-100% uptime for our API, but after multiple outages that nearly crippled our business, we became">
|
||
<meta name="twitter:url" content="https://highscalability.com/buttercms-architecture-a-mission-critical-api-serving-millio/">
|
||
<meta name="twitter:image" content="https://static.ghost.org/v5.0.0/images/publication-cover.jpg">
|
||
<meta name="twitter:label1" content="Written by">
|
||
<meta name="twitter:data1" content="High Scalability">
|
||
<meta name="twitter:label2" content="Filed under">
|
||
<meta name="twitter:data2" content="Example">
|
||
<meta name="twitter:site" content="@ghost">
|
||
<meta name="twitter:creator" content="@highscal">
|
||
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "Article",
|
||
"publisher": {
|
||
"@type": "Organization",
|
||
"name": "High Scalability",
|
||
"url": "https://highscalability.com/",
|
||
"logo": {
|
||
"@type": "ImageObject",
|
||
"url": "https://highscalability.com/favicon.ico",
|
||
"width": 48,
|
||
"height": 48
|
||
}
|
||
},
|
||
"author": {
|
||
"@type": "Person",
|
||
"name": "High Scalability",
|
||
"image": {
|
||
"@type": "ImageObject",
|
||
"url": "https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/2024/03/hs.jpeg",
|
||
"width": 400,
|
||
"height": 400
|
||
},
|
||
"url": "https://highscalability.com/author/hs/",
|
||
"sameAs": [
|
||
"https://blog.bytebytego.com/",
|
||
"https://x.com/highscal"
|
||
]
|
||
},
|
||
"headline": "ButterCMS Architecture: a Mission-Critical API Serving Millions of Requests per Month - High Scalability -",
|
||
"url": "https://highscalability.com/buttercms-architecture-a-mission-critical-api-serving-millio/",
|
||
"datePublished": "2017-10-16T14:56:17.000Z",
|
||
"dateModified": "2017-10-16T14:56:17.000Z",
|
||
"keywords": "Example",
|
||
"description": "This is a guest post by Jake Lumetta, co-founder and CEO of ButterCMS.\n\nButterCMS lets developers add a content management system to any website in minutes. Our business requires us to deliver near-100% uptime for our API, but after multiple outages that nearly crippled our business, we became obsessed with eliminating single points of failure. In this post, I’ll discuss how we use Fastly’s edge cloud platform and other strategies to make sure we keep our customers’ websites up and running.\n\nAt ",
|
||
"mainEntityOfPage": "https://highscalability.com/buttercms-architecture-a-mission-critical-api-serving-millio/"
|
||
}
|
||
</script>
|
||
|
||
<meta name="generator" content="Ghost 6.64">
|
||
<link rel="alternate" type="application/rss+xml" title="High Scalability" href="https://highscalability.com/rss/">
|
||
<script defer src="https://cdn.jsdelivr.net/ghost/portal@~2.71/umd/portal.min.js" data-i18n="true" data-ghost="https://highscalability.com/" data-key="e7388272b3fcb33a0abfc2f95c" data-api="https://high-scalability.ghost.io/ghost/api/content/" data-locale="en" crossorigin="anonymous"></script><style id="gh-members-styles">.gh-post-upgrade-cta-content,
|
||
.gh-post-upgrade-cta {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||
text-align: center;
|
||
width: 100%;
|
||
color: #ffffff;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.gh-post-upgrade-cta-content {
|
||
border-radius: 8px;
|
||
padding: 40px 4vw;
|
||
}
|
||
|
||
.gh-post-upgrade-cta h2 {
|
||
color: #ffffff;
|
||
font-size: 28px;
|
||
letter-spacing: -0.2px;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.gh-post-upgrade-cta p {
|
||
margin: 20px 0 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.gh-post-upgrade-cta small {
|
||
font-size: 16px;
|
||
letter-spacing: -0.2px;
|
||
}
|
||
|
||
.gh-post-upgrade-cta a {
|
||
color: #ffffff;
|
||
cursor: pointer;
|
||
font-weight: 500;
|
||
box-shadow: none;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.gh-post-upgrade-cta a:hover {
|
||
color: #ffffff;
|
||
opacity: 0.8;
|
||
box-shadow: none;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.gh-post-upgrade-cta a.gh-btn {
|
||
display: block;
|
||
background: #ffffff;
|
||
text-decoration: none;
|
||
margin: 28px 0 0;
|
||
padding: 8px 18px;
|
||
border-radius: 4px;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.gh-post-upgrade-cta a.gh-btn:hover {
|
||
opacity: 0.92;
|
||
}</style>
|
||
<script defer src="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/sodo-search.min.js" data-key="e7388272b3fcb33a0abfc2f95c" data-styles="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/main.css" data-sodo-search="https://high-scalability.ghost.io/" data-locale="en" crossorigin="anonymous"></script>
|
||
|
||
<link href="https://highscalability.com/webmentions/receive/" rel="webmention">
|
||
<script defer src="/public/cards.min.js?v=ShRHxgy4po8zN-Wf"></script>
|
||
<link rel="stylesheet" type="text/css" href="/public/cards.min.css?v=WwnU9jw5ancNC8Gc">
|
||
<script defer src="/public/comment-counts.min.js?v=oFYkaGLdiMqB8VN9" data-ghost-comments-counts-api="https://highscalability.com/members/api/comments/counts/"></script>
|
||
<script defer src="/public/member-attribution.min.js?v=AKG4hWena9j3yX3I"></script>
|
||
<script defer src="/public/ghost-stats.min.js?v=vFcCUf6ZQ0Hyhc8h" data-stringify-payload="false" data-datasource="analytics_events" data-storage="localStorage" data-host="https://highscalability.com/.ghost/analytics/api/v1/page_hit" tb_site_uuid="647204cd-7ad2-4539-b98a-3489074b932d" tb_post_uuid="fc809010-3c4e-40f9-bbe2-3544e6ead695" tb_post_type="post" tb_member_uuid="undefined" tb_member_status="undefined" tb_gift_link=""></script><style>:root {--ghost-accent-color: #35cea0;}</style>
|
||
<!-- Fathom - beautiful, simple website analytics -->
|
||
<script src="https://cdn.usefathom.com/script.js" data-site="XBRJSZNU" defer></script>
|
||
<!-- / Fathom -->
|
||
<style>
|
||
/* Hide feature image on single post page in Source theme */
|
||
.post-template .gh-article-image {
|
||
display: none;
|
||
}
|
||
.gh-footer-copyright { display: none; }
|
||
</style>
|
||
|
||
</head>
|
||
<body class="post-template tag-example tag-hash-sqs has-sans-title has-sans-body">
|
||
|
||
<div class="gh-viewport">
|
||
|
||
<header id="gh-navigation" class="gh-navigation is-middle-logo gh-outer">
|
||
<div class="gh-navigation-inner gh-inner">
|
||
|
||
<div class="gh-navigation-brand">
|
||
<a class="gh-navigation-logo is-title" href="https://highscalability.com">
|
||
High Scalability
|
||
</a>
|
||
<button class="gh-search gh-icon-button" aria-label="Search this site" data-ghost-search>
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button> <button class="gh-burger gh-icon-button" aria-label="Menu">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path></svg> </button>
|
||
</div>
|
||
|
||
<nav class="gh-navigation-menu">
|
||
<ul class="nav">
|
||
<li class="nav-home"><a href="https://highscalability.com/">Home</a></li>
|
||
<li class="nav-system-design-interview-course"><a href="https://bit.ly/hishscalcourse">System Design Interview Course</a></li>
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
<div class="gh-navigation-actions">
|
||
<button class="gh-search gh-icon-button" aria-label="Search this site" data-ghost-search>
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button> <div class="gh-navigation-members">
|
||
<a href="#/portal/signin" data-portal="signin">Sign in</a>
|
||
<a class="gh-button" href="#/portal/signup" data-portal="signup">Subscribe</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</header>
|
||
|
||
|
||
|
||
<main class="gh-main">
|
||
|
||
<article class="gh-article post tag-example tag-hash-sqs no-image">
|
||
|
||
<header class="gh-article-header gh-canvas">
|
||
|
||
<a class="gh-article-tag" href="https://highscalability.com/tag/example/">Example</a>
|
||
<h1 class="gh-article-title is-title">ButterCMS Architecture: a Mission-Critical API Serving Millions of Requests per Month</h1>
|
||
|
||
<div class="gh-meta-share">
|
||
<div class="gh-article-meta">
|
||
<div class="gh-article-author-image instapaper_ignore">
|
||
<a href="/author/hs/">
|
||
<img class="author-profile-image" src="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w160/2024/03/hs.jpeg" alt="High Scalability">
|
||
</a>
|
||
</div>
|
||
<div class="gh-article-meta-wrapper">
|
||
<h4 class="gh-article-author-name"><a href="/author/hs/">High Scalability</a></h4>
|
||
<div class="gh-article-meta-content">
|
||
<time class="gh-article-meta-date" datetime="2017-10-16">16 Oct 2017</time>
|
||
<span class="gh-article-meta-length"><span class="bull">—</span> 5 min read</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a href="#/share" class="gh-button gh-button-share">
|
||
Share
|
||
</a>
|
||
</div>
|
||
|
||
|
||
</header>
|
||
|
||
<section class="gh-content gh-canvas is-body">
|
||
<figure class="kg-card kg-image-card"><img src="https://c1.staticflickr.com/5/4485/37735288901_1059b76043_m.jpg" class="kg-image" alt loading="lazy"></figure><p><em>This is a guest post by <a href="https://twitter.com/jakelumetta?ref=highscalability.com">Jake Lumetta</a>, co-founder and CEO of <a href="https://buttercms.com/?ref=highscalability.com">ButterCMS</a>.</em></p><p><a href="https://buttercms.com/?ref=highscalability.com">ButterCMS</a> lets developers add a content management system to any website in minutes. Our business requires us to deliver near-100% uptime for our API, but after multiple outages that nearly crippled our business, we became obsessed with eliminating single points of failure. In this post, I’ll discuss how we use <a href="https://www.fastly.com/?ref=highscalability.com">Fastly</a>’s edge cloud platform and other strategies to make sure we keep our customers’ websites up and running.</p><p>At its core, ButterCMS offers:</p><p>A dashboard for content editors</p><p>A <a href="https://buttercms.com/docs/api/?ref=highscalability.com">JSON API</a> for fetching content</p><p><a href="https://github.com/buttercms?ref=highscalability.com">SDK’s for integrating ButterCMS</a> into native code</p><h2 id="buttercms-tech-stack">ButterCMS Tech Stack</h2><p>ButterCMS is a single monolithic Django application that is responsible for the marketing website, editing tools, API, and backoffice tools for customer support. The Django application runs on Heroku along with a Postgres database.</p><p>We also utilize the following 3rd-party services:</p><p><a href="https://www.filestack.com/?ref=highscalability.com">Filestack</a> for providing their customers image editing</p><p><a href="https://www.fastly.com/?ref=highscalability.com">Fastly</a> for external API caching and delivery</p><p><a href="https://aws.amazon.com/cloudfront/?ref=highscalability.com">Cloudfront</a> as a CDN for customers’ assets</p><p><a href="https://www.easydns.com/?ref=highscalability.com">EasyDNS</a> for DNS</p><h2 id="downtime-is-fatal">Downtime is Fatal</h2><p>Our customers typically build websites that make an API request to ButterCMS for page content during their request/response lifecycle. This means that if their API request to ButterCMS fails, their page likely won’t render. If our API goes down, our customers’ websites go down with us.</p><p>This is a lesson we learned the hard way in our early days. Unreliable server hosting led to frequent intermittent outages and performance degradations that frustrated customers. A botched DNS migration led to hours of API downtime that took down dozens of customers’ websites for nearly half a day and left a large number of customers questioning whether they could continue relying on us (a handful of them left us).</p><p>After this incident, we recognized that ensuring near-100% uptime was an existential issue. A significant outage in the future could lead to us losing hard-earned customers and put our business in crisis.</p><h2 id="delivering-a-global-fast-resilient-api">Delivering a Global, Fast, Resilient API</h2><p>Avoiding failure completely is not possible–you can only do your best to reduce your chances.</p><p>For example, “controlling your own fate” by running your own physical servers protects you against your hosting provider going down, but puts you in the position of having to handle security and scalability, both of which can easily take you down and be difficult to recover from.</p><p>For our team, keeping our API up at all times and making sure it delivered high performance across the globe was crucial. But as a smaller company, we knew we didn’t have the resources to deliver global, highly scalable performance with near-100% uptime. So we turned to someone that did: <a href="https://www.fastly.com/?ref=highscalability.com">Fastly</a>.</p><p>Fastly describes itself as an “edge cloud platform powers fast, secure, and scalable digital experiences for the world's most popular businesses”. They work with large customers including the New York Times, BuzzFeed, Pinterest, and New Relic. We put Fastly in front of our API as a cache layer so that all API requests are served via their CDN.</p><figure class="kg-card kg-image-card"><img src="https://lh6.googleusercontent.com/zhkgWKOLcF3BVt3QNswbOWHgsLdr_6dOZt_kdjEaO2Kh-hVjeccPfKBI4mKSraBu_pN-QdjeayIKDg2DoN6nvbVDlLywRA75Jss0pTpwZcZazggsUin4AtXZgwIZ1LXkOAbF2NI" class="kg-image" alt loading="lazy" width="624" height="311"></figure><p>When one of our customers updates their website content in ButterCMS, we invalidate the API keys for the specific bits of content that were edited. Non-cached requests hit our servers but we have a 94% hit rate because content on our customers’ websites changes infrequently, relative to the number of visitors they get. This means that even if our database or servers experience intermittent outages, our API remains up. We wouldn’t want this, but theoretically, our servers could go down completely for several hours and our customers’ websites would stay up so long as Fastly was.</p><p>Fastly’s global CDN offers another benefit to us. Many of our customers have static JavaScript websites where API requests are made from their visitors’ browsers rather than their servers. Serving API responses via Fastly’s CDN means that our customers’ website visitors get fast load times wherever they’re located.</p><h2 id="eliminating-single-points-of-failure">Eliminating single points of failure</h2><p>During the early days of ButterCMS, we dealt with two separate DNS incidents that left us scarred. In the first incident, our DNS provider at the time accidentally “cancelled” our account from their system, leading to an outage that took nearly 6 hours for us to fully recover from. Our second incident occurred when routine DNS editing led to a malfunction by our [different] DNS provider, and took nearly half a day to resolve. DNS incidents are particularly damaging because even after an issue is identified and fixed, you have to wait for various DNS servers and ISP’s to clear their caches before customers’ see the fix on their end (DNS servers also tend to ignore your TTL setting and impose their own policy).</p><p>Our experiences made us extremely focused on eliminating any single point of failure across our architecture.</p><p>For DNS, we switched to using multiple nameservers from different DNS providers. DNS providers often allow and encourage you to use 4-6 redundant nameservers (eg. ns1.example.com, ns2.example.com). This is great: if one fails, requests will still be resolved by the others. But since all of your nameservers are from a single company, you’re putting a lot of faith that they are going to have 100% uptime.</p><p>For our application servers, we use Heroku’s monitoring and <a href="https://blog.heroku.com/heroku-autoscaling?ref=highscalability.com">auto-scaling</a> tools to make sure our performance doesn’t degrade from spikes in traffic (or if Fastly goes down and we suddenly need to route all requests directly to our servers). In addition to caching our API with Fastly, we also cache our API at the application level using Memcached. This provides an additional layer of buffer against intermittent database or server failure.</p><p>To protect against the rare possibly of a total outage across Heroku or AWS (which Heroku runs on), we maintain a separate server and database instance running on Google Cloud that we can failover to quickly.</p><h2 id="failure-is-inevitable">Failure is inevitable</h2><p>No matter how reliable our API is, we have to accept that networks are <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing?ref=highscalability.com">unreliable</a> and failures are bound to occur. We’ve all experienced trouble connecting to Wi-Fi, or had a phone call drop on us abruptly. Outages, routing problems, and other intermittent failures may be statistically unusual on the whole, but still bound to be happening all the time at some ambient background rate.</p><p>To overcome this sort of inherently unreliable environment, we help our customers build applications that will be robust in the event of failure. Our SDK’s offer features such as <a href="https://github.com/ButterCMS/buttercms-csharp/pull/2?ref=highscalability.com">automatically retrying when API requests fail</a>, or <a href="https://github.com/ButterCMS/buttercms-ruby?ref=highscalability.com#fallback-data-store">support for easily using a failover cache</a> such as Redis on the client.</p><h2 id="conclusion">Conclusion</h2><p>Without realizing it, many of us are building single points of failure into our stack. At ButterCMS, our success depends on ensuring that our customers applications don’t ever go down because of us. We do this by eliminating as many single points of failure as possible from our back-end infrastructure, and providing SDK’s that make it easy for our customers to achieve resiliency and fault-tolerance within their applications.</p><h3 id="about-buttercms">About ButterCMS</h3><p>When you hear “CMS” or “blogging”, you probably think of WordPress. ButterCMS is a newer alternative that allows development teams to add CMS and blogging functionality into their own native codebases using the ButterCMS API.</p><p>ButterCMS was started by <a href="https://twitter.com/jakelumetta?ref=highscalability.com">Jake Lumetta</a> and <a href="https://twitter.com/abi?ref=highscalability.com">Abi Noda</a> because both of them had encountered the challenge of finding alternatives to WordPress that were fully featured, flexible, and didn’t bind you to a specific programming language like PHP..</p><p>Today, ButterCMS powers hundreds of websites across the world, helping serve millions of requests per month.</p>
|
||
</section>
|
||
|
||
</article>
|
||
|
||
<div class="gh-comments gh-canvas">
|
||
|
||
<script defer src="https://cdn.jsdelivr.net/ghost/comments-ui@~1.6/umd/comments-ui.min.js" data-locale="en" data-ghost-comments="https://highscalability.com/" data-api="https://high-scalability.ghost.io/ghost/api/content/" data-admin="https://high-scalability.ghost.io/ghost/" data-key="e7388272b3fcb33a0abfc2f95c" data-title="null" data-count="true" data-post-id="65bceaca3953980001659a0c" data-color-scheme="auto" data-avatar-saturation="60" data-accent-color="#35cea0" data-comments-enabled="all" data-publication="High Scalability" crossorigin="anonymous"></script>
|
||
|
||
</div>
|
||
|
||
</main>
|
||
|
||
|
||
<section class="gh-container is-grid gh-outer">
|
||
<div class="gh-container-inner gh-inner">
|
||
<h2 class="gh-container-title">Read more</h2>
|
||
<div class="gh-feed">
|
||
<article class="gh-card post">
|
||
<a class="gh-card-link" href="/untitled-2/">
|
||
<figure class="gh-card-image">
|
||
<img
|
||
srcset="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w160/format/webp/2024/05/pasted-image-0-2.png 160w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w320/format/webp/2024/05/pasted-image-0-2.png 320w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/format/webp/2024/05/pasted-image-0-2.png 600w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w960/format/webp/2024/05/pasted-image-0-2.png 960w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w1200/format/webp/2024/05/pasted-image-0-2.png 1200w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w2000/format/webp/2024/05/pasted-image-0-2.png 2000w"
|
||
sizes="320px"
|
||
src="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/2024/05/pasted-image-0-2.png"
|
||
alt="Kafka 101"
|
||
loading="lazy"
|
||
>
|
||
</figure>
|
||
<div class="gh-card-wrapper">
|
||
<h3 class="gh-card-title is-title">Kafka 101</h3>
|
||
<p class="gh-card-excerpt is-body">This is a guest article by Stanislav Kozlovski, an Apache Kafka Committer. If you would like to connect with Stanislav, you can do so on Twitter and LinkedIn.
|
||
|
||
Originally developed in LinkedIn during 2011, Apache Kafka is one of the most popular open-source Apache projects out there. So far</p>
|
||
<footer class="gh-card-meta">
|
||
<!--
|
||
-->
|
||
<span class="gh-card-author">By ByteByteGo</span>
|
||
<time class="gh-card-date" datetime="2024-05-09">09 May 2024</time>
|
||
<!--
|
||
--></footer>
|
||
</div>
|
||
</a>
|
||
</article>
|
||
<article class="gh-card post">
|
||
<a class="gh-card-link" href="/capturing-a-billion-emo-j-i-ons/">
|
||
<figure class="gh-card-image">
|
||
<img
|
||
srcset="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w160/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 160w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w320/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 320w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 600w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w960/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 960w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w1200/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 1200w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w2000/format/webp/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif 2000w"
|
||
sizes="320px"
|
||
src="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/2024/03/1-rSRWALA4XzOdDcn-5vv7Zw.gif"
|
||
alt="Capturing A Billion Emo(j)i-ons"
|
||
loading="lazy"
|
||
>
|
||
</figure>
|
||
<div class="gh-card-wrapper">
|
||
<h3 class="gh-card-title is-title">Capturing A Billion Emo(j)i-ons</h3>
|
||
<p class="gh-card-excerpt is-body">This blog post was written by Dedeepya Bonthu. This is a repost from her Medium article, approved by the author.
|
||
|
||
In stadiums, sports fans love to express themselves by cheering for their favorite teams, holding up placards and team logos. Emoji’s allow fans at home to rapidly express themselves,</p>
|
||
<footer class="gh-card-meta">
|
||
<!--
|
||
-->
|
||
<span class="gh-card-author">By ByteByteGo</span>
|
||
<time class="gh-card-date" datetime="2024-03-26">26 Mar 2024</time>
|
||
<!--
|
||
--></footer>
|
||
</div>
|
||
</a>
|
||
</article>
|
||
<article class="gh-card post">
|
||
<a class="gh-card-link" href="/brief-history-of-scaling-uber/">
|
||
<figure class="gh-card-image">
|
||
<img
|
||
srcset="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w160/format/webp/2026/03/1704993859593.png 160w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w320/format/webp/2026/03/1704993859593.png 320w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/format/webp/2026/03/1704993859593.png 600w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w960/format/webp/2026/03/1704993859593.png 960w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w1200/format/webp/2026/03/1704993859593.png 1200w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w2000/format/webp/2026/03/1704993859593.png 2000w"
|
||
sizes="320px"
|
||
src="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/2026/03/1704993859593.png"
|
||
alt="Brief History of Scaling Uber"
|
||
loading="lazy"
|
||
>
|
||
</figure>
|
||
<div class="gh-card-wrapper">
|
||
<h3 class="gh-card-title is-title">Brief History of Scaling Uber</h3>
|
||
<p class="gh-card-excerpt is-body">This blog post was written by Josh Clemm, Senior Director of Engineering at Uber Eats. This is a repost from his LinkedIn article, approved by the author.
|
||
|
||
On a cold evening in Paris in 2008, Travis Kalanick and Garrett Camp couldn't get a cab. That's when</p>
|
||
<footer class="gh-card-meta">
|
||
<!--
|
||
-->
|
||
<span class="gh-card-author">By ByteByteGo</span>
|
||
<time class="gh-card-date" datetime="2024-03-14">14 Mar 2024</time>
|
||
<!--
|
||
--></footer>
|
||
</div>
|
||
</a>
|
||
</article>
|
||
<article class="gh-card post">
|
||
<a class="gh-card-link" href="/behind-aws-s3s-massive-scale/">
|
||
<figure class="gh-card-image">
|
||
<img
|
||
srcset="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w160/format/webp/2024/03/7.png 160w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w320/format/webp/2024/03/7.png 320w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/format/webp/2024/03/7.png 600w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w960/format/webp/2024/03/7.png 960w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w1200/format/webp/2024/03/7.png 1200w,
|
||
https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w2000/format/webp/2024/03/7.png 2000w"
|
||
sizes="320px"
|
||
src="https://storage.ghost.io/c/64/72/647204cd-7ad2-4539-b98a-3489074b932d/content/images/size/w600/2024/03/7.png"
|
||
alt="Behind AWS S3’s Massive Scale"
|
||
loading="lazy"
|
||
>
|
||
</figure>
|
||
<div class="gh-card-wrapper">
|
||
<h3 class="gh-card-title is-title">Behind AWS S3’s Massive Scale</h3>
|
||
<p class="gh-card-excerpt is-body">This is a guest article by Stanislav Kozlovski, an Apache Kafka Committer. If you would like to connect with Stanislav, you can do so on Twitter and LinkedIn.
|
||
|
||
AWS S3 is a service every engineer is familiar with.
|
||
|
||
It’s the service that popularized the notion of cold-storage to</p>
|
||
<footer class="gh-card-meta">
|
||
<!--
|
||
-->
|
||
<span class="gh-card-author">By ByteByteGo</span>
|
||
<time class="gh-card-date" datetime="2024-03-06">06 Mar 2024</time>
|
||
<!--
|
||
--></footer>
|
||
</div>
|
||
</a>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<footer class="gh-footer gh-outer">
|
||
<div class="gh-footer-inner gh-inner">
|
||
|
||
<section class="gh-footer-signup">
|
||
<h2 class="gh-footer-signup-header is-title">
|
||
High Scalability
|
||
</h2>
|
||
<p class="gh-footer-signup-subhead is-body">
|
||
Building bigger, faster, more reliable websites.
|
||
</p>
|
||
<form class="gh-form" data-members-form>
|
||
<input class="gh-form-input" id="footer-email" name="email" type="email" placeholder="jamie@example.com" required data-members-email>
|
||
<button class="gh-button" type="submit" aria-label="Subscribe">
|
||
<span><span>Subscribe</span> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z"></path></svg></span>
|
||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24">
|
||
<g stroke-linecap="round" stroke-width="2" fill="currentColor" stroke="none" stroke-linejoin="round" class="nc-icon-wrapper">
|
||
<g class="nc-loop-dots-4-24-icon-o">
|
||
<circle cx="4" cy="12" r="3"></circle>
|
||
<circle cx="12" cy="12" r="3"></circle>
|
||
<circle cx="20" cy="12" r="3"></circle>
|
||
</g>
|
||
<style data-cap="butt">
|
||
.nc-loop-dots-4-24-icon-o{--animation-duration:0.8s}
|
||
.nc-loop-dots-4-24-icon-o *{opacity:.4;transform:scale(.75);animation:nc-loop-dots-4-anim var(--animation-duration) infinite}
|
||
.nc-loop-dots-4-24-icon-o :nth-child(1){transform-origin:4px 12px;animation-delay:-.3s;animation-delay:calc(var(--animation-duration)/-2.666)}
|
||
.nc-loop-dots-4-24-icon-o :nth-child(2){transform-origin:12px 12px;animation-delay:-.15s;animation-delay:calc(var(--animation-duration)/-5.333)}
|
||
.nc-loop-dots-4-24-icon-o :nth-child(3){transform-origin:20px 12px}
|
||
@keyframes nc-loop-dots-4-anim{0%,100%{opacity:.4;transform:scale(.75)}50%{opacity:1;transform:scale(1)}}
|
||
</style>
|
||
</g>
|
||
</svg> <span>Email sent</span>
|
||
</button>
|
||
<p data-members-error></p>
|
||
</form>
|
||
</section>
|
||
|
||
<div class="gh-social-links">
|
||
<a href="https://x.com/ghost" target="_blank" rel="noopener" aria-label="X">
|
||
<svg viewBox="0 0 24 24" fill="currentColor"><g><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></g></svg> </a>
|
||
<a href="https://www.facebook.com/ghost" target="_blank" rel="noopener" aria-label="Facebook">
|
||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M23.9981 11.9991C23.9981 5.37216 18.626 0 11.9991 0C5.37216 0 0 5.37216 0 11.9991C0 17.9882 4.38789 22.9522 10.1242 23.8524V15.4676H7.07758V11.9991H10.1242V9.35553C10.1242 6.34826 11.9156 4.68714 14.6564 4.68714C15.9692 4.68714 17.3424 4.92149 17.3424 4.92149V7.87439H15.8294C14.3388 7.87439 13.8739 8.79933 13.8739 9.74824V11.9991H17.2018L16.6698 15.4676H13.8739V23.8524C19.6103 22.9522 23.9981 17.9882 23.9981 11.9991Z"/></svg> </a>
|
||
</div>
|
||
|
||
<div class="gh-footer-bar">
|
||
<span class="gh-footer-logo is-title">
|
||
High Scalability
|
||
</span>
|
||
<nav class="gh-footer-menu">
|
||
<ul class="nav">
|
||
<li class="nav-sign-up"><a href="#/portal/">Sign up</a></li>
|
||
</ul>
|
||
|
||
</nav>
|
||
<div class="gh-footer-copyright">
|
||
Powered by <a href="https://ghost.org/" target="_blank" rel="noopener">Ghost</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||
<div class="pswp__bg"></div>
|
||
|
||
<div class="pswp__scroll-wrap">
|
||
<div class="pswp__container">
|
||
<div class="pswp__item"></div>
|
||
<div class="pswp__item"></div>
|
||
<div class="pswp__item"></div>
|
||
</div>
|
||
|
||
<div class="pswp__ui pswp__ui--hidden">
|
||
<div class="pswp__top-bar">
|
||
<div class="pswp__counter"></div>
|
||
|
||
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
|
||
<button class="pswp__button pswp__button--share" title="Share"></button>
|
||
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
|
||
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
|
||
|
||
<div class="pswp__preloader">
|
||
<div class="pswp__preloader__icn">
|
||
<div class="pswp__preloader__cut">
|
||
<div class="pswp__preloader__donut"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||
<div class="pswp__share-tooltip"></div>
|
||
</div>
|
||
|
||
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button>
|
||
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button>
|
||
|
||
<div class="pswp__caption">
|
||
<div class="pswp__caption__center"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script src="https://highscalability.com/assets/built/source.js?v=uMULaSMoSjM4gY5C"></script>
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|