Files
nexus/sreweekly/articles/190/04-postgresql-connection-pooling-part-1-pros-cons.html
2026-09-12 17:23:01 +08:00

547 lines
39 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<title>PostgreSQL Connection Pooling: Part 1 – Pros &amp; Cons - 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/postgresql-connection-pooling-part-1-pros-cons/">
<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="PostgreSQL Connection Pooling: Part 1 – Pros &amp; Cons - High Scalability -">
<meta property="og:description" content="A long time ago, in a galaxy far far away, &amp;lsquo;threads&amp;rsquo; were a programming nov...">
<meta property="og:url" content="https://highscalability.com/postgresql-connection-pooling-part-1-pros-cons/">
<meta property="og:image" content="https://scalegrid.io/blog/wp-content/uploads/2019/09/PostgreSQL-Connection-Pooling-Part-1-Pros-and-Cons.jpg?__SQUARESPACE_CACHEVERSION&#x3D;1571332279615">
<meta property="article:published_time" content="2019-10-18T14:51:38.000Z">
<meta property="article:modified_time" content="2019-10-18T14:51:38.000Z">
<meta property="article:tag" content="Linux">
<meta property="article:tag" content="Database">
<meta property="article:tag" content="Postgres">
<meta property="article:tag" content="failure">
<meta property="article:tag" content="Performance">
<meta property="article:tag" content="open source">
<meta property="article:tag" content="application">
<meta property="article:tag" content="administrator">
<meta property="article:tag" content="cluster">
<meta property="article:tag" content="deployment">
<meta property="article:tag" content="architecture">
<meta property="article:tag" content="postgresql">
<meta property="article:tag" content="database performance online website">
<meta property="article:tag" content="multithreading">
<meta property="article:tag" content="Latency">
<meta property="article:tag" content="connection-pool">
<meta property="article:tag" content="multilanguage">
<meta property="article:tag" content="sql">
<meta property="article:tag" content="DevOps">
<meta property="article:tag" content="developer">
<meta property="article:tag" content="Connection Pooling">
<meta property="article:tag" content="Connection Pooler">
<meta property="article:tag" content="Multithreaded">
<meta property="article:tag" content="Language Library">
<meta property="article:tag" content="Web Applications">
<meta property="article:tag" content="Forking">
<meta property="article:publisher" content="https://www.facebook.com/ghost">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="PostgreSQL Connection Pooling: Part 1 – Pros &amp; Cons - High Scalability -">
<meta name="twitter:description" content="A long time ago, in a galaxy far far away, ‘threads’ were a programming novelty rarely used and seldom trusted. In that environment, the first PostgreSQL developers decided forking a process for each connection to the database is the safest choice. It would be a shame if your database crashed,">
<meta name="twitter:url" content="https://highscalability.com/postgresql-connection-pooling-part-1-pros-cons/">
<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="Kristi Anderson">
<meta name="twitter:label2" content="Filed under">
<meta name="twitter:data2" content="Linux, Database, Postgres, failure, Performance, open source, application, administrator, cluster, deployment, architecture, postgresql, database performance online website, multithreading, Latency, connection-pool, multilanguage, sql, DevOps, developer, Connection Pooling, Connection Pooler, Multithreaded, Language Library, Web Applications, Forking">
<meta name="twitter:site" content="@ghost">
<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": "Kristi Anderson",
"url": "https://highscalability.com/author/kristimke/",
"sameAs": []
},
"headline": "PostgreSQL Connection Pooling: Part 1 – Pros & Cons - High Scalability -",
"url": "https://highscalability.com/postgresql-connection-pooling-part-1-pros-cons/",
"datePublished": "2019-10-18T14:51:38.000Z",
"dateModified": "2019-10-18T14:51:38.000Z",
"keywords": "Linux, Database, Postgres, failure, Performance, open source, application, administrator, cluster, deployment, architecture, postgresql, database performance online website, multithreading, Latency, connection-pool, multilanguage, sql, DevOps, developer, Connection Pooling, Connection Pooler, Multithreaded, Language Library, Web Applications, Forking",
"description": "A long time ago, in a galaxy far far away, ‘threads’ were a programming novelty rarely used and seldom trusted. In that environment, the first PostgreSQL developers decided forking a process for each connection to the database is the safest choice. It would be a shame if your database crashed, after all.\n\nSince then, a lot of water has flown under that bridge, but the PostgreSQL community has stuck by their original decision. It is difficult to fault their argument – as it’s absolutely true that",
"mainEntityOfPage": "https://highscalability.com/postgresql-connection-pooling-part-1-pros-cons/"
}
</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="03b32ffb-914f-46c5-a68c-b125cec748f0" 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-linux tag-database tag-postgres tag-failure tag-performance tag-open-source tag-application tag-administrator tag-cluster tag-deployment tag-architecture tag-postgresql tag-database-performance-online-website tag-multithreading tag-latency tag-connection-pool tag-multilanguage tag-sql tag-devops tag-developer tag-connection-pooling tag-connection-pooler tag-multithreaded tag-language-library tag-web-applications tag-forking 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-linux tag-database tag-postgres tag-failure tag-performance tag-open-source tag-application tag-administrator tag-cluster tag-deployment tag-architecture tag-postgresql tag-database-performance-online-website tag-multithreading tag-latency tag-connection-pool tag-multilanguage tag-sql tag-devops tag-developer tag-connection-pooling tag-connection-pooler tag-multithreaded tag-language-library tag-web-applications tag-forking tag-hash-sqs no-image">
<header class="gh-article-header gh-canvas">
<a class="gh-article-tag" href="https://highscalability.com/tag/linux/">Linux</a>
<h1 class="gh-article-title is-title">UG9zdGdyZVNRTCBDb25uZWN0aW9uIFBvb2xpbmc6IFBhcnQgMSDigJMgUHJvcyAmIENvbnM&#x3D;
</h1>
<div class="gh-meta-share">
<div class="gh-article-meta">
<div class="gh-article-author-image instapaper_ignore">
<a href="/author/kristimke/"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M3.513 18.998C4.749 15.504 8.082 13 12 13s7.251 2.504 8.487 5.998C18.47 21.442 15.417 23 12 23s-6.47-1.558-8.487-4.002zM12 12c2.21 0 4-2.79 4-5s-1.79-4-4-4-4 1.79-4 4 1.79 5 4 5z" fill="#FFF"/></g></svg>
</a>
</div>
<div class="gh-article-meta-wrapper">
<h4 class="gh-article-author-name"><a href="/author/kristimke/">Kristi Anderson</a></h4>
<div class="gh-article-meta-content">
<time class="gh-article-meta-date" datetime="2019-10-18">18 Oct 2019</time>
<span class="gh-article-meta-length"><span class="bull">—</span> 4 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://scalegrid.io/blog/wp-content/uploads/2019/09/PostgreSQL-Connection-Pooling-Part-1-Pros-and-Cons.jpg?__SQUARESPACE_CACHEVERSION=1571332279615" class="kg-image" alt="PostgreSQL Connection Pooling: Part 1 – Pros &amp; Cons" loading="lazy"></figure><p>A long time ago, in a galaxy far far away, ‘threads’ were a programming novelty rarely used and seldom trusted. In that environment, the first <a href="https://scalegrid.io/postgresql.html?ref=highscalability.com">PostgreSQL</a> developers decided forking a process for each connection to the database is the safest choice. It would be a shame if your database crashed, after all.</p><p>Since then, a lot of water has flown under that bridge, but the PostgreSQL community has stuck by their original decision. It is difficult to fault <a href="https://www.postgresql.org/message-id/1098894087.31930.62.camel@localhost.localdomain?ref=highscalability.com">their argument</a> – as it’s absolutely true that:</p><ul><li>Each client having its own process prevents a poorly behaving client from crashing the entire database.</li><li>On modern Linux systems, the difference in overhead between forking a process and creating a thread is much lesser than it used to be.</li><li>Moving to a multithreaded architecture will require extensive rewrites.</li></ul><p>However, in modern web applications, clients tend to open a lot of connections. Developers are often strongly discouraged from holding a database connection while other operations take place. “Open a connection as late as possible, close a connection as soon as possible”. But that causes a problem with PostgreSQL’s architecture – forking a process becomes expensive when transactions are very short, as the common wisdom dictates they should be. In this post, we cover the <a href="https://scalegrid.io/blog/postgresql-connection-pooling-part-1-pros-and-cons/?ref=highscalability.com">pros and cons of PostgreSQL connection pooling</a>.</p><figure class="kg-card kg-image-card"><img src="https://scalegrid.io/blog/wp-content/uploads/2019/09/postgres_architecture.png" class="kg-image" alt="PostgreSQL Architecture Diagram" loading="lazy"></figure><p>The PostgreSQL Architecture | <a href="http://www.interdb.jp/pg/pgsql02.html?ref=highscalability.com">Source</a></p><h2 id="the-connection-pool-architecture">The Connection Pool Architecture</h2><p>Using a modern language library does reduce the problem somewhat – connection pooling is an essential feature of most popular database-access libraries. It ensures ‘closed’ connections are not really closed, but returned to a pool, and ‘opening’ a new connection returns the same ‘physical connection’ back, reducing the actual forking on the PostgreSQL side.</p><figure class="kg-card kg-image-card"><img src="https://scalegrid.io/blog/wp-content/uploads/2019/09/connection-pool-architecture.png" class="kg-image" alt="Visual Representation of a Connection Pool" loading="lazy"></figure><p>The architecture of a generic connection-pool</p><p>However, modern web applications are rarely monolithic, and often use multiple languages and technologies. Using a connection pool in each module is hardly efficient:</p><ul><li>Even with a relatively small number of modules, and a small pool size in each, you end up with a lot of server processes. Context-switching between them is costly.</li><li>The pooling support varies widely between libraries and languages – one badly behaving pool can consume all resources and leave the database inaccessible by other modules.</li><li>There is no centralized control – you cannot use measures like client-specific access limits.</li></ul><p>As a result, popular middlewares have been developed for PostgreSQL. These sit between the database and the clients, sometimes on a seperate server (physical or virtual) and sometimes on the same box, and create a pool that clients can connect to. These middleware are:</p><ul><li>Optimized for PostgreSQL and its rather unique architecture amongst modern DBMSes.</li><li>Provide centralized access control for diverse clients.</li><li>Allow you to reap the same rewards as client-side pools, and then some more (we will discuss these more in more detail in our next posts)!</li></ul><h2 id="postgresql-connection-pooler-cons">PostgreSQL Connection Pooler Cons</h2><p>A connection pooler is an almost indispensable part of a production-ready PostgreSQL setup. While there is plenty of well-documented benefits to using a connection pooler, there <em>are</em> some arguments to be made against using one:</p><ul><li>Introducing a middleware in the communication inevitably introduces some latency. However, when located on the same host, and factoring in the overhead of forking a connection, this is negligible in practice as we will see in the next section.</li><li>A middleware becomes a single point of failure. Using a cluster at this level can resolve this issue, but that introduces added complexity to the architecture.</li></ul><figure class="kg-card kg-image-card"><img src="https://scalegrid.io/blog/wp-content/uploads/2019/09/redundancy-in-middleware.png" class="kg-image" alt="Redundant pgBouncer instances to prevent single point of failure" loading="lazy"></figure><p>Redundancy in middleware to avoid Single-Point-of-Failure | <a href="https://medium.com/tech-hornet/postgres-and-rails-from-0-20-million-users-part-1-aef2f73a480e?ref=highscalability.com">Source</a><br><br></p><ul><li>A middleware implies extra costs. You either need an extra server (or 3), or your database server(s) must have enough resources to support a connection pooler, in addition to PostgreSQL.</li><li>Sharing connections between different modules can become a security vulnerability. It is very important that we configure pgPool or PgBouncer to clean connections before they are returned to the pool.</li><li>The authentication shifts from the DBMS to the connection pooler. This may not always be acceptable.</li></ul><figure class="kg-card kg-image-card"><img src="https://scalegrid.io/blog/wp-content/uploads/2019/09/PgBouncer-Authentication-Model.png" class="kg-image" alt="PgBouncer Authentication Model" loading="lazy"></figure><p>PgBouncer Authentication Model | <a href="https://www.cybertec-postgresql.com/en/pgbouncer-authentication-made-easy/?ref=highscalability.com">Source</a><br><br></p><ul><li>It increases the surface area for attack, unless access to the underlying database is locked down to allow access only via the connection pooler.</li><li>It creates yet another component that must be maintained, fine tuned for your workload, security patched often, and upgraded as required.</li></ul><h2 id="should-you-use-a-postgresql-connection-pooler">Should You Use a PostgreSQL Connection Pooler?</h2><p>However, all of these problems are well-discussed in the PostgreSQL community, and mitigation strategies ensure the pros of a connection pooler far exceed their cons. Our tests show that even a small number of clients can significantly benefit from using a connection pooler. They are well worth the added configuration and maintenance effort.</p><p>In the next post, we will discuss one of the most popular connection poolers in the PostgreSQL world – <a href="https://pgbouncer.github.io/?ref=highscalability.com">PgBouncer</a>, followed by <a href="https://www.pgpool.net/mediawiki/index.php/Main_Page?ref=highscalability.com">Pgpool-II</a>, and lastly a performance test comparison of these two PostgreSQL connection poolers in our final post of the series.</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="65bceaca3953980001659acd" 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&#39;t get a cab. That&#39;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>