Files
nexus/sreweekly/articles/36/08-serverless-architectures.html
2026-09-12 17:23:01 +08:00

2356 lines
130 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><meta charset="UTF-8">
<title>Serverless Architectures</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /><script defer src="https://cloud.umami.is/script.js" data-website-id="eb12527f-b713-4afa-905a-8a50f8a7f157"></script>
<meta content = 'summary_large_image' name = 'twitter:card'></meta>
<meta content = '16665197' name = 'twitter:site:id'></meta>
<meta content = '@martinfowler' name = 'twitter:site'></meta>
<meta content = 'Serverless Architectures' property = 'og:title'></meta>
<meta content = 'https://martinfowler.com/articles/serverless.html' property = 'og:url'></meta>
<meta content = 'Serverless architectures replace a managed server with a collection of third party services and FaaS' property = 'og:description'></meta>
<meta content = 'https://martinfowler.com/articles/serverless/sps.png' property = 'og:image'></meta>
<meta content = 'martinfowler.com' property = 'og:site_name'></meta>
<meta content = 'article' property = 'og:type'></meta>
<meta content = '2018-05-22' property = 'og:article:modified_time'></meta>
<meta content = 'width=device-width, initial-scale=1' name = 'viewport'></meta>
<link href = 'serverless.css' rel = 'stylesheet' type = 'text/css'></link>
</head>
<body><header id = 'banner' style = 'background-image: url("/img/zakim.png"); background-repeat: no-repeat'>
<div class = 'name-logo'><a href = 'https://martinfowler.com'><img src = '/mf-name-white.png'></img></a></div>
<div class = 'search'>
<!-- SiteSearch Google -->
<form method='GET' action="https://www.google.com/search">
<input type='hidden' name='ie' value='UTF-8'/>
<input type='hidden' name='oe' value='UTF-8'/>
<input class = 'field' type='text'
name='q' size='15' maxlength='255' value=""/>
<button class = 'button' type='submit'
name='btnG' value=" " title = "Search"/>
<input type='hidden' name='domains' value="martinfowler.com"/>
<input type='hidden' name='sitesearch' value=""/>
<input
type='hidden' name='sitesearch' value="martinfowler.com"/>
</form>
</div>
<div class = 'menu-button navmenu-button'><a class = 'icon icon-bars' href = '#navmenu-bottom'></a></div>
<nav class = 'top-menu'>
<ul>
<li><a class = '' href = 'https://refactoring.com'>Refactoring</a></li>
<li><a class = '' href = '/agile.html'>Agile</a></li>
<li><a class = '' href = '/architecture'>Architecture</a></li>
<li><a class = '' href = '/aboutMe.html'>About</a></li>
<li><a class = 'tw' href = 'https://www.thoughtworks.com/engineering'>Thoughtworks</a></li>
<li><a class = 'icon icon-rss' href = '/feed.atom' title = 'feed'></a></li>
<li><a class = 'icon icon-twitter' href = 'https://www.twitter.com/martinfowler' title = 'Twitter stream'></a></li>
<li class = 'icon'><a href = 'https://toot.thoughtworks.com/@mfowler' title = 'Mastodon stream'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M21.2595 13.9898C20.9852 15.4006 18.8033 16.9446 16.2974 17.2439C14.9907 17.3998 13.7041 17.5431 12.3321 17.4802C10.0885 17.3774 8.31809 16.9446 8.31809 16.9446C8.31809 17.163 8.33156 17.371 8.3585 17.5655C8.65019 19.7797 10.5541 19.9124 12.3576 19.9742C14.1779 20.0365 15.7987 19.5254 15.7987 19.5254L15.8735 21.1711C15.8735 21.1711 14.6003 21.8548 12.3321 21.9805C11.0814 22.0493 9.52849 21.9491 7.71973 21.4703C3.79684 20.432 3.12219 16.2504 3.01896 12.0074C2.98749 10.7477 3.00689 9.55981 3.00689 8.56632C3.00689 4.22771 5.84955 2.95599 5.84955 2.95599C7.2829 2.29772 9.74238 2.0209 12.2993 2H12.3621C14.919 2.0209 17.3801 2.29772 18.8133 2.95599C18.8133 2.95599 21.6559 4.22771 21.6559 8.56632C21.6559 8.56632 21.6916 11.7674 21.2595 13.9898ZM18.3029 8.9029C18.3029 7.82924 18.0295 6.97604 17.4805 6.34482C16.9142 5.71359 16.1726 5.39001 15.2522 5.39001C14.187 5.39001 13.3805 5.79937 12.8473 6.61819L12.3288 7.48723L11.8104 6.61819C11.2771 5.79937 10.4706 5.39001 9.40554 5.39001C8.485 5.39001 7.74344 5.71359 7.17719 6.34482C6.62807 6.97604 6.3547 7.82924 6.3547 8.9029V14.1562H8.43597V9.05731C8.43597 7.98246 8.88822 7.4369 9.79281 7.4369C10.793 7.4369 11.2944 8.08408 11.2944 9.36376V12.1547H13.3634V9.36376C13.3634 8.08408 13.8646 7.4369 14.8648 7.4369C15.7694 7.4369 16.2216 7.98246 16.2216 9.05731V14.1562H18.3029V8.9029Z"></path></svg>
</a></li>
<li class = 'icon'><a href = 'https://www.linkedin.com/in/martin-fowler-com/' title = 'LinkedIn'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4.00098 3H20.001C20.5533 3 21.001 3.44772 21.001 4V20C21.001 20.5523 20.5533 21 20.001 21H4.00098C3.44869 21 3.00098 20.5523 3.00098 20V4C3.00098 3.44772 3.44869 3 4.00098 3ZM5.00098 5V19H19.001V5H5.00098ZM7.50098 9C6.67255 9 6.00098 8.32843 6.00098 7.5C6.00098 6.67157 6.67255 6 7.50098 6C8.3294 6 9.00098 6.67157 9.00098 7.5C9.00098 8.32843 8.3294 9 7.50098 9ZM6.50098 10H8.50098V17.5H6.50098V10ZM12.001 10.4295C12.5854 9.86534 13.2665 9.5 14.001 9.5C16.072 9.5 17.501 11.1789 17.501 13.25V17.5H15.501V13.25C15.501 12.2835 14.7175 11.5 13.751 11.5C12.7845 11.5 12.001 12.2835 12.001 13.25V17.5H10.001V10H12.001V10.4295Z"></path></svg>
</a></li>
<li class = 'icon'><a href = 'https://bsky.app/profile/martinfowler.com' title = 'BlueSky'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 11.3884C11.0942 9.62673 8.62833 6.34423 6.335 4.7259C4.13833 3.17506 3.30083 3.4434 2.75167 3.69256C2.11583 3.9784 2 4.95506 2 5.52839C2 6.10339 2.315 10.2367 2.52 10.9276C3.19917 13.2076 5.61417 13.9776 7.83917 13.7309C4.57917 14.2142 1.68333 15.4017 5.48083 19.6292C9.65833 23.9542 11.2058 18.7017 12 16.0392C12.7942 18.7017 13.7083 23.7651 18.4442 19.6292C22 16.0392 19.4208 14.2142 16.1608 13.7309C18.3858 13.9784 20.8008 13.2076 21.48 10.9276C21.685 10.2376 22 6.10256 22 5.52923C22 4.95423 21.8842 3.97839 21.2483 3.6909C20.6992 3.44256 19.8617 3.17423 17.665 4.72423C15.3717 6.34506 12.9058 9.62756 12 11.3884Z"></path></svg></a></li>
</ul>
</nav>
</header>
<nav id = 'top-navmenu'>
<nav class = 'navmenu'>
<div class = 'nav-head'> <div class = 'search'>
<!-- SiteSearch Google -->
<form method='GET' action="https://www.google.com/search">
<input type='hidden' name='ie' value='UTF-8'/>
<input type='hidden' name='oe' value='UTF-8'/>
<input class = 'field' type='text'
name='q' size='15' maxlength='255' value=""/>
<button class = 'button' type='submit'
name='btnG' value=" " title = "Search"/>
<input type='hidden' name='domains' value="martinfowler.com"/>
<input type='hidden' name='sitesearch' value=""/>
<input
type='hidden' name='sitesearch' value="martinfowler.com"/>
</form>
</div>
<div class = 'closediv'>
<span class = 'close' title = 'close'></span>
</div>
</div>
<div class = 'nav-body'>
<div class = 'topics'>
<h2>Topics</h2>
<p><a href = '/architecture'>Architecture</a></p>
<p><a href = 'https://refactoring.com'>Refactoring</a></p>
<p><a href = '/agile.html'>Agile</a></p>
<p><a href = '/delivery.html'>Delivery</a></p>
<p><a href = '/microservices'>Microservices</a></p>
<p><a href = '/data'>Data</a></p>
<p><a href = '/testing'>Testing</a></p>
<p><a href = '/dsl.html'>DSL</a></p>
</div>
<div class = 'about'>
<h2>about me</h2>
<p><a href = '/aboutMe.html'>About</a></p>
<p><a href = '/books'>Books</a></p>
<p><a href = '/faq.html'>FAQ</a></p>
</div>
<div class = 'content'>
<h2>content</h2>
<p><a href = '/videos.html'>Videos</a></p>
<p><a href = '/tags'>Content Index</a></p>
<p><a href = '/fragments'>Fragments</a></p>
<p><a href = '/boardgames'>Board Games</a></p>
<p><a href = '/photos'>Photography</a></p>
</div>
<div class = 'tw'>
<h2>Thoughtworks</h2>
<p><a href = 'https://thoughtworks.com'>Home</a></p>
<p><a href = 'https://thoughtworks.com/insights'>Insights</a></p>
<p><a href = 'https://thoughtworks.com/careers'>Careers</a></p>
<p><a href = 'https://thoughtworks.com/radar'>Radar</a></p>
<p><a href = 'https://www.thoughtworks.com/engineering'>Engineering</a></p>
</div>
<div class = 'feeds'>
<h2>follow</h2>
<p><a href = '/feed.atom'>RSS</a></p>
<p><a href = 'https://toot.thoughtworks.com/@mfowler'>Mastodon</a></p>
<p><a href = 'https://www.linkedin.com/in/martin-fowler-com/'>LinkedIn</a></p>
<p><a href = 'https://bsky.app/profile/martinfowler.com'>Bluesky</a></p>
<p><a href = 'https://www.twitter.com/martinfowler'>X</a></p>
<p><a href = 'https://boardgamegeek.com/blog/13064/martins-7th-decade'>BGG</a></p>
</div>
</div>
</nav>
</nav>
<nav id = 'toc-dropdown'>
<button class = 'dropdown-button'>
<h2>Table of Contents</h2>
</button>
<div class = 'hidden' id = 'dropdownLinks'>
<ul>
<li><a href = '#top'>Top</a></li>
<li><a href = '#WhatIsServerless'>What is Serverless?</a>
<ul>
<li><a href = '#ACoupleOfExamples'>A couple of examples</a>
<ul>
<li><a href = '#Ui-drivenApplications'>UI-driven applications</a></li>
<li><a href = '#Message-drivenApplications'>Message-driven applications</a></li>
</ul>
</li>
<li><a href = '#unpacking-faas'>Unpacking “Function as a Service”</a>
<ul>
<li><a href = '#State'>State</a></li>
<li><a href = '#ExecutionDuration'>Execution duration</a></li>
<li><a href = '#StartupLatencyAndx201ccoldStartsx201d'>Startup latency and &#x201C;cold starts&#x201D;</a></li>
<li><a href = '#ApiGateways'>API gateways</a></li>
<li><a href = '#Tooling'>Tooling</a></li>
<li><a href = '#OpenSource'>Open source</a></li>
</ul>
</li>
<li><a href = '#what-isnt-serverless'>What isn&#x2019;t Serverless?</a>
<ul>
<li><a href = '#ComparisonWithPaas'>Comparison with PaaS</a></li>
<li><a href = '#ComparisonWithContainers'>Comparison with containers</a></li>
<li><a href = '#noops'>#NoOps</a></li>
<li><a href = '#StoredProceduresAsAService'>Stored Procedures as a Service</a></li>
</ul>
</li>
</ul>
</li>
<li><a href = '#benefits'>Benefits</a>
<ul>
<li><a href = '#ReducedOperationalCost'>Reduced operational cost</a></li>
<li><a href = '#BaasReducedDevelopmentCost'>BaaS: reduced development cost</a></li>
<li><a href = '#FaasScalingCosts'>FaaS: scaling costs</a>
<ul>
<li><a href = '#ExampleOccasionalRequests'>Example: occasional requests</a></li>
<li><a href = '#ExampleInconsistentTraffic'>Example: inconsistent traffic</a></li>
<li><a href = '#OptimizationIsTheRootOfSomeCostSavings'>Optimization is the root of some cost savings</a></li>
</ul>
</li>
<li><a href = '#EasierOperationalManagement'>Easier operational management</a>
<ul>
<li><a href = '#ScalingBenefitsOfFaasBeyondInfrastructureCosts'>Scaling benefits of FaaS beyond infrastructure costs</a></li>
<li><a href = '#ReducedPackagingAndDeploymentComplexity'>Reduced packaging and deployment complexity</a></li>
<li><a href = '#TimeToMarketAndContinuousExperimentation'>Time to market and continuous experimentation</a></li>
</ul>
</li>
<li><a href = '#greenerComputing'>“Greener” computing?</a></li>
</ul>
</li>
<li><a href = '#drawbacks'>Drawbacks</a>
<ul>
<li><a href = '#InherentDrawbacks'>Inherent drawbacks</a>
<ul>
<li><a href = '#VendorControl'>Vendor control</a></li>
<li><a href = '#MultitenancyProblems'>Multitenancy problems</a></li>
<li><a href = '#VendorLock-in'>Vendor lock-in</a></li>
<li><a href = '#SecurityConcerns'>Security concerns</a></li>
<li><a href = '#RepetitionOfLogicAcrossClientPlatforms'>Repetition of logic across client platforms</a></li>
<li><a href = '#LossOfServerOptimizations'>Loss of server optimizations</a></li>
<li><a href = '#NoIn-serverStateForServerlessFaas'>No in-server state for Serverless FaaS</a></li>
</ul>
</li>
<li><a href = '#ImplementationDrawbacks'>Implementation drawbacks</a>
<ul>
<li><a href = '#Configuration'>Configuration</a></li>
<li><a href = '#DosYourself'>DoS yourself</a></li>
<li><a href = '#ExecutionDuration'>Execution duration</a></li>
<li><a href = '#StartupLatency'>Startup latency</a></li>
<li><a href = '#Testing'>Testing</a></li>
<li><a href = '#Debugging'>Debugging</a></li>
<li><a href = '#DeploymentPackagingAndVersioning'>Deployment, packaging, and versioning</a></li>
<li><a href = '#Discovery'>Discovery</a></li>
<li><a href = '#MonitoringAndObservability'>Monitoring and observability</a></li>
<li><a href = '#ApiGatewayDefinitionAndOver-ambitiousApiGateways'>API gateway definition, and over-ambitious API gateways</a></li>
<li><a href = '#DeferringOfOperations'>Deferring of operations</a></li>
</ul>
</li>
</ul>
</li>
<li><a href = '#future'>The Future of Serverless</a>
<ul>
<li><a href = '#MitigatingTheDrawbacks'>Mitigating the drawbacks</a>
<ul>
<li><a href = '#Tooling'>Tooling</a></li>
<li><a href = '#StateManagement'>State management</a></li>
<li><a href = '#PlatformImprovements'>Platform improvements</a></li>
<li><a href = '#Education'>Education</a></li>
<li><a href = '#IncreasedTransparencyAndClearerExpectationsFromVendors'>Increased transparency and clearer expectations from vendors</a></li>
</ul>
</li>
<li><a href = '#TheEmergenceOfPatterns'>The emergence of patterns</a></li>
<li><a href = '#GloballyDistributedArchitectures'>Globally distributed architectures</a></li>
<li><a href = '#Beyondfaasification'>Beyond “FaaSification”</a></li>
<li><a href = '#Testing'>Testing</a></li>
<li><a href = '#PortableImplementations'>Portable implementations</a>
<ul>
<li><a href = '#AbstractionsOverVendorImplementations'>Abstractions over vendor implementations</a></li>
<li><a href = '#DeployableImplementations'>Deployable implementations</a></li>
</ul>
</li>
<li><a href = '#Community'>Community</a></li>
</ul>
</li>
<li><a href = '#conclusion'>Conclusion</a></li>
</ul>
<h3>Sidebars</h3>
<ul>
<li><a href = '#origin'>Origin of &#x2018;Serverless&#x2019;</a></li>
</ul>
</div>
</nav>
<main>
<h1>Serverless Architectures</h1>
<section class = 'frontMatter'>
<p class = 'abstract'><i>
Serverless architectures are application designs that incorporate third-party &#x201C;Backend as a
Service&#x201D; (BaaS) services, and/or that include custom code run in managed, ephemeral containers
on a &#x201C;Functions as a Service&#x201D; (FaaS) platform. By using these ideas, and related ones like
single-page applications, such architectures remove much of the need for a traditional always-on
server component. Serverless architectures may benefit from significantly reduced operational
cost, complexity, and engineering lead time, at a cost of increased reliance on vendor
dependencies and comparatively immature supporting services.
</i></p>
<p class = 'date'>22 May 2018</p>
<hr style = 'clear: both'></hr>
<div class = 'front-grid'>
<div class = 'author-list'>
<div class = 'author'>
<div class = 'photo'><a href = 'https://www.symphonia.io/bios/#mike-roberts'><img alt = 'Photo of Mike Roberts' src = 'serverless/mike.jpg' width = '80'></img></a></div>
<address class = 'name'><a href = 'https://www.symphonia.io/bios/#mike-roberts' rel = 'author'>Mike Roberts</a></address>
<div class = 'bio'>
<p>Mike Roberts is a partner, and co-founder, of <a href = 'https://www.symphonia.io/'>Symphonia</a> - a consultancy specializing in Cloud
Architecture and the impact it has on companies and teams.</p>
<p>During his career
Mike&#x2019;s been an engineer, a CTO, and other fun places in-between. He&#x2019;s a long-time
proponent of Agile and DevOps values and is passionate about the role that cloud technologies
have played in enabling such values for many high-functioning software teams.
He sees Serverless as the next evolution of cloud systems and as such is excited about
its ability to help teams, and their customers, be awesome.</p>
</div>
</div>
</div>
<div class = 'tags'>
<p class = 'tag-link'><a href = /tags/application%20architecture.html>application architecture</a></p>
</div>
<div class = 'contents'><span class = 'contents-expand'>expand</span>
<h2>Contents</h2>
<ul>
<li><a href = '#WhatIsServerless'>What is Serverless?</a>
<ul>
<li><a href = '#ACoupleOfExamples'>A couple of examples</a>
<ul>
<li><a href = '#Ui-drivenApplications'>UI-driven applications</a></li>
<li><a href = '#Message-drivenApplications'>Message-driven applications</a></li>
</ul>
</li>
<li><a href = '#unpacking-faas'>Unpacking “Function as a Service”</a>
<ul>
<li><a href = '#State'>State</a></li>
<li><a href = '#ExecutionDuration'>Execution duration</a></li>
<li><a href = '#StartupLatencyAndx201ccoldStartsx201d'>Startup latency and &#x201C;cold starts&#x201D;</a></li>
<li><a href = '#ApiGateways'>API gateways</a></li>
<li><a href = '#Tooling'>Tooling</a></li>
<li><a href = '#OpenSource'>Open source</a></li>
</ul>
</li>
<li><a href = '#what-isnt-serverless'>What isn&#x2019;t Serverless?</a>
<ul>
<li><a href = '#ComparisonWithPaas'>Comparison with PaaS</a></li>
<li><a href = '#ComparisonWithContainers'>Comparison with containers</a></li>
<li><a href = '#noops'>#NoOps</a></li>
<li><a href = '#StoredProceduresAsAService'>Stored Procedures as a Service</a></li>
</ul>
</li>
</ul>
</li>
<li><a href = '#benefits'>Benefits</a>
<ul>
<li><a href = '#ReducedOperationalCost'>Reduced operational cost</a></li>
<li><a href = '#BaasReducedDevelopmentCost'>BaaS: reduced development cost</a></li>
<li><a href = '#FaasScalingCosts'>FaaS: scaling costs</a>
<ul>
<li><a href = '#ExampleOccasionalRequests'>Example: occasional requests</a></li>
<li><a href = '#ExampleInconsistentTraffic'>Example: inconsistent traffic</a></li>
<li><a href = '#OptimizationIsTheRootOfSomeCostSavings'>Optimization is the root of some cost savings</a></li>
</ul>
</li>
<li><a href = '#EasierOperationalManagement'>Easier operational management</a>
<ul>
<li><a href = '#ScalingBenefitsOfFaasBeyondInfrastructureCosts'>Scaling benefits of FaaS beyond infrastructure costs</a></li>
<li><a href = '#ReducedPackagingAndDeploymentComplexity'>Reduced packaging and deployment complexity</a></li>
<li><a href = '#TimeToMarketAndContinuousExperimentation'>Time to market and continuous experimentation</a></li>
</ul>
</li>
<li><a href = '#greenerComputing'>“Greener” computing?</a></li>
</ul>
</li>
<li><a href = '#drawbacks'>Drawbacks</a>
<ul>
<li><a href = '#InherentDrawbacks'>Inherent drawbacks</a>
<ul>
<li><a href = '#VendorControl'>Vendor control</a></li>
<li><a href = '#MultitenancyProblems'>Multitenancy problems</a></li>
<li><a href = '#VendorLock-in'>Vendor lock-in</a></li>
<li><a href = '#SecurityConcerns'>Security concerns</a></li>
<li><a href = '#RepetitionOfLogicAcrossClientPlatforms'>Repetition of logic across client platforms</a></li>
<li><a href = '#LossOfServerOptimizations'>Loss of server optimizations</a></li>
<li><a href = '#NoIn-serverStateForServerlessFaas'>No in-server state for Serverless FaaS</a></li>
</ul>
</li>
<li><a href = '#ImplementationDrawbacks'>Implementation drawbacks</a>
<ul>
<li><a href = '#Configuration'>Configuration</a></li>
<li><a href = '#DosYourself'>DoS yourself</a></li>
<li><a href = '#ExecutionDuration'>Execution duration</a></li>
<li><a href = '#StartupLatency'>Startup latency</a></li>
<li><a href = '#Testing'>Testing</a></li>
<li><a href = '#Debugging'>Debugging</a></li>
<li><a href = '#DeploymentPackagingAndVersioning'>Deployment, packaging, and versioning</a></li>
<li><a href = '#Discovery'>Discovery</a></li>
<li><a href = '#MonitoringAndObservability'>Monitoring and observability</a></li>
<li><a href = '#ApiGatewayDefinitionAndOver-ambitiousApiGateways'>API gateway definition, and over-ambitious API gateways</a></li>
<li><a href = '#DeferringOfOperations'>Deferring of operations</a></li>
</ul>
</li>
</ul>
</li>
<li><a href = '#future'>The Future of Serverless</a>
<ul>
<li><a href = '#MitigatingTheDrawbacks'>Mitigating the drawbacks</a>
<ul>
<li><a href = '#Tooling'>Tooling</a></li>
<li><a href = '#StateManagement'>State management</a></li>
<li><a href = '#PlatformImprovements'>Platform improvements</a></li>
<li><a href = '#Education'>Education</a></li>
<li><a href = '#IncreasedTransparencyAndClearerExpectationsFromVendors'>Increased transparency and clearer expectations from vendors</a></li>
</ul>
</li>
<li><a href = '#TheEmergenceOfPatterns'>The emergence of patterns</a></li>
<li><a href = '#GloballyDistributedArchitectures'>Globally distributed architectures</a></li>
<li><a href = '#Beyondfaasification'>Beyond “FaaSification”</a></li>
<li><a href = '#Testing'>Testing</a></li>
<li><a href = '#PortableImplementations'>Portable implementations</a>
<ul>
<li><a href = '#AbstractionsOverVendorImplementations'>Abstractions over vendor implementations</a></li>
<li><a href = '#DeployableImplementations'>Deployable implementations</a></li>
</ul>
</li>
<li><a href = '#Community'>Community</a></li>
</ul>
</li>
<li><a href = '#conclusion'>Conclusion</a></li>
</ul>
<h3>Sidebars</h3>
<ul>
<li><a href = '#origin'>Origin of &#x2018;Serverless&#x2019;</a></li>
</ul>
</div>
</div>
<hr></hr></section>
<div class = 'paperBody deep'>
<aside class = 'sidebar'>
<p>This article provides an in-depth look at serverless architecture and as a
result is a long read. If you need a concise summary of what serverless is and its
trade-offs - take a look at the <a href = '/bliki/Serverless.html'>bliki entry on
serverless</a></p>
</aside>
<p><b>Serverless computing</b>, or more simply <i>Serverless</i>, is a hot topic in the software
architecture world. The &#x201C;Big Three&#x201D; cloud vendors&#x2014;Amazon, Google, and Microsoft&#x2014;are heavily
invested in Serverless, and we&#x2019;ve seen plenty of books, open-source projects, conferences, and
software vendors dedicated to the subject. But what is Serverless, and why is (or isn&#x2019;t) it
worth considering? In this article I hope to enlighten you a little on these questions.</p>
<p>To start we'll look at the &#x201C;what&#x201D; of Serverless. We&#x2019;ll get into the benefits and drawbacks
of the approach later.</p>
<section id = 'WhatIsServerless'>
<h2>What is Serverless?</h2>
<p>Like many trends in software, there&#x2019;s no one clear view of what Serverless is. For
starters, it encompasses two different but overlapping areas:</p>
<ol>
<li>Serverless was first used to describe applications that significantly or fully
incorporate third-party, cloud-hosted applications and services, to manage server-side logic
and state. These are typically &#x201C;rich client&#x201D; applications&#x2014;think single-page web apps, or
mobile apps&#x2014;that use the vast ecosystem of cloud-accessible databases (e.g., Parse,
Firebase), authentication services (e.g., Auth0, AWS Cognito), and so on. These types of
services have been previously described as &#x201C;<a href = 'https://en.wikipedia.org/wiki/Mobile_backend_as_a_service'>(Mobile) Backend as a
Service</a>“, and I use
<b>“BaaS”</b> as shorthand in the rest of this article.</li>
<li>Serverless can also mean applications where server-side logic is still written by the
application developer, but, unlike traditional architectures, it&#x2019;s run in stateless compute
containers that are event-triggered, ephemeral (may only last for one invocation), and fully
managed by a third party. One way to think of this is &#x201C;Functions as a Service&#x201D; or
<b>“FaaS”</b>. (Note: The <a href = 'https://twitter.com/marak/status/736357543598002176'>original source</a> for this
name&#x2014;a tweet by @marak&#x2014;is no longer publicly available.) <a href = 'https://aws.amazon.com/lambda/'>
AWS Lambda</a> is one of the most popular implementations of a Functions-as-a-Service
platform at present, but there are many others, too.</li>
</ol>
<aside class = 'sidebar' id = 'origin'>
<h2>Origin of &#x2018;Serverless&#x2019;</h2>
<p>The term <i>&#x201C;Serverless&#x201D;</i> is confusing since with such applications there are both server
hardware and server processes running somewhere, but the difference compared to normal
approaches is that the organization building and supporting a &#x2018;Serverless&#x2019; application is not
looking after that hardware or those processes. They are outsourcing this responsibility to
someone else.</p>
<p>First usages of the term seem to have appeared around 2012, including in
<a href = 'http://readwrite.com/2012/10/15/why-the-future-of-software-and-apps-is-serverless/'>this article</a> by
<a href = 'https://twitter.com/frommww'>Ken Fromm</a>. <a href = 'https://twitter.com/badrij'>Badri Janakiraman</a>
says that he also heard the term used around this time in regard to
<a href = '/articles/continuousIntegration.html'>continuous integration</a> and source control systems being hosted as a
service, rather than on a company&#x2019;s own servers. However this second usage was about development
team infrastructure (i.e. the tools that a software team uses), rather than about incorporation
of external services into the actual products built by a development team - the meaning that we
now tend to use for Serverless.</p>
<p>The term became more popular in 2015, following the AWS Lambda launch in 2014, and grew
further in popularity after Amazon&#x2019;s API Gateway launched in July 2015. Here&#x2019;s <a href = 'https://medium.com/precipitation-io/servers-are-dead-3c0fa8d77259#.mbd7csugq'>an example</a> where
<a href = 'https://twitter.com/IamStan'>Ant Stanley</a> writes about Serverless following the API Gateway
announcement. In October 2015 there was a talk at Amazon&#x2019;s re:Invent conference titled &#x201C;<a href = 'https://www.youtube.com/watch?v=U8ODkSCJpJU'>The Serverless Company using AWS Lambda</a>&#x201D;, referring to
<a href = 'http://www.playonsports.com/'>PlayOn! Sports</a>. Towards the end of 2015 the
<a href = 'https://serverlesscode.com/post/serverless-formerly-jaws/'>&#x2018;Javascript Amazon Web Services (JAWS)&#x2019; open source project
renamed themselves</a> to the
<a href = 'https://github.com/serverless/serverless'>Serverless Framework</a>, continuing the trend.</p>
<p>By mid 2016, Serverless had become a dominant name for this area, giving way to the birth of
the <a href = 'http://serverlessconf.io'>Serverless Conference</a> series, and various Serverless vendors
embracing the term in everything from product marketing to job descriptions. Serverless as a
term was here to stay</p>
</aside>
<p>In this article, we&#x2019;ll primarily focus on FaaS. Not only is it the area of Serverless
that&#x2019;s newer and driving a lot of the hype, but it has significant differences to how we
typically think about technical architecture.</p>
<p>BaaS and FaaS are related in their operational attributes (e.g., no resource management)
and are frequently used together. The large cloud vendors all have &#x201C;Serverless portfolios&#x201D;
that include both BaaS and FaaS products&#x2014;for example, <a href = 'https://aws.amazon.com/serverless/'>here&#x2019;s
Amazon&#x2019;s Serverless</a> product page. Google&#x2019;s Firebase BaaS database has explicit FaaS
support through <a href = 'https://firebase.google.com/docs/functions/'>Google Cloud Functions for
Firebase.</a></p>
<p>There is similar linking of the two areas from smaller companies too. <a href = 'https://auth0.com'>Auth0</a> started with a BaaS product that implemented many facets of user
management, and subsequently created the companion FaaS service <a href = 'https://webtask.io'>Webtask</a>. The company have taken this idea even further with <a href = 'https://auth0.com/extend/'>Extend</a>, which enables other SaaS and BaaS companies to easily add a
FaaS capability to existing products so they can create a unified Serverless product.</p>
<section id = 'ACoupleOfExamples'>
<h3>A couple of examples</h3>
<section id = 'Ui-drivenApplications'>
<h4>UI-driven applications</h4>
<p>Let&#x2019;s think about a traditional three-tier client-oriented system with server-side
logic. A good example is a typical ecommerce app&#x2014;dare I say an online pet store?</p>
<p>Traditionally, the architecture will look something like the diagram below. Let&#x2019;s say
it&#x2019;s implemented in Java or Javascript on the server side, with an HTML + Javascript
component as the client:</p>
<div class = 'figure ' id = 'ps.svg'><img src = 'serverless/ps.svg'></img>
<p class = 'photoCaption'></p>
</div>
<p>With this architecture the client can be relatively unintelligent, with much of the
logic in the system&#x2014;authentication, page navigation, searching, transactions&#x2014;implemented
by the server application.</p>
<p>With a Serverless architecture this may end up looking more like this:</p>
<div class = 'figure ' id = 'sps.svg'><img src = 'serverless/sps.svg'></img>
<p class = 'photoCaption'></p>
</div>
<p>This is a massively simplified view, but even here we see a number of significant
changes:</p>
<ol>
<li>We&#x2019;ve deleted the authentication logic in the original application and have replaced
it with a third-party BaaS service (e.g., Auth0.)</li>
<li>Using another example of BaaS, we&#x2019;ve allowed the client direct access to a subset of
our database (for product listings), which itself is fully hosted by a third party
(e.g., Google Firebase.) We likely have a different security profile for the client
accessing the database in this way than for server resources that access the
database.</li>
<li>These previous two points imply a very important third: some logic that was in the
Pet Store server is now within the client&#x2014;e.g., keeping track of a user session,
understanding the UX structure of the application, reading from a database and
translating that into a usable view, etc. The client is well on its way to becoming a
<a href = 'https://en.wikipedia.org/wiki/Single-page_application'>Single Page Application</a>.</li>
<li>We may want to keep some UX-related functionality in the server, if, for example,
it&#x2019;s compute intensive or requires access to significant amounts of data. In our pet
store, an example is &#x201C;search.&#x201D; Instead of having an always-running server, as existed in
the original architecture, we can instead implement a FaaS function that responds to
HTTP requests via an API gateway (described later). Both the client and the server
&#x201C;search&#x201D; function read from the same database for product data.</li>
<p>If we choose to use AWS Lambda as our FaaS platform we can port the search code from
the original Pet Store server to the new Pet Store Search function without a complete
rewrite, since Lambda supports Java and Javascript&#x2014;our original implementation
languages.</p>
<li>Finally, we may replace our &#x201C;purchase&#x201D; functionality with another separate FaaS
function, choosing to keep it on the server side for security reasons, rather than
reimplement it in the client. It too is fronted by an API gateway. Breaking up different
logical requirements into separately deployed components is a very common approach when
using FaaS.</li>
</ol>
<p>Stepping back a little, this example demonstrates another very important point about
Serverless architectures. In the original version, all flow, control, and security was
managed by the central server application. In the Serverless version there is no central
arbiter of these concerns. Instead we see a preference for <b>choreography over
orchestration</b>, with each component playing a more architecturally aware role&#x2014;an idea
also common in a microservices approach.</p>
<p>There are many benefits to such an approach. As Sam Newman notes in his <i><a href = 'https://samnewman.io/books/building_microservices/'>Building Microservices</a></i> book, systems built this way
are often &#x201C;more flexible and amenable to change,&#x201D; both as a whole and through independent
updates to components; there is better division of concerns; and there are also some
fascinating cost benefits, a point that Gojko Adzic discusses in <a href = 'https://gojko.net/2017/10/05/serverless-design-gotocph.html'>this excellent talk</a>.</p>
<p>Of course, such a design is a trade-off: it requires better distributed monitoring
(more on this later), and we rely more significantly on the security capabilities of the
underlying platform. More fundamentally, there are a greater number of moving pieces to
get our heads around than there are with the monolithic application we had originally.
Whether the benefits of flexibility and cost are worth the added complexity of multiple
backend components is very context dependent.</p>
</section>
<section id = 'Message-drivenApplications'>
<h4>Message-driven applications</h4>
<p>A different example is a backend data-processing service.</p>
<p>Say you&#x2019;re writing a user-centric application that needs to quickly respond to UI
requests, and, secondarily, it needs to capture all the different types of user activity
that are occurring, for subsequent processing. Think about an online advertisement system:
when a user clicks on an ad you want to very quickly redirect them to the target of that
ad. At the same time, you need to collect the fact that the click has happened so that you
can charge the advertiser. (This example is not hypothetical&#x2014;my former team at
<a href = 'http://www.intentmedia.com/'>Intent Media</a> had exactly this need, which they implemented
in a Serverless way.)</p>
<p>Traditionally, the architecture may look as below. The &#x201C;Ad Server&#x201D; synchronously
responds to the user (not shown) and also posts a &#x201C;click message&#x201D; to a channel. This
message is then asynchronously processed by a &#x201C;click processor&#x201D; application that updates a
database, e.g., to decrement the advertiser&#x2019;s budget.</p>
<div class = 'figure ' id = 'cp.svg'><img src = 'serverless/cp.svg'></img>
<p class = 'photoCaption'></p>
</div>
<p>In the Serverless world this looks as follows:</p>
<div class = 'figure ' id = 'scp.svg'><img src = 'serverless/scp.svg'></img>
<p class = 'photoCaption'></p>
</div>
<p>Can you see the difference? The change in architecture is much smaller here compared to
our first example&#x2014;this is why asynchronous message processing is a very popular use case
for Serverless technologies. We&#x2019;ve replaced a long-lived message-consumer
<i>application</i> with a FaaS <i>function</i>. This function runs within the event-driven
context the vendor provides. Note that the cloud platform vendor supplies both the message
broker <i>and</i> the FaaS environment&#x2014;the two systems are closely tied to each other.</p>
<p>The FaaS environment may also process several messages in parallel by instantiating
multiple copies of the function code. Depending on how we wrote the original process this
may be a new concept we need to consider.</p>
</section>
</section>
<section id = 'unpacking-faas'>
<h3>Unpacking “Function as a Service”</h3>
<p>We've mentioned FaaS a lot already, but it's time to dig into what it really means. To do
this let's look at the <a href = 'https://aws.amazon.com/lambda/'>opening description</a>
for Amazon's FaaS product: Lambda. I've added some tokens to it, which I&#x2019;ll expand on.
</p>
<blockquote>
<p>AWS Lambda lets you run code without provisioning or managing servers. <b>(1)</b> ...
With Lambda, you can run code for virtually any type of application or backend
service <b>(2)</b> - all with zero administration. Just upload your code and Lambda takes
care of everything required to run <b>(3)</b> and scale <b>(4)</b> your code with high
availability. You can set up your code to automatically trigger from other AWS
services <b>(5)</b> or call it directly from any web or mobile app <b>(6)</b>.</p>
</blockquote>
<ol>
<li><b>Fundamentally, FaaS is about running backend code without managing your own server
systems or your own long-lived server applications.</b> That second clause&#x2014;long-lived
server applications&#x2014;is a key difference when comparing with other modern architectural
trends like containers and PaaS (Platform as a Service).
</li>
<p>If we go back to our click-processing example from earlier, FaaS replaces the
click-processing server (possibly a physical machine, but definitely a specific
application) with something that doesn&#x2019;t need a provisioned server, nor an application
that is running all the time.</p>
<li>FaaS offerings do not require coding to a specific framework or library. FaaS
functions are regular applications when it comes to language and environment. For
instance, AWS Lambda functions can be implemented &#x201C;first class&#x201D; in Javascript, Python, Go,
any JVM language (Java, Clojure, Scala, etc.), or any .NET language. However your Lambda
function can also execute another process that is bundled with its deployment artifact, so
you can actually use any language that can compile down to a Unix process (see Apex, later
in this article).</li>
<p>FaaS functions have significant architectural restrictions though, especially when it
comes to state and execution duration. We&#x2019;ll get to that soon.</p>
<p>Let&#x2019;s consider our click-processing example again. The only code that needs to change
when moving to FaaS is the &#x201C;main method&#x201D; (startup) code, in that it is deleted, and likely
the specific code that is the top-level message handler (the &#x201C;message listener interface&#x201D;
implementation), but this might only be a change in method signature. The rest of the code
(e.g., the code that writes to the database) is no different in a FaaS world.</p>
<li>Deployment is very different from traditional systems since we have no server
applications to run ourselves. In a FaaS environment we upload the code for our function
to the FaaS provider, and the provider does everything else necessary for provisioning
resources, instantiating VMs, managing processes, etc.</li>
<li>Horizontal scaling is completely automatic, elastic, and managed by the provider. If
your system needs to be processing 100 requests in parallel the provider will handle that
without any extra configuration on your part. The &#x201C;compute containers&#x201D; executing your
functions are ephemeral, with the FaaS provider creating and destroying them purely driven
by runtime need. Most importantly, with FaaS <b>the vendor handles all underlying resource
provisioning and allocation</b>&#x2014;no cluster or VM management is required by the user at
all.</li>
<p>Let&#x2019;s return to our click processor. Say that we were having a good day and customers
were clicking on ten times as many ads as usual. For the traditional architecture, would
our click-processing application be able to handle this? For example, did we develop our
application to be able to handle multiple messages at a time? If we did, would one running
instance of the application be enough to process the load? If we are able to run multiple
processes, is autoscaling automatic or do we need to reconfigure that manually? With a
FaaS approach all of these questions are already answered&#x2014;you need to write the function
ahead of time to assume horizontal-scaled parallelism, but from that point on the FaaS
provider automatically handles all scaling needs.</p>
<li>Functions in FaaS are typically triggered by event types defined by the provider. With
Amazon AWS such stimuli include S3 (file/object) updates, time (scheduled tasks), and
messages added to a message bus (e.g., <a href = 'https://aws.amazon.com/kinesis/'>Kinesis</a>).</li>
<li>Most providers also allow functions to be triggered as a response to inbound HTTP
requests; in AWS one typically enables this by way of using an API gateway. We used an API
gateway in our Pet Store example for our &#x201C;search&#x201D; and &#x201C;purchase&#x201D; functions. Functions can
also be invoked directly via a platform-provided API, either externally or from within the
same cloud environment, but this is a comparatively uncommon use.</li>
</ol>
<section id = 'State'>
<h4>State</h4>
<p>FaaS functions have significant restrictions when it comes to local
(machine/instance-bound) state&#x2014;i.e., data that you store in variables in memory, or data
that you write to local disk. You do have such storage available, but you have no
guarantee that such state is persisted across multiple invocations, and, more strongly,
you should not assume that state from one invocation of a function will be available to
another invocation of the same function. FaaS functions are therefore often described as
stateless, but it&#x2019;s more accurate to say that any state of a FaaS function that is
required to be <b>persistent</b> needs to be <b>externalized</b> outside of the FaaS
function instance.</p>
<p>For FaaS functions that are naturally stateless&#x2014;i.e., those that provide a purely
functional transformation of their input to their output&#x2014;this is of no concern. But for
others this can have a large impact on application architecture, albeit not a unique
one&#x2014;the &#x201C;<a href = 'http://12factor.net/'>Twelve-Factor app</a>&#x201D; concept has <a href = 'http://12factor.net/processes'>precisely the same restriction</a>. Such state-oriented functions will
typically make use of a database, a cross-application cache (like Redis), or network
file/object store (like S3) to store state across requests, or to provide further input
necessary to handle a request.</p>
</section>
<section id = 'ExecutionDuration'>
<h4>Execution duration</h4>
<p>FaaS functions are typically limited in how long each invocation is allowed to run. At
present the &#x201C;timeout&#x201D; for an AWS Lambda function to respond to an event is at most five
minutes, before being terminated. Microsoft Azure and Google Cloud Functions have similar
limits.</p>
<p>This means that certain classes of long-lived tasks are not suited to FaaS functions
without re-architecture&#x2014;you may need to create several different coordinated FaaS
functions, whereas in a traditional environment you may have one long-duration task
performing both coordination and execution.</p>
</section>
<section id = 'StartupLatencyAndx201ccoldStartsx201d'>
<h4>Startup latency and &#x201C;cold starts&#x201D;</h4>
<p>It takes some time for a FaaS platform to initialize an instance of a function before
each event. This startup latency can vary significantly, even for one specific function,
depending on a large number of factors, and may range anywhere from a few milliseconds to
several seconds. That sounds bad, but let&#x2019;s get a little more specific, using AWS Lambda
as an example.</p>
<p>Initialization of a Lambda function will either be a &#x201C;warm start&#x201D;&#x2014;reusing an instance
of a Lambda function and its host container from a previous event&#x2014;or a &#x201C;cold start&#x201D;
&#x2014;creating a new container instance, starting the function host process, etc.
Unsurprisingly, when considering startup latency, it&#x2019;s these cold starts that bring the
most concern.</p>
<p>Cold-start latency depends on many variables: the language you use, how many libraries
you&#x2019;re using, how much code you have, the configuration of the Lambda function environment
itself, whether you need to connect to <a href = 'https://aws.amazon.com/vpc/'>VPC</a> resources, etc.
Many of these aspects are under a developer&#x2019;s control, so it&#x2019;s often possible to reduce
the startup latency incurred as part of a cold start.</p>
<p>Equally as variable as cold-start duration is cold-start frequency. For instance, if a
function is processing 10 events per second, with each event taking 50 ms to process,
you&#x2019;ll likely only see a cold start with Lambda every 100,000&#x2013;200,000 events or so. If, on
the other hand, you process an event once per hour, you&#x2019;ll likely see a cold start for
every event, since Amazon retires inactive Lambda instances after a few minutes. Knowing
this will help you understand whether cold starts will impact you on aggregate, and
whether you might want to perform &#x201C;keep alives&#x201D; of your function instances to avoid them
being put out to pasture.</p>
<p>Are cold starts a concern? It depends on the style and traffic shape of your
application. My former team at Intent Media has an asynchronous message-processing Lambda
app implemented in Java (typically the language with the slowest startup time) which
processes hundreds of millions of messages per day, and they have no concerns with startup
latency for this component. That said, if you were writing a low-latency trading
application you probably wouldn&#x2019;t want to use cloud-hosted FaaS systems at this time, no
matter the language you were using for implementation.</p>
<p>Whether or not you think your app may have problems like this, you should test
performance with production-like load. If your use case doesn&#x2019;t work now you may want to
try again in a few months, since this is a major area of continual improvement by FaaS
vendors.</p>
<p>For much more detail on cold starts, please see <a href = 'https://blog.symphonia.io/learning-lambda-part-8-addfab6b460d'>my
article on the subject</a>.</p>
</section>
<section id = 'ApiGateways'>
<h4>API gateways</h4>
<div class = 'figure ' id = 'ag.svg'><img src = 'serverless/ag.svg'></img>
<p class = 'photoCaption'></p>
</div>
<p>One aspect of Serverless that we brushed upon earlier is an &#x201C;API gateway.&#x201D; An API
gateway is an HTTP server where routes and endpoints are defined in configuration, and
each route is associated with a resource to handle that route. In a Serverless
architecture such handlers are often FaaS functions.</p>
<p>When an API gateway receives a request, it finds the routing configuration matching the
request, and, in the case of a FaaS-backed route, will call the relevant FaaS function
with a representation of the original request. Typically the API gateway will allow
mapping from HTTP request parameters to a more concise input for the FaaS function, or
will allow the entire HTTP request to be passed through, typically as a JSON object. The
FaaS function will execute its logic and return a result to the API gateway, which in turn
will transform this result into an HTTP response that it passes back to the original
caller.</p>
<p>Amazon Web Services have their own API gateway (slightly confusingly named &#x201C;<a href = 'https://aws.amazon.com/api-gateway/'>API Gateway</a>&#x201D;), and other vendors offer similar abilities.
Amazon&#x2019;s API Gateway is a BaaS (yes, BaaS!) service in its own right in that it&#x2019;s an
external service that you configure, but do not need to run or provision yourself.</p>
<p>Beyond purely routing requests, API gateways may also perform authentication, input
validation, response code mapping, and more. (If your spidey senses are tingling as you
consider whether this is actually such a good idea, hold that thought! We'll consider this
further later.)</p>
<p>One use case for an API gateway with FaaS functions is creating HTTP-fronted
microservices in a Serverless way with all the scaling, management, and other benefits
that come from FaaS functions.</p>
<p>When I first wrote this article, the tooling for Amazon&#x2019;s API Gateway, at least, was
achingly immature. Such tools have improved significantly since then. Components like AWS
API Gateway are not quite &#x201C;mainstream,&#x201D; but hopefully they&#x2019;re a little less painful than
they once were, and will only continue to improve.</p>
</section>
<section id = 'Tooling'>
<h4>Tooling</h4>
<p>The comment above about maturity of tooling also applies to Serverless FaaS in general.
In 2016 things were pretty rough; by 2018 we&#x2019;ve seen a marked improvement, and we expect
tools to get better still.</p>
<p>A couple of notable examples of good &#x201C;developer UX&#x201D; in the FaaS world are worth calling
out. First of all is <a href = 'https://webtask.io'>Auth0 Webtask</a> which places significant
priority on developer UX in its tooling. Second is Microsoft, with their <a href = 'https://azure.microsoft.com/en-us/services/functions/'>Azure Functions</a> product. Microsoft has always put Visual Studio, with
its tight feedback loops, at the forefront of its developer products, and Azure Functions
is no exception. The ability it offers to debug functions locally, given an input from a
cloud-triggered event, is quite special.</p>
<p>An area that still needs significant improvement is monitoring. I discuss that later
on.</p>
</section>
<section id = 'OpenSource'>
<h4>Open source</h4>
<p>So far I&#x2019;ve mostly discussed proprietary vendor products and tools. The majority of
Serverless applications make use of such services, but there are open-source projects in
this world, too.</p>
<p>The most common uses of open source in Serverless are for FaaS tools and frameworks,
especially the popular <a href = 'https://github.com/serverless/serverless'>Serverless Framework</a>, which aims to
make working with AWS API Gateway and Lambda easier than using the tools provided by AWS.
It also provides an amount of cross-vendor tooling abstraction, which some users find
valuable. Examples of similar tools include <a href = 'https://github.com/claudiajs/claudia'>Claudia</a> and <a href = 'https://github.com/Miserlou/Zappa'>Zappa</a>. Another example is <a href = 'https://github.com/apex/apex'>Apex</a>, which is
particularly interesting since it allows you to develop Lambda functions in languages
other than those directly supported by Amazon.</p>
<p>The big vendors themselves aren&#x2019;t getting left behind in the open-source tool party
though. AWS&#x2019;s own deployment tool, SAM&#x2014;the <a href = 'https://docs.aws.amazon.com/lambda/latest/dg/serverless_app.html'>Serverless Application
Model</a>&#x2014;is <a href = 'https://github.com/awslabs/serverless-application-model'>also open source</a>.</p>
<p>One of the main benefits of proprietary FaaS is not having to be concerned about the
underlying compute infrastructure (machines, VMs, even containers). But what if you
<i>want</i> to be concerned about such things? Perhaps you have some security needs that
can&#x2019;t be satisfied by a cloud vendor, or maybe you have a few racks of servers that you&#x2019;ve
already bought and don&#x2019;t want to throw away. Can open source help in these scenarios,
allowing you to run your own &#x201C;Serverful&#x201D; FaaS platform?</p>
<p>Yes, and there&#x2019;s been a good amount of activity in this area. One of the initial
leaders in open-source FaaS was IBM (with <a href = 'https://openwhisk.apache.org/'>OpenWhisk</a>, now an
Apache project) and surprisingly&#x2014;to me at least!&#x2014;Microsoft, which open sourced much of its
<a href = 'https://azure.microsoft.com/en-us/services/functions/'>Azure Functions</a> platform. Many other self-hosted FaaS
implementations make use of an underlying container platform, frequently Kubernetes, which
makes a lot of sense for many reasons. In this arena it&#x2019;s worth exploring projects like
<a href = 'http://www.galacticfog.com/'>Galactic Fog</a>, <a href = 'https://fission.io/'>Fission</a>, and
<a href = 'https://github.com/openfaas/faas'>OpenFaaS</a>. This is a large, fast-moving world, and I recommend
looking at the work that the Cloud Native Computing Federation (CNCF) <a href = 'https://github.com/cncf/wg-serverless'>Serverless Working Group</a> have done to track it.</p>
</section>
</section>
<section id = 'what-isnt-serverless'>
<h3>What isn&#x2019;t Serverless?</h3>
<p>So far in this article I've described Serverless as being the union of two ideas: Backend
as a Service and Functions as a Service. I've also dug into the capabilities of the latter.
For more precision about what I see as the key attributes of a Serverless service (and why I
consider even older services like S3 to be Serverless), I refer you to another article of
mine: <a href = 'https://blog.symphonia.io/defining-serverless-part-1-704d72bc8a32'>Defining Serverless</a>.</p>
<p>Before we start looking at the very important area of benefits and drawbacks, I'd like to
spend one more quick moment on definition. Let&#x2019;s define what Serverless isn't.</p>
<section id = 'ComparisonWithPaas'>
<h4>Comparison with PaaS</h4>
<p>Given that Serverless FaaS functions are very similar to <a href = 'http://12factor.net/'>Twelve-Factor
applications</a>, are they just another form of <a href = 'https://en.wikipedia.org/wiki/Platform_as_a_service'>“Platform as a
Service”</a> (PaaS) like <a href = 'http://www.heroku.com/'>Heroku</a>? For a brief answer I refer
to Adrian Cockcroft</p>
<blockquote>
<p>If your PaaS can efficiently start instances in 20ms that run for half a second, then
call it serverless.</p>
<p class = 'quote-attribution'>-- <a href = 'https://twitter.com/adrianco/status/736553530689998848'>Adrian Cockcroft</a></p>
</blockquote>
<p>In other words, most PaaS applications are not geared towards bringing entire
applications up and down in response to an event, whereas FaaS platforms do <i>exactly</i>
this.</p>
<p>If I&#x2019;m being a good Twelve-Factor app developer, this doesn&#x2019;t necessarily impact how I
program and architect my applications, but it does make a big difference in how I operate
them. Since we're all good DevOps-savvy engineers, we're thinking about operations as much
as we&#x2019;re thinking about development, right?</p>
<p>The key operational difference between FaaS and PaaS is <i>scaling</i>. Generally with
a PaaS you still need to think about how to scale&#x2014;for example, with Heroku, how many Dynos
do you want to run? With a FaaS application this is completely transparent. Even if you
set up your PaaS application to auto-scale you won&#x2019;t be doing this to the level of
individual requests (unless you have a very specifically shaped traffic profile), so a
FaaS application is much more efficient when it comes to costs.</p>
<p>Given this benefit, why would you still use a PaaS? There are several reasons, but
tooling is probably the biggest. Also some people use PaaS platforms like <a href = 'https://en.wikipedia.org/wiki/Cloud_Foundry'>Cloud Foundry</a> to provide a common development experience
across a hybrid public and private cloud; at time of writing there isn&#x2019;t a FaaS equivalent
as mature as this.</p>
</section>
<section id = 'ComparisonWithContainers'>
<h4>Comparison with containers</h4>
<p>
One of the reasons to use Serverless FaaS is to avoid having to manage application
processes at the operating-system level. PaaS services, like Heroku, also provide this
capability, and I&#x2019;ve described above how PaaS is different to Serverless FaaS. Another
popular abstraction of processes are containers, with <a href = 'https://www.docker.com/'>Docker</a>
being the most visible example of such a technology. Container hosting systems such as
<a href = 'http://mesos.apache.org/'>Mesos</a> and <a href = 'http://kubernetes.io/'>Kubernetes</a>, which
abstract individual applications from OS-level deployment, are increasingly popular. Even
further along this path we see cloud-hosting container platforms like <a href = 'https://aws.amazon.com/ecs/'>Amazon ECS</a> and <a href = 'https://aws.amazon.com/eks/'>EKS</a>, and
<a href = 'https://cloud.google.com/container-engine'>Google Container Engine</a> which, like Serverless
FaaS, let teams avoid having to manage their own server hosts at all. Given the momentum
around containers, is it still worth considering Serverless FaaS?</p>
<p>Principally the argument I made for PaaS still holds with containers - for Serverless
FaaS <b>scaling is automatically managed, transparent, and fine grained</b>, and this is
tied in with the automatic resource provisioning and allocation I mentioned earlier.
Container platforms have traditionally still needed you to manage the size and shape of
your clusters.</p>
<p>I&#x2019;d also argue that container technology is still not mature and stable, although it is
getting ever closer to being so. That&#x2019;s not to say that Serverless FaaS is mature, of
course, but picking which rough edges you&#x2019;d like is still the order of the day.</p>
<p>It&#x2019;s also important to mention that self-scaling container clusters are now available
within container platforms. Kubernetes has this built in with “<a href = 'http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/'>Horizontal Pod Autoscaling</a>,” and services like <a href = 'https://aws.amazon.com/fargate/'>AWS Fargate</a> also make the promise of &#x201C;Serverless Containers.&#x201D;</p>
<p>As we see the gap of management and scaling between Serverless FaaS and hosted
containers narrow, the choice between them may just come down to style and type of
application. For example, it may be that FaaS is seen as a better choice for an
event-driven style with few event types per application component, and containers are seen
as a better choice for synchronous-request&#x2013;driven components with many entry points. I
expect in a fairly short period of time that many applications and teams will use both
architectural approaches, and it will be fascinating to see patterns of such use
emerge.</p>
</section>
<section id = 'noops'>
<h4>#NoOps</h4>
<p>Serverless doesn&#x2019;t mean “No Ops”&#x2014;though it might mean &#x201C;No sysadmin&#x201D; depending on how
far down the Serverless rabbit hole you go.</p>
<p>&#x201C;Ops&#x201D; means a lot more than server administration. It also means&#x2014;at least&#x2014;monitoring,
deployment, security, networking, support, and often some amount of production debugging
and system scaling. These problems all still exist with Serverless apps, and you&#x2019;re still
going to need a strategy to deal with them. In some ways Ops is harder in a Serverless
world because a lot of this is so new.</p>
<p>The sysadmin is still happening&#x2014;you&#x2019;re just outsourcing it with Serverless. That&#x2019;s not
necessarily a bad (or good) thing&#x2014;we outsource a lot, and its goodness or badness depends
on what precisely you&#x2019;re trying to do. Either way, at some point the abstraction will
likely leak, and you&#x2019;ll need to know that human sysadmins somewhere are supporting your
application.</p>
<p><a href = 'https://twitter.com/mipsytipsy'>Charity Majors</a> gave <a href = 'https://www.youtube.com/watch?v=wgT5f0eBhD8'>a great
talk on this subject</a> at the first Serverlessconf. (You can also read her two
write-ups on it: <a href = 'https://charity.wtf/2016/05/31/wtf-is-operations-serverless/'>WTF is operations?</a> and <a href = 'https://charity.wtf/2016/05/31/operational-best-practices-serverless/'>Operational Best Practices</a>.)</p>
</section>
<section id = 'StoredProceduresAsAService'>
<h4>Stored Procedures as a Service</h4>
<blockquote class = 'aside'>
<p>I wonder if serverless services will become a thing like stored procedures, a
good idea that quickly turns into massive technical debt</p>
<p class = 'quote-attribution'>-- <a href = 'https://twitter.com/skamille/status/719583067275403265'>Camille Fournier</a></p>
</blockquote>
<p>Another theme I&#x2019;ve seen is that Serverless FaaS is &#x201C;Stored Procedures as a Service.&#x201D; I
think that's come from the fact that many examples of FaaS functions (including some I've
used in this article) are small pieces of code that are tightly integrated with a
database. If that's all we could use FaaS for I think the name would be useful, but
because it is really just a subset of FaaS's capability, I don&#x2019;t think it&#x2019;s useful to
think about FaaS in these terms.</p>
<p>That being said, it&#x2019;s worth considering whether FaaS comes with some of the same
problems of stored procedures, including the technical debt concern Camille mentions in
the above-referenced tweet. There are many lessons that come from using stored procedures
that are worth reviewing in the context of FaaS and seeing whether they apply. Consider
that stored procedures:</p>
<ol>
<li>Often require vendor-specific language, or at least vendor-specific
frameworks / extensions to a language </li>
<li>Are hard to test since they need to be executed in the context of a
database </li>
<li>Are tricky to version control or to treat as a first class application</li>
</ol>
<p>While not all of these will necessarily apply to all implementations of stored procs,
they&#x2019;re certainly problems one might come across. Let&#x2019;s see if they might apply to
FaaS:</p>
<p>(1) is definitely not a concern for the FaaS implementations I&#x2019;ve seen so
far, so we can scrub that one off the list right away. </p>
<p>For (2) since we&#x2019;re dealing with “just code,” unit testing is definitely
as easy as any other code. Integration testing is a different (and legitimate)
question though, and one which we&#x2019;ll discuss later.</p>
<p>For (3), again since FaaS functions are &#x201C;just code&#x201D; version control is okay. Until
recently application packaging was also a concern, but we&#x2019;re starting to see maturity
here, with tools like Amazon&#x2019;s <a href = 'https://docs.aws.amazon.com/lambda/latest/dg/serverless_app.html'>Serverless Application Model</a>
(SAM) and the Serverless Framework that I mentioned earlier. At the beginning of 2018
Amazon even launched a &#x201C;<a href = 'https://aws.amazon.com/serverless/serverlessrepo/'>Serverless Application Repository</a>&#x201D; (SAR)
providing organizations with a way to distribute applications, and application components,
built on AWS Serverless services. (Read more on SAR in my fittingly titled article <a href = 'https://blog.symphonia.io/examining-the-aws-serverless-application-repository-9ef316e2fd4'>Examining the AWS Serverless Application Repository</a>.)</p>
</section>
</section>
</section>
<section id = 'benefits'>
<h2>Benefits</h2>
<p>So far I've mostly tried to stick to just defining and explaining what Serverless
architectures have come to mean. Now I'm going to discuss some of the benefits and drawbacks to
such a way of designing and deploying applications. You should definitely not take any decision
to use Serverless without significant consideration and weighing of pros and cons.</p>
<p>Let&#x2019;s start off in the land of rainbows and unicorns and look at the benefits of
Serverless.</p>
<section id = 'ReducedOperationalCost'>
<h3>Reduced operational cost</h3>
<p>Serverless is, at its most simple, an outsourcing solution. It allows you to pay
someone to manage servers, databases and even application logic that you might
otherwise manage yourself. Since you're using a predefined service that many other
people will also be using we see an
<a href = 'https://en.wikipedia.org/wiki/Economies_of_scale'>Economy of Scale</a> effect: you pay less for your
managed database because one vendor is running thousands of very similar databases.</p>
<p>The reduced costs appear to you as the total of two aspects. The first are infrastructure
cost gains that come purely from sharing infrastructure (e.g., hardware, networking) with
other people. The second are labor cost gains: you'll be able to spend less of your own time
on an outsourced Serverless system than on an equivalent developed and hosted by yourself.</p>
<p>This benefit, however, isn't too different than what you'll get from
Infrastructure as a Service (IaaS) or Platform as a Service (PaaS). But we can
extend this benefit in two key ways, one for each of Serverless BaaS and FaaS.</p>
</section>
<section id = 'BaasReducedDevelopmentCost'>
<h3>BaaS: reduced development cost</h3>
<p>IaaS and PaaS are based on the premise that server and operating system management can be
commodified. Serverless Backend as a Service, on the other hand, is a result of entire
application components being commodified.</p>
<p>Authentication is a good example. Many applications code their own authentication
functionality, which often includes features such as signup, login, password management, and
integration with other authentication providers. On the whole this logic is very similar
across most applications, and services like <a href = 'https://auth0.com'>Auth0</a> have been created
to allow us to integrate ready-built authentication functionality into our application without
us having to develop it ourselves.</p>
<p>On the same thread are BaaS databases, like <a href = 'https://firebase.google.com/docs/database/'>Firebase's database
service</a>. Some mobile application teams have found it makes sense to have the client
communicate directly with a server-side database. A BaaS database removes much of the database
administration overhead, and typically provides mechanisms to perform appropriate
authorization for different types of users, in the patterns expected of a Serverless app.</p>
<p>Depending on your background, these ideas might make you squirm (likely for reasons that
we'll get into in the drawbacks section) but there&#x2019;s no denying the number of successful
companies that have been able to produce compelling products with barely any of their own
server-side code. <a href = 'http://www.slideshare.net/ServerlessConf/joe-emison-10x-product-development'>Joe Emison gave a couple of examples</a>
of this at the first Serverless Conference.</p>
</section>
<section id = 'FaasScalingCosts'>
<h3>FaaS: scaling costs</h3>
<p>One of the joys of Serverless FaaS is that&#x2014;as I put it earlier in this article&#x2014;&#x201C;horizontal
scaling is completely automatic, elastic, and managed by the provider.&#x201D; There are several
benefits to this but on the basic infrastructural side <b>the biggest benefit is that you only
pay for the compute that you need</b>, down to a 100ms boundary in the case of AWS Lambda.
Depending on your traffic scale and shape, this can be a huge economic win for you.</p>
<section id = 'ExampleOccasionalRequests'>
<h4>Example: occasional requests</h4>
<p>Say you're running a server application that only processes one request every minute, it
takes 50 ms to process each request, and your mean CPU usage over an hour is 0.1 percent. If
this application is deployed to its own dedicated host then this is wildly inefficient. A
thousand other similar applications could all share that one machine.</p>
<p>Serverless FaaS captures this inefficiency, handing the benefit to you in reduced cost.
With the example application above you'd be paying for just 100 ms of compute every minute,
which is 0.15 percent of the time overall.</p>
<p>This has the following knock-on benefits:</p>
<ul>
<li>For would-be microservices that have very small load requirements it gives support to
breaking down components by logic/domain even if the operational costs of such fine
granularity might have been otherwise prohibitive.</li>
<li>Such cost benefits are a great democratizer. If companies or teams want to try out
something new they have extremely small operational costs associated with &#x201C;dipping their
toe in the water&#x201D; when they use FaaS for their compute needs. In fact, if your total
workload is relatively small (but not entirely insignificant), you may not need to pay for
any compute at all due to the &#x201C;free tier&#x201D; provided by some FaaS vendors.</li>
</ul>
</section>
<section id = 'ExampleInconsistentTraffic'>
<h4>Example: inconsistent traffic</h4>
<p>Let's look at another example. Say your traffic profile is very spiky&#x2014;perhaps your
baseline traffic is 20 requests per second, but that every five minutes you receive 200
requests per second (10 times the usual number) for 10 seconds. Let's also assume, for the
sake of the example, that your baseline performance maxes out your preferred host server
type, and that you don't want to reduce your response time during the traffic spike phase.
How do you solve for this?</p>
<p>In a traditional environment you may need to increase your total hardware count by a
factor of 10 over what it might otherwise be to handle the spikes, even though the total
durations of the spikes account for less than 4 percent of total machine uptime.
Auto-scaling is likely not a good option here due to how long new instances of servers will
take to come up&#x2014;by the time your new instances have booted the spike phase will be over.</p>
<div class = 'figure ' id = 'inconsistent-traffic-pattern.png'><img src = 'serverless/inconsistent-traffic-pattern.png'></img>
<p class = 'photoCaption'></p>
</div>
<p>With Serverless FaaS however this becomes a non-issue. You literally do nothing
differently than if your traffic profile was uniform, and you only pay for the extra
compute capacity during the spike phases.</p>
</section>
<p>Obviously I've deliberately picked examples here for which Serverless FaaS gives huge cost
savings, but the point is to show that, from a scaling viewpoint, unless you have a very
steady traffic shape that consistently uses the whole capacity of your server hosts, then you
may save money using FaaS.</p>
<p>One caveat about the above: if your traffic is uniform and would consistently make good
utilization of a running server you may not see this cost benefit, and you may actually spend
more by using FaaS. You should do some math and compare current provider costs with the
equivalents of running full-time servers to see whether costs are acceptable.</p>
<p>For more detail on the cost benefits of FaaS I recommend the paper &#x201C;<a href = 'http://www.doc.ic.ac.uk/~rbc/papers/fse-serverless-17.pdf'>Serverless Computing: Economic and Architectural Impact</a>&#x201D; by Gojko
Adzic and Robert Chatley.</p>
<section id = 'OptimizationIsTheRootOfSomeCostSavings'>
<h4>Optimization is the root of some cost savings</h4>
<p>There is one more interesting aspect to mention about FaaS costs: any performance
optimizations you make to your code will not only increase the speed of your app, but
they&#x2019;ll have a direct and immediate link to reduction in operational costs, subject to the
granularity of your vendor&#x2019;s charging scheme. For example, say an application initially
takes one second to process an event. If, through code optimization, this is reduced to 200
ms, it will (on AWS Lambda) immediately see an 80 percent savings in compute costs without
making any infrastructural changes.</p>
</section>
</section>
<section id = 'EasierOperationalManagement'>
<h3>Easier operational management</h3>
<p>This next section comes with a giant asterisk&#x2014;some aspects of operations are still tough
for Serverless, but for now we&#x2019;re sticking with our unicorn and rainbow friends&#x2026;</p>
<p>On the Serverless BaaS side of the fence, it&#x2019;s fairly obvious why operational management is
more simple than other architectures: supporting fewer components equals less work.</p>
<p>On the FaaS side there are a number of aspects at play though, and I&#x2019;m going to dig into a
couple of them.</p>
<section id = 'ScalingBenefitsOfFaasBeyondInfrastructureCosts'>
<h4>Scaling benefits of FaaS beyond infrastructure costs</h4>
<p>While scaling is fresh in our minds from the previous section it&#x2019;s worth noting that not
only does the scaling functionality of FaaS reduce compute cost, it also reduces operational
management because the scaling is automatic.</p>
<p>In the best case, if your scaling process was a manual one&#x2014;say, a human being needs to
explicitly add and remove instances to an array of servers&#x2014;with FaaS you can happily forget
about that and let your FaaS vendor scale your application for you.</p>
<p>Even if you&#x2019;ve gotten to the point of using auto-scaling in a non-FaaS architecture, that
still requires setup and maintenance. This work is no longer necessary with FaaS.</p>
<p>Similarly, since scaling is performed by the provider on every request/event,
<b>you no longer need to think about the question of how many concurrent requests you can
handle</b> before running out of memory or seeing too much of a performance hit&#x2014;at least not
within your FaaS-hosted components. Downstream databases and non-FaaS components will have
to be reconsidered in light of a possibly significant increase in their load.</p>
</section>
<section id = 'ReducedPackagingAndDeploymentComplexity'>
<h4>Reduced packaging and deployment complexity</h4>
<p>Packaging and deploying a FaaS function is simple compared to deploying an entire
server. All you&#x2019;re doing is packaging all your code into a zip file, and uploading it. No
Puppet/Chef, no start/stop shell scripts, no decisions about whether to deploy one or many
containers on a machine. If you&#x2019;re just getting started you don&#x2019;t even need to package
anything&#x2014;you may be able to write your code in the vendor console itself (this, obviously,
is not recommended for production code!).</p>
<p>This process doesn't take long to describe, but for some teams this benefit may be
absolutely huge: <b>a fully Serverless solution requires zero system administration</b>.</p>
<p>PaaS solutions have similar deployment benefits, but as we saw earlier, when comparing
PaaS with FaaS, the scaling advantages are unique to FaaS.</p>
</section>
<section id = 'TimeToMarketAndContinuousExperimentation'>
<h4>Time to market and continuous experimentation</h4>
<p>Easier operational management is a benefit that we as engineers understand, but what does
that mean to our businesses?</p>
<p>The obvious reason is cost: less time spent on operations equals fewer people needed for
operations, as I&#x2019;ve already described. But a far more important reason in my mind is
<a href = 'https://en.wikipedia.org/wiki/Time_to_market'>time to market</a>. As our teams and products become
increasingly geared toward lean and agile processes, we want to continually try new things
and rapidly update our existing systems. While simple redeployment in the context of
continuous delivery allows rapid iteration of stable projects, having a good
<i>new-idea-to-initial-deployment</i> capability allows us to try new experiments with low
friction and minimal cost.</p>
<p>The new-idea-to-initial-deployment story for FaaS is often excellent, especially for
simple functions triggered by a maturely defined event in the vendor&#x2019;s ecosystem. For
instance, say your organization is already using <a href = 'https://aws.amazon.com/kinesis/'>AWS Kinesis</a>, a
Kafka-like messaging system, for broadcasting various types of real-time events through your
infrastructure. With AWS Lambda you can develop and deploy a new production event listener
against that Kinesis stream in minutes&#x2014;you could try several different experiments all in
one day!</p>
<p>While the cost benefits are the most easily expressed improvements with Serverless,
<b>it&#x2019;s this reduction in lead time that makes me most excited</b>. It can enable a product
development mindset of <a href = 'https://www.youtube.com/watch?v=mzjhEZLTEpM'><i>continuous
experimentation</i></a>, and that is a true revolution for how we deliver software in
companies.</p>
</section>
</section>
<section id = 'greenerComputing'>
<h3>“Greener” computing?</h3>
<p>Over the last couple of decades, there&#x2019;s been a massive increase in the numbers and sizes
of data centers in the world. As well as the physical resources necessary to build these
centers, the associated energy requirements are so large that Apple, Google, and the like talk
about hosting some of their data centers near sources of renewable energy in order to reduce
the fossil-fuel burning impact of such sites that would otherwise be necessary.</p>
<p>Idle, but powered up, servers consume an untoward amount of this energy - and they&#x2019;re a big
part of the reason why we need so many, and bigger data centers:</p>
<blockquote>
<p>Typical servers in business and
enterprise data centers deliver between 5 and 15 percent of their maximum computing
output on average over the course of the year.</p>
<p class = 'quote-attribution'>-- <a href = 'http://www.forbes.com/sites/benkepes/2015/06/03/30-of-servers-are-sitting-comatose-according-to-research/#2f4944612c2'>Forbes</a></p>
</blockquote>
<p>That&#x2019;s extraordinarily inefficient, and creates a huge environmental impact.</p>
<p>On one hand it&#x2019;s likely that cloud infrastructure has probably helped reduce this impact
already since companies can &#x201C;buy&#x201D; more servers on demand, only when they absolutely need them,
rather than provisioning all only possibly necessary servers a long time in advance. However
one could also argue that the ease of provisioning servers may have made the situation worse
if a lot of those servers are being left around without adequate capacity management.</p>
<p>Whether we use a self-hosted server, IaaS, or PaaS infrastructure solution we&#x2019;re still
manually making capacity decisions about our applications that will often last months or
years. Typically we are cautious, and rightly so, about managing capacity, and so we
over-provision, leading to the inefficiencies just described. With a Serverless approach
<b>we no longer make such capacity decisions ourselves</b>&#x2014;we let the Serverless vendor
provision just enough compute capacity for our needs in real time. The vendor can then make
their own capacity decisions in aggregate across their customers.</p>
<p>This difference should lead to far more efficient use of resources across data centers, and
therefore to reductions in environmental impact compared with traditional capacity management
approaches.</p>
</section>
</section>
<section id = 'drawbacks'>
<h2>Drawbacks</h2>
<p>So, dear reader, I hope you enjoyed your time in the land of rainbows, unicorns, and all
things shiny and nice, because we&#x2019;re about to get slapped around the face by the wet fish
of reality.</p>
<p>There&#x2019;s certainly a lot to like about Serverless architectures, but they come with
significant trade-offs. Some of these trade-offs are inherent to the concepts; they can&#x2019;t be
entirely fixed by progress, and they&#x2019;re always going to need to be considered. Others are tied
to current implementations; with time we can expect to see these resolved.</p>
<section id = 'InherentDrawbacks'>
<h3>Inherent drawbacks</h3>
<section id = 'VendorControl'>
<h4>Vendor control</h4>
<p>With any outsourcing strategy you are giving up control of some of your system to a
third-party vendor. Such lack of control may manifest as system downtime, unexpected limits,
cost changes, loss of functionality, forced API upgrades, and more. Charity Majors, who I
referenced earlier, explains this problem in much more detail in the Tradeoffs section of
<a href = 'https://charity.wtf/2016/05/31/operational-best-practices-serverless/'>this article</a>:</p>
<blockquote>
<p>[The Vendor service], if it is smart, will put strong constraints on how you
are able to use it, so they are more likely to deliver on their reliability
goals. When users have flexibility and options it creates chaos and
unreliability. If the platform has to choose between your happiness vs thousands
of other customers&#x2019; happiness, they will choose the many over the one every time
&#x2014; as they should.</p>
<p class = 'quote-attribution'>-- <a href = 'https://charity.wtf/2016/05/31/operational-best-practices-serverless/'>Charity Majors</a></p>
</blockquote>
</section>
<section id = 'MultitenancyProblems'>
<h4>Multitenancy problems</h4>
<p><a href = 'https://en.wikipedia.org/wiki/Multitenancy'>Multitenancy</a> refers to the situation where multiple
instances of software for several different customers (or tenants) are run on the same
machine, and possibly within the same hosting application. It's a strategy to achieve the
economy of scale benefits we mentioned earlier. Service vendors try their darndest to make
customers feel that they each are the only ones using their system, and typically good
service vendors do a great job of that. But no one&#x2019;s perfect and sometimes multitenant
solutions can have problems with security (one customer being able to see another&#x2019;s data),
robustness (an error in one customer&#x2019;s software causing a failure in a different customer&#x2019;s
software), and performance (a high-load customer causing another to slow down).</p>
<p>These problems are not unique to Serverless systems&#x2014;they exist in many other service
offerings that use multitenancy. AWS Lambda is now mature enough that we don&#x2019;t expect to see
these kind of problems with it, but you should be on the lookout for such issues with any
service that is less mature, whether it&#x2019;s from AWS or other vendors.</p>
</section>
<section id = 'VendorLock-in'>
<h4>Vendor lock-in</h4>
<p>It&#x2019;s very likely that whatever Serverless features you&#x2019;re using from one vendor will be
implemented differently by another vendor. If you want to switch vendors you&#x2019;ll almost
certainly need to update your operational tools (deployment, monitoring, etc.), you&#x2019;ll
probably need to change your code (e.g., to satisfy a different FaaS interface), and you may
even need to change your design or architecture if there are differences to how competing
vendor implementations behave.</p>
<p>Even if you manage to easily migrate one part of your ecosystem, you may be more
significantly impacted by another architectural component. For instance, say you&#x2019;re using
AWS Lambda to respond to events on an AWS Kinesis message bus. The differences between <a href = 'https://aws.amazon.com/lambda/'>AWS Lambda</a>,
<a href = 'https://cloud.google.com/functions/docs/'>Google Cloud Functions</a> and
<a href = 'https://azure.microsoft.com/en-us/services/functions/'>Microsoft Azure Functions</a> may be relatively small, but you&#x2019;re
still not going to be able to hook up the latter two vendor implementations directly to your
AWS Kinesis stream. This means that <b>moving, or porting, your code from one solution to
another isn&#x2019;t going to be possible without also moving other chunks of your
infrastructure</b>.</p>
<p>A lot of people are scared by this idea&#x2014;it&#x2019;s not a great feeling to know that if your
chosen cloud vendor today needs to change tomorrow that you have a lot of work to do.
Because of this some people adopt a &#x201C;multi-cloud&#x201D; approach, developing and operating
applications in a way that&#x2019;s agnostic of the actual cloud vendor being used. Often this is
even more costly than a single-cloud approach&#x2014;so while vendor lock-in is a legitimate
concern, I still recommend picking a vendor that you&#x2019;re happy with and exploiting their
capabilities as much as possible. I talk more about why that is in <a href = 'https://blog.symphonia.io/on-serverless-multi-cloud-and-vendor-lock-in-da930b3993f'>this article</a>.</p>
</section>
<section id = 'SecurityConcerns'>
<h4>Security concerns</h4>
<p>Embracing a Serverless approach opens you up to a large number of security questions.
Here&#x2019;s just a very brief smattering of things to consider&#x2014;be sure to explore what else could
impact you.</p>
<ul>
<li>Each Serverless vendor that you use increases the number of different security
implementations embraced by your ecosystem. This increases your surface area for
malicious intent and ups the likelihood of a successful attack.</li>
<li>If using a BaaS database directly from your mobile platforms you are losing the
protective barrier a server-side application provides in a traditional application.
While this is not a dealbreaker, it does require significant care in designing and
developing your application.</li>
<li>As your organization embraces FaaS you may experience a cambrian explosion of FaaS
functions across your company. Each of those functions offers another vector for
problems. For instance, in AWS Lambda, every Lambda function typically goes hand in hand
with a configured <a href = 'https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html'>IAM policy</a>, which are easy to get
wrong. This is not a simple topic, nor is it one that can be ignored. IAM management
needs careful consideration, at least within production AWS accounts.</li>
</ul>
</section>
<section id = 'RepetitionOfLogicAcrossClientPlatforms'>
<h4>Repetition of logic across client platforms</h4>
<p>With a &#x201C;full&#x201D; BaaS architecture no custom logic is written on the server side&#x2014;it&#x2019;s all in
the client. This may be fine for your first client platform, but as soon as you need your
next platform you&#x2019;re going to need to repeat the implementation of a subset of that
logic&#x2014;and you wouldn&#x2019;t have needed this repetition in a more traditional architecture. For
instance, if using a BaaS database in this kind of system, all your client apps (perhaps
web, native iOS, and native Android) now need to be able to communicate with your vendor
database, and will need to understand how to map from your database schema to application
logic.</p>
<p>Furthermore, if you want to migrate to a new database at any point, you&#x2019;re going to need
to replicate that coding/coordination change across all your different clients.</p>
</section>
<section id = 'LossOfServerOptimizations'>
<h4>Loss of server optimizations</h4>
<p>With a full BaaS architecture there is no opportunity to optimize your server design for
client performance. The <a href = 'http://samnewman.io/patterns/architectural/bff/'>&#x2018;Backend For Frontend&#x2019;</a> pattern exists to
abstract certain underlying aspects of your whole system within the server, partly so that
the client can perform operations more quickly and use less battery power in the case of
mobile applications. Such a pattern is not available for full BaaS.</p>
<p>Both this and the previous drawback exist for full BaaS architectures where all custom
logic is in the client and the only backend services are vendor supplied. A mitigation of
both of these is to embrace FaaS, or some other kind of lightweight server-side pattern, to
move certain logic to the server.</p>
</section>
<section id = 'NoIn-serverStateForServerlessFaas'>
<h4>No in-server state for Serverless FaaS</h4>
<p>After a couple of BaaS-specific drawbacks, let&#x2019;s talk about FaaS for a moment. I
said earlier:</p>
<blockquote>
<p>FaaS functions have significant restrictions when it comes to local .. state. ..
You should not assume that state from one invocation of a function will be available to
another invocation of the same function.</p>
</blockquote>
<p>The reason for this assumption is that with FaaS we typically have no control over when
the host containers for our functions start and stop.</p>
<p>I also said earlier that the alternative to local state was to follow factor number 6 of
the Twelve-Factor app, which is to embrace this very constraint:</p>
<blockquote>
<p>Twelve-factor processes are stateless and share-nothing. Any data that needs to
persist must be stored in a stateful backing service, typically a database.</p>
<p class = 'quote-attribution'>-- <a href = 'http://12factor.net/processes'>The Twelve-Factor App</a></p>
</blockquote>
<p>Heroku recommends this way of thinking, but you can bend the rules when running on their
PaaS since you have control of when Heroku Dynos are started and stopped. With FaaS there&#x2019;s
no bending the rules.</p>
<p>So where does your state go with FaaS if you can&#x2019;t keep it in memory? The quote above
refers to using a database, and in many cases a fast NoSQL database, out-of-process cache
(e.g., Redis), or an external object/file store (e.g., S3) will be some of your options. But
these are all a lot slower than in-memory or on-machine persistence. You&#x2019;ll need to consider
whether your application is a good fit for this.</p>
<p>Another concern in this regard is in-memory caches. Many apps that are reading from a
large data set stored externally will keep an in-memory cache of part of that data set. You
may be reading from &#x201C;reference data&#x201D; tables in a database and using something like <a href = 'http://www.ehcache.org/'>Ehcache</a>. Alternatively you may be reading from an HTTP service that
specifies cache headers, in which case your in-memory HTTP client can provide a local
cache.</p>
<p>FaaS does allow some use of local cache, and this may be useful assuming your functions
are used frequently enough. For instance, with AWS Lambda we typically expect a function
instance to stick around for a few hours as long as it&#x2019;s used at least once every few
minutes. That means we can use the (configurable) 3 GB RAM, or 512 MB local &#x201C;/tmp&#x201D; space,
that Lambda can provide us. For some caches this may be sufficient. Otherwise you will need
to no longer assume in-process cache, and you&#x2019;ll need to use a low-latency external cache
like Redis or Memcached. However this requires extra work, and may be prohibitively slow
depending on your use case.</p>
</section>
</section>
<section id = 'ImplementationDrawbacks'>
<h3>Implementation drawbacks</h3>
<p>The previously described drawbacks are likely always going to exist with Serverless. We&#x2019;ll
see improvements in mitigating solutions, but they&#x2019;re always going to be there.</p>
<p>The remaining drawbacks, however, come down purely to the current state of the art. With
inclination and investment on the part of vendors and/or a heroic community these can all be
wiped out. In fact this list has shrunk since the first version of this article.</p>
<section id = 'Configuration'>
<h4>Configuration</h4>
<p>When I wrote the first version of this article AWS offered very little in the way of
configuration for Lambda functions. I&#x2019;m glad to say that has now been fixed, but it&#x2019;s still
something that&#x2019;s worth checking if you use a less mature platform.</p>
</section>
<section id = 'DosYourself'>
<h4>DoS yourself</h4>
<p>Here&#x2019;s an example of why <i>caveat emptor</i> is a key phrase whenever you&#x2019;re dealing
with FaaS. AWS Lambda limits how many concurrent executions of your Lambda functions you can
be running at a given time. Say that this limit is one thousand; that means that at any time
you are allowed to be executing one thousand function instances. If you to need to go above
that you may start getting exceptions, queueing, and/or general slow down.</p>
<p>The problem here is that this limit is across an entire AWS account. Some organizations
use the same AWS account for both production and testing. That means if someone, somewhere,
in your organization performs a new type of load test and starts trying to execute one
thousand concurrent Lambda functions, you&#x2019;ll accidentally
<a href = 'https://en.wikipedia.org/wiki/Denial-of-service_attack'>DoS</a> your production applications. Oops.</p>
<p>Even if you use different AWS accounts for production and development, one overloaded
production lambda (e.g., processing a batch upload from a customer) could cause your
separate real-time lambda-backed production API to become unresponsive.</p>
<p>Amazon provides some protection here, <a href = 'https://blog.symphonia.io/aws-lambda-reserved-concurrency-f2c3a32b9f1d'>by way of
<b>reserved concurrency</b></a>. Reserved concurrency allows you to limit the concurrency
of a Lambda function so that it doesn&#x2019;t blow up the rest of your account, while
simultaneously making sure there is always capacity available no matter what the other
functions in an account are doing. However, reserved concurrency is not turned on by default
for an account, and it needs careful management.</p>
</section>
<section id = 'ExecutionDuration'>
<h4>Execution duration</h4>
<p>Earlier in the article I mentioned that AWS Lambda functions are aborted if they run for
longer than five minutes. This has been consistent now for a couple of years, and AWS has
shown no signs of changing it.</p>
</section>
<section id = 'StartupLatency'>
<h4>Startup latency</h4>
<p>I talked about cold starts earlier, and mentioned <a href = 'https://blog.symphonia.io/learning-lambda-part-8-addfab6b460d'>my
article on the subject</a>. AWS has improved this area over time, but there are still
significant concerns here, especially for only occasionally triggered JVM-implemented
functions and/or functions that need access to VPC resources. Continued improvements are
expected in this area.</p>
<p>Okay, that&#x2019;s enough picking on AWS Lambda specifically. I&#x2019;m sure other vendors also have
some pretty ugly skeletons barely in their closets.</p>
</section>
<section id = 'Testing'>
<h4>Testing</h4>
<p>Unit testing Serverless apps is fairly simple for reasons I&#x2019;ve talked about earlier: any
code that you write is &#x201C;just code,&#x201D; and for the most part there aren&#x2019;t a whole bunch of
custom libraries you have to use or interfaces that you have to implement.</p>
<p>Integration testing Serverless apps, on the other hand, is hard. In the BaaS world you&#x2019;re
deliberately relying on externally provided systems rather than, for instance, your own
database. So should your integration tests use the external systems too? If yes, then how
amenable are those systems to testing scenarios? Can you easily tear up and tear down state?
Can your vendor give you a different billing strategy for load testing?</p>
<p>If you want to stub those external systems for integration testing does the vendor
provide a local stub simulation? If so, how good is the fidelity of the stub? If the vendor
doesn&#x2019;t supply a stub how will you implement one yourself?</p>
<p>The same kinds of problems exist in FaaS land, although there&#x2019;s been improvement in this
area. It&#x2019;s now possible to run FaaS functions locally for both Lambda and Microsoft Azure.
However no local environment can fully simulate the cloud environment; relying solely on
local FaaS environments is not a strategy I&#x2019;d recommend. In fact, I&#x2019;d go further and suggest
that your canonical environment for running automated integration tests, at least as part of
a <a href = '/bliki/DeploymentPipeline.html'>deployment pipeline</a>, should be the cloud, and that
you should use the local testing environments primarily for interactive development and
debugging. These local testing environments continue to improve - <a href = 'https://github.com/awslabs/aws-sam-cli'>SAM
CLI</a>, for example, provides fast feedback for developing a Lambda-backed HTTP API
application.</p>
<p>And remember those cross-account execution limits I mentioned a couple of sections ago
when running integration tests in the cloud? You probably want to at least isolate such
tests from your production cloud accounts, and likely use even more fine-grained accounts
than that.</p>
<p>Part of the reason that considering integration tests is a big deal is that our units of
integration with Serverless FaaS (i.e., each function) are a lot smaller than with other
architectures, so we rely on integration testing a lot more than we may with other
architectural styles.</p>
<p>Relying on cloud-based testing environments rather than running everything locally on my
laptop has been quite a shock to me. But times change, and the capabilities we get from the
cloud are similar to what engineers at Google and the like have had for over a decade.
Amazon now <a href = 'https://aws.amazon.com/cloud9/'>even lets you run your IDE in the cloud</a>. I haven&#x2019;t
quite made that jump yet&#x2014;but it&#x2019;s probably coming.</p>
</section>
<section id = 'Debugging'>
<h4>Debugging</h4>
<p>Debugging with FaaS is an interesting area. There&#x2019;s been progress here, mostly related to
running FaaS functions locally, in line with the testing updates discussed above. Microsoft,
as I mentioned earlier, provides excellent debugging support for functions run locally, yet
triggered by remote events. Amazon offers something similar, but not yet triggered by
production events.</p>
<p>Debugging functions actually running in a production cloud environment is a different
story. Lambda at least has no support for that yet, though it would be great to see such a
capability.</p>
</section>
<section id = 'DeploymentPackagingAndVersioning'>
<h4>Deployment, packaging, and versioning</h4>
<p>This is an area under active improvement. AWS has made vast strides in improving this
area, and I discuss it further in the &#x201C;Future of Serverless&#x201D; section a little later.</p>
</section>
<section id = 'Discovery'>
<h4>Discovery</h4>
<p>&#x201C;<a href = 'https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/'>Discovery</a>&#x201D; is a frequently discussed topic in the
microservices world: it&#x2019;s the question of how one service can call the correct version of
another service. In the Serverless world there&#x2019;s been little discussion of discovery.
Initially this concerned me, but now I&#x2019;m less worried. Many usages of Serverless are
inherently event driven, and here the consumer of an event typically self registers to some
extent. For API-oriented usages of FaaS, we typically use them behind an API gateway. In
this context we use DNS in front of the API gateway, and automated deployment/traffic
shifting behind the gateway. We may even use further layers in front of the API gateway
(e.g., using <a href = 'https://aws.amazon.com/cloudfront/'>AWS CloudFront</a>) to support cross-region
resiliency.</p>
<p>I&#x2019;m leaving this idea in &#x201C;limitations&#x201D; since I don&#x2019;t think it&#x2019;s been proven yet, but it
may end up being fine after all.</p>
</section>
<section id = 'MonitoringAndObservability'>
<h4>Monitoring and observability</h4>
<p>Monitoring is a tricky area for FaaS because of the ephemeral nature of containers. Most
of the cloud vendors give you some amount of monitoring support, and we&#x2019;ve seen a lot of
third-party work here from traditional monitoring vendors too. Still, whatever they&#x2014;and
you&#x2014;can ultimately do depends on the fundamental data the vendor gives you. This may be fine
in some cases, but for AWS Lambda, at least, it is very basic. What we really need in this
area are open APIs and the ability for third-party services to help out more.</p>
</section>
<section id = 'ApiGatewayDefinitionAndOver-ambitiousApiGateways'>
<h4>API gateway definition, and over-ambitious API gateways</h4>
<p>Thoughtworks, as part of its Technology Radar publication, has discussed <a href = 'https://www.thoughtworks.com/radar/platforms/overambitious-api-gateways'>over-ambitious API gateways</a>. While the link refers to API
gateways in general (e.g., for those fronting traditionally deployed microservices) it can
definitely apply to the use of API gateways as HTTP frontend-to-FaaS functions. The problem
is that API gateways offer the opportunity to perform much application-specific logic within
their own configuration/definition domain. This logic is typically hard to test, version
control, and, sometimes, define. Typically it&#x2019;s far better for such logic to remain in
program code like the rest of the application.</p>
<p>There&#x2019;s definitely a tension here though. If we consider an API gateway as a BaaS, isn&#x2019;t
it valuable to consider all the options it gives us, in order to save ourselves work? And if
we&#x2019;re paying for use of an API gateway per request, as opposed to by per CPU utilization,
isn&#x2019;t it more cost efficient to maximize the use of the API gateway&#x2019;s functionality?</p>
<p>My guidance is to use enhanced API gateway functionality judiciously, and only if it
really is saving you effort in the long run, including in how it is deployed, monitored, and
tested. Definitely don&#x2019;t use API gateway features that can&#x2019;t be expressed within a
source-controllable configuration file or deployment script.</p>
<p>Regarding difficulty of definition, Amazon&#x2019;s API gateway used to force you to create some
tricky configuration to map HTTP requests and responses to/from Lambda functions. Much of
that has been made more simple with <a href = 'https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html'>Lambda proxy
integration</a>, but you still need to understand some occasionally tricky nuances. Those
elements themselves are made easier using open-source projects like the <a href = 'https://github.com/serverless/serverless'>Serverless Framework</a> and <a href = 'https://github.com/claudiajs/claudia'>Claudia.js</a>, or
Amazon&#x2019;s <a href = 'https://docs.aws.amazon.com/lambda/latest/dg/serverless_app.html'>Serverless Application Model</a>.</p>
</section>
<section id = 'DeferringOfOperations'>
<h4>Deferring of operations</h4>
<p>I mentioned earlier that Serverless is not &#x201C;No Ops&#x201D;&#x2014;there&#x2019;s still plenty to do from monitoring, architectural scaling, security, and networking points of view. However, it&#x2019;s easy to ignore operations when you&#x2019;re getting started (&#x201C;Look, ma, no operating system!&#x201D;). The danger here is getting lulled into a false sense of security. Maybe you have your app up and running but it unexpectedly appears on Hacker News, and suddenly you have 10 times the amount of traffic to deal with and oops! You&#x2019;re accidentally DoS&#x2019;ed and have no idea how to deal with it.</p>
<p>The fix here is education. Teams using Serverless systems need to consider operational activities early, and it is on vendors and the community to provide the teaching to help them understand what this means. Areas like preemptive load testing, and <a href = 'https://www.oreilly.com/webops-perf/free/chaos-engineering.csp'>chaos engineering</a>, will also help teams teach themselves.</p>
</section>
</section>
</section>
<section id = 'future'>
<h2>The Future of Serverless</h2>
<p>We&#x2019;re coming to the end of this journey into the world of Serverless architectures. To close
out I&#x2019;m going to discuss a few areas where I think the Serverless world may develop in the
coming months and years.</p>
<section id = 'MitigatingTheDrawbacks'>
<h3>Mitigating the drawbacks</h3>
<p>Serverless is still a fairly new world. As such, the previous section on drawbacks was
extensive, and I didn&#x2019;t even cover everything I could have. The most important developments of
Serverless are going to be to mitigate the inherent drawbacks and remove, or at least improve,
the implementation drawbacks.</p>
<section id = 'Tooling'>
<h4>Tooling</h4>
<p>Tooling continues to be a concern with Serverless, and that&#x2019;s because so many of the
technologies and techniques are new. Deployment/application bundling and configuration have
both improved over the last two years, with the Serverless framework and Amazon&#x2019;s
Serverless Application Model leading the way. However the &#x201C;first 10 minutes&#x201D; experience
still isn&#x2019;t as universally amazing as it could be, although Amazon and Google could look to
Microsoft and Auth0 for more inspiration.</p>
<p>An area I&#x2019;ve been excited to see being actively addressed by cloud vendors is
higher-level release approaches. In traditional systems, teams have typically needed to code
their own processes to handle &#x201C;traffic-shifting&#x201D; ideas like blue-green deployment and <a href = '/bliki/CanaryRelease.html'>canary releases</a>. With this in mind Amazon supports <a href = 'https://docs.aws.amazon.com/lambda/latest/dg/automating-updates-to-serverless-apps.html'>automatic traffic shifting</a> for both Lambda and API
Gateway. Such concepts are even more useful in Serverless systems where so many individually
deployed components make up a system&#x2014;atomic release of 100 Lambda functions at a time is
simply not possible. In fact, <a href = 'https://twitter.com/natpryce'>Nat Pryce</a> described to me the
idea for a &#x201C;mixing desk&#x201D; approach, one where we can gradually bring groups of components in
and out of a traffic flow.</p>
<p>Distributed monitoring is probably the area in need of the most significant improvement.
We&#x2019;ve seen the early days of work here from Amazon&#x2019;s <a href = 'https://aws.amazon.com/xray/'>X-Ray</a> and
various third-party products, but this is definitely not a solved problem.</p>
<p>Remote debugging is also something I&#x2019;d like to see more widespread. Microsoft Azure
Functions supports this, but Lambda does not. Being able to breakpoint a remotely running
function is a very powerful capability.</p>
<p>Finally, I expect to see improvements for tooling of &#x201C;meta operations&#x201D;&#x2014;how to more
effectively look after hundreds or thousands of FaaS functions, configured services, etc.
For instance, organizations need to be able to see when certain service instances are no
longer used (for security purposes, if nothing else), they need better grouping and
visibility of cross-service costs (especially for autonomous teams that have cost
responsibilities), and more.</p>
</section>
<section id = 'StateManagement'>
<h4>State management</h4>
<p>The lack of persistent in-server state for FaaS is fine for a good number of
applications, but it&#x2019;s a deal breaker for many others&#x2014;whether it be for large cache sets or
fast access to session state.</p>
<p>One workaround for high-throughput applications will likely be for vendors to keep
function instances alive for longer between events, and let regular in-process caching
approaches do their job. This won&#x2019;t work 100 percent of the time since the cache won&#x2019;t be
warm for every event, but this is the same concern that already exists for traditionally
deployed apps using auto-scaling.</p>
<p>A better solution could be very low-latency access to out-of-process data, like being
able to query a Redis database with very low network overhead. This doesn&#x2019;t seem too much of
a stretch given that Amazon already offer a hosted Redis solution in their <a href = 'https://aws.amazon.com/elasticache/'>Elasticache</a> product, and that they already allow relative co-location
of EC2 (server) instances using <a href = 'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html'>Placement Groups</a>.</p>
<p>More likely, though, I think we&#x2019;re going to see different kinds of hybrid (Serverless and
non-Serverless) application architectures embraced to take account of the externalized-state
constraint. For instance, for low-latency applications you may see an approach of a regular,
long-running server handling an initial request, gathering all the context necessary to
process that request from its local and external state, then handing off a fully
contextualized request to a farm of FaaS functions that don&#x2019;t need to look up data
externally.</p>
</section>
<section id = 'PlatformImprovements'>
<h4>Platform improvements</h4>
<p>Certain drawbacks to Serverless FaaS right now come down to the way platforms are
implemented. Execution duration, startup latency, and cross-function limits are three
obvious ones. These will likely either be fixed by new solutions or given workarounds with
possible extra costs. For instance, I imagine that startup latency could be mitigated by
allowing a customer to request that two instances of a FaaS function are always available at
low latency, with the customer paying for this availability. Microsoft Azure Functions has
elements of this idea with <a href = 'https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-overview'>Durable Functions</a>, and <a href = 'https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale'>App Service plan-hosted functions</a>.</p>
<p>Of course we&#x2019;ll see platform improvements beyond just fixing current deficiencies, and
these will be exciting too.</p>
</section>
<section id = 'Education'>
<h4>Education</h4>
<p>Many vendor-specific inherent drawbacks with Serverless are being mitigated through
education. Everyone using such platforms needs to think actively about what it means to have
so much of their ecosystems hosted by one or many application vendors. We need to think
about questions like, &#x201C;Do we want to consider parallel solutions from different vendors in
case one becomes unavailable?&#x201D; and &#x201C;How do applications gracefully degrade in the case of a
partial outage?&#x201D;</p>
<p>Another area for education is technical operations. Many teams now have fewer sysadmins
than they used to, and Serverless is going to accelerate this change. But sysadmins do more
than just configure Unix boxes and Chef scripts&#x2014;they&#x2019;re often the people on the front line
of support, networking, security, and the like.</p>
<p>A true <a href = '/bliki/DevOpsCulture.html'>DevOps culture</a> becomes even more
important in a Serverless world since those other non-sysadmin activities still need to get
done, and often it&#x2019;s developers who are now responsible for them. These activities may not
come naturally to many developers and technical leads, so education and close collaboration
with operations folk is of utmost importance.</p>
</section>
<section id = 'IncreasedTransparencyAndClearerExpectationsFromVendors'>
<h4>Increased transparency and clearer expectations from vendors</h4>
<p>Finally, on the subject of mitigation: vendors are going to have to be even more clear in
the expectations we can have of their platforms as we rely on them for more of our hosting
capabilities. While migrating platforms is hard, it&#x2019;s not impossible, and untrustworthy
vendors will see their customers taking their business elsewhere.</p>
</section>
</section>
<section id = 'TheEmergenceOfPatterns'>
<h3>The emergence of patterns</h3>
<p>Our understanding of how and when to use Serverless architectures is still in its infancy.
Right now teams are throwing all kinds of ideas at Serverless platforms and seeing what
sticks. Thank goodness for pioneers! We&#x2019;re starting to see patterns of recommended practice
occur, and this knowledge will only grow.</p>
<p>Some of the patterns we&#x2019;re seeing are in application architecture. For instance, how big
can FaaS functions get before they get unwieldy? Assuming we can atomically deploy a group of
FaaS functions, what are good ways of creating such groupings? Do they map closely to how we&#x2019;d
currently clump logic into microservices, or does the difference in architecture push us in a
different direction?</p>
<p>One particularly interesting area of active discussion in Serverless application
architecture is how it interacts with event-thinking. Ajay Nair, head of product for AWS
Lambda, <a href = 'https://serverless.com/blog/ajay-nair-good-citizen-event-driven-world-emit-2017/'>gave a great talk</a> on this in 2017, and it&#x2019;s <a href = 'https://github.com/cloudevents/spec/blob/master/spec.md'>one of the main areas of discussion</a> for the CNCF Serverless
Working Group.</p>
<p>Extending this further, what are good ways of creating hybrid architectures between FaaS
and traditional &#x201C;always on&#x201D; persistent server components? What are good ways of introducing
BaaS into an existing ecosystem? And, for the reverse, what are the warning signs that a fully
or mostly BaaS system needs to start embracing or using more custom server-side code?</p>
<p>We&#x2019;re also seeing many more usage patterns discussed. One of the standard examples for FaaS
is media conversion, e.g. whenever a large media file is stored to an S3 bucket then
automatically running a process to create smaller versions in another bucket. However we also
now see significant use of Serverless in data-processing pipelines, highly scalable web APIs,
and as general purpose &#x201C;glue&#x201D; code in operations. Some of these patterns can be implemented as
generic components, directly deployable into organizations; <a href = 'https://blog.symphonia.io/examining-the-aws-serverless-application-repository-9ef316e2fd4'>I&#x2019;ve
written about Amazon&#x2019;s Serverless Application Repository</a>, which has an early form of
this idea.</p>
<p>Finally, we&#x2019;re starting to see recommended operational patterns as tooling improves. How do
we logically aggregate logging for a hybrid architecture of FaaS, BaaS, and traditional
servers? How do we most effectively debug FaaS functions? A lot of the answers to these
questions&#x2014;and the emerging patterns&#x2014;are coming from the cloud vendors themselves, and I expect
activity to grow in this area.</p>
</section>
<section id = 'GloballyDistributedArchitectures'>
<h3>Globally distributed architectures</h3>
<p>In the Pet Store example that I gave earlier we saw that the single Pet Store server was
broken up into several server-side components and some logic that moved all the way up to the
client&#x2014;but fundamentally this was still an architecture focused either on the client, or on
remote services in known locations.</p>
<p>What we&#x2019;re starting to see in the Serverless world now is a much fuzzier distribution of
responsibility. An example is Amazon&#x2019;s <a href = 'https://aws.amazon.com/lambda/edge/'>Lambda@Edge</a> product: a
way to run Lambda functions in Amazon&#x2019;s CloudFront Content Delivery Network. With Lambda@Edge
a Lambda function is now globally distributed&#x2014;a single upload activity by an engineer will
mean that function is deployed to <a href = 'https://aws.amazon.com/cloudfront/details/'>over 100 data centers</a>
across the globe. This is not a design that we are accustomed to, and comes with a raft of
both constraints and capabilities.</p>
<p>Further, Lambda functions can be run <a href = 'https://aws.amazon.com/greengrass/'>on devices</a>,
machine-learning models can be run on mobile clients, and before you know it, the bifurcation
of &#x201C;client side&#x201D; and &#x201C;server side&#x201D; no longer seems to make sense. We in fact now see a
spectrum of locality of components, spreading out from the human user. Serverless will
become Regionless.</p>
</section>
<section id = 'Beyondfaasification'>
<h3>Beyond “FaaSification”</h3>
<p>Most usages of FaaS that I&#x2019;ve seen so far are mostly about taking existing code and design
ideas and &#x201C;FaaSifying&#x201D; them: converting them to a set of stateless functions. This is
powerful, but I expect that we&#x2019;ll start to see more abstractions, and possibly languages,
using FaaS as an underlying implementation that gives developers the benefits of FaaS without
actually thinking about their application as a set of discrete functions.</p>
<p>As an example, I don&#x2019;t know whether Google uses a FaaS implementation for its <a href = 'https://cloud.google.com/dataflow/'>Dataflow</a> product, but I can imagine someone creating a product or
open-source project that does something similar, and using FaaS as an implementation. A
comparison here is something like <a href = 'http://spark.apache.org/'>Apache Spark</a> . Spark is a tool
for large-scale data processing, and offers very high-level abstractions that can use <a href = 'https://aws.amazon.com/elasticmapreduce/details/spark/'>Amazon EMR and Hadoop</a> as its underlying platform.</p>
</section>
<section id = 'Testing'>
<h3>Testing</h3>
<p>I think there&#x2019;s more work to be done on integration and acceptance testing of Serverless
systems, but a lot of this work is the same as &#x201C;cloud native&#x201D; microservice systems developed
in more traditional ways.</p>
<p>One radical idea here is to embrace ideas like <a href = 'https://youtu.be/L-WOJmCcA9g'>testing in
production</a> and <a href = 'https://nl.devoteam.com/en/blog-post/monitoring-driven-development-making-money/'>monitoring-driven
development</a>; once code has passed basic unit-test validation, deploy to a subset of
traffic and see how it compares to the previous version. This can be combined with the
traffic-shifting tools I mentioned earlier. This doesn&#x2019;t work for all contexts, but it can be
a surprisingly effective tool for many teams.</p>
</section>
<section id = 'PortableImplementations'>
<h3>Portable implementations</h3>
<p>There are a couple ways that teams can use Serverless, while being less tied to specific
cloud vendors.</p>
<section id = 'AbstractionsOverVendorImplementations'>
<h4>Abstractions over vendor implementations</h4>
<p>The <a href = 'http://serverless.com/'>Serverless Framework</a> primarily exists to ease operational
tasks for Serverless applications, but also provides an amount of neutrality about where and
how such applications are deployed. For example, it would be great to be able to easily
switch, even right now, between AWS API Gateway + Lambda and Auth0 webtask, depending on the
operational capabilities of each of the platforms.</p>
<p>A tricky aspect of this is modeling abstracted FaaS coding interfaces without some idea
of standardization, but that is precisely the work of the CNCF Serverless Working Group on
<a href = 'https://github.com/cloudevents/spec/blob/master/spec.md'>CloudEvents</a>.</p>
<p>It&#x2019;s questionable how much value exists in providing a deployment abstraction for
multiple platforms though, once complexities of operations rear their ugly heads. For
instance getting security right for one cloud is always likely to be different in another
cloud.</p>
</section>
<section id = 'DeployableImplementations'>
<h4>Deployable implementations</h4>
<p>It may sound odd to suggest that we use Serverless techniques without using third-party
providers, but consider these thoughts:</p>
<ul>
<li>Maybe we&#x2019;re a large technical organization and we want to start offering a
<a href = 'https://firebase.google.com/docs/database/'>Firebase</a>-like database experience to all of
our mobile application development teams, but we want to use our existing
database architecture as the back end.</li>
<li>I talked earlier about &#x201C;Serverful&#x201D; FaaS platform&#x2014;being able to use FaaS-style
architecture for some of our projects, but submitting to compliance, legal, etc. reasons to
run our applications on premise.</li>
</ul>
<p>In either of these cases there are still many benefits of using a Serverless approach
without those that come from vendor hosting. There&#x2019;s a precedent here&#x2014;consider Platform as a
Service (PaaS). The initial popular PaaS were all cloud based (e.g., Heroku), but, fairly
quickly, people saw the benefits of running a PaaS environment on their own systems&#x2014;a
so-called &#x201C;Private&#x201D; PaaS (e.g., <a href = 'https://en.wikipedia.org/wiki/Cloud_Foundry'>Cloud Foundry</a>, as I mentioned earlier in the article).</p>
<p>I can imagine, like private PaaS implementations, that we&#x2019;ll see both open-source and
commercial implementations of BaaS and FaaS concepts becoming popular, especially those
integrated with container platforms like Kubernetes.</p>
</section>
</section>
<section id = 'Community'>
<h3>Community</h3>
<p>There is already a good-size Serverless community with multiple conferences, meetups in
many cities, and various online groups. I expect this will continue to grow, probably in the
same vein of communities like Docker and Spring.</p>
</section>
</section>
<section id = 'conclusion'>
<h2>Conclusion</h2>
<p>Serverless, despite the confusing name, is a style of architecture where we rely on running
our own server-side systems as part of our applications to a smaller extent than usual. We do
this through two techniques: BaaS, where we tightly integrate third-party remote application
services directly into the frontend of our apps, and FaaS, which moves server-side code from
long-running components to ephemeral function instances.</p>
<p>Serverless is not the correct approach for every problem, so be wary of anyone who says it
will replace all of your existing architectures. Be careful if you take the plunge into
Serverless systems now, especially in the FaaS realm. While there are riches&#x2014;of scaling and
saved deployment effort&#x2014;to be plundered, there also be dragons&#x2014;of debugging and
monitoring&#x2014;lurking right around the next corner.</p>
<p>Those riches shouldn&#x2019;t be dismissed too quickly, however, since there are significant
positive aspects to Serverless architecture, including reduced operational and development
costs, easier operational management, and reduced environmental impact. But I think the most
important benefit is the reduced feedback loop of creating new application components. I&#x2019;m a
huge fan of &#x201C;lean&#x201D; approaches, largely because I think there is a lot of value in getting
technology in front of an end user as soon as possible to get early feedback, and the reduced
time to market that comes with Serverless fits right in with this philosophy.</p>
<p>Serverless services, and our understanding of how to use them, are today (May 2018) in the
&#x201C;slightly awkward teenage years&#x201D; of maturity. There will be many advances in the field over the
coming years, and it will be fascinating to see how Serverless fits into our architectural
toolkit.</p>
</section>
<hr class = 'bodySep'></hr>
</div>
<div class = 'appendix'>
<section id = 'Acknowledgements'>
<h2>Acknowledgements</h2>
<p>Thanks to the following for their input into this article: Obie Fernandez, Martin
Fowler, Paul Hammant, Badri Janakiraman, Kief Morris, Nat Pryce, Ben Rady, Carlos
Nunez, John Chapin, Robert Bagge, Karel Sague Alfonso, Premanand Chandrasekaran,
Augusto Marietti, Roberto Sarrionandia, Donna Malayeri.</p>
<p>Thanks to Badri Janakiraman and Ant Stanley who provided input for the sidebar
on origins of the term.</p>
<p>Thanks to members of my former team at Intent Media for tackling this new technology with
appropriately sceptical enthusiasm: John Chapin, Pete Gieser, Sebasti&#xE1;n Rojas
and Philippe Ren&#xE9;.</p>
<p>Thanks to Sid Orlando for performing copy-editing.</p>
<p>Finally, thanks to my friends and colleagues in the Serverless community, especially those whose content I link to in this article.</p>
</section>
</div>
<div class = 'appendix'>
<details id = 'SignificantRevisions'>
<summary>Significant Revisions</summary>
<p><i>22 May 2018: </i>Substantive update of entire article. Read <a href = 'https://go.symphonia.io/sa-may-2018'>here</a> for details of this update.</p>
<p><i>04 August 2016: </i>Added &#x201C;Future&#x201D; and &#x201C;Conclusion&#x201D;</p>
<p><i>25 July 2016: </i>Added origins sidebar and section &#x201C;Comparison with
containers&#x201D;</p>
<p><i>18 July 2016: </i>Added &#x201C;Drawbacks&#x201D;</p>
<p><i>13 July 2016: </i>Added &#x201C;Benefits&#x201D;</p>
<p><i>17 June 2016: </i>Added &#x201C;What isn&#x2019;t Serverless&#x2019;&#x201D;</p>
<p><i>16 June 2016: </i>Added &#x201C;Unpacking &#x2018;Function as a Service&#x2019;&#x201D;</p>
<p><i>15 June 2016: </i>Published first installment - A couple of examples</p>
</details>
</div>
</main>
<nav id = 'bottom-navmenu'>
<nav class = 'navmenu'>
<div class = 'nav-head'> <div class = 'search'>
<!-- SiteSearch Google -->
<form method='GET' action="https://www.google.com/search">
<input type='hidden' name='ie' value='UTF-8'/>
<input type='hidden' name='oe' value='UTF-8'/>
<input class = 'field' type='text'
name='q' size='15' maxlength='255' value=""/>
<button class = 'button' type='submit'
name='btnG' value=" " title = "Search"/>
<input type='hidden' name='domains' value="martinfowler.com"/>
<input type='hidden' name='sitesearch' value=""/>
<input
type='hidden' name='sitesearch' value="martinfowler.com"/>
</form>
</div>
<div class = 'closediv'>
<span class = 'close' title = 'close'></span>
</div>
</div>
<div class = 'nav-body'>
<div class = 'topics'>
<h2>Topics</h2>
<p><a href = '/architecture'>Architecture</a></p>
<p><a href = 'https://refactoring.com'>Refactoring</a></p>
<p><a href = '/agile.html'>Agile</a></p>
<p><a href = '/delivery.html'>Delivery</a></p>
<p><a href = '/microservices'>Microservices</a></p>
<p><a href = '/data'>Data</a></p>
<p><a href = '/testing'>Testing</a></p>
<p><a href = '/dsl.html'>DSL</a></p>
</div>
<div class = 'about'>
<h2>about me</h2>
<p><a href = '/aboutMe.html'>About</a></p>
<p><a href = '/books'>Books</a></p>
<p><a href = '/faq.html'>FAQ</a></p>
</div>
<div class = 'content'>
<h2>content</h2>
<p><a href = '/videos.html'>Videos</a></p>
<p><a href = '/tags'>Content Index</a></p>
<p><a href = '/fragments'>Fragments</a></p>
<p><a href = '/boardgames'>Board Games</a></p>
<p><a href = '/photos'>Photography</a></p>
</div>
<div class = 'tw'>
<h2>Thoughtworks</h2>
<p><a href = 'https://thoughtworks.com'>Home</a></p>
<p><a href = 'https://thoughtworks.com/insights'>Insights</a></p>
<p><a href = 'https://thoughtworks.com/careers'>Careers</a></p>
<p><a href = 'https://thoughtworks.com/radar'>Radar</a></p>
<p><a href = 'https://www.thoughtworks.com/engineering'>Engineering</a></p>
</div>
<div class = 'feeds'>
<h2>follow</h2>
<p><a href = '/feed.atom'>RSS</a></p>
<p><a href = 'https://toot.thoughtworks.com/@mfowler'>Mastodon</a></p>
<p><a href = 'https://www.linkedin.com/in/martin-fowler-com/'>LinkedIn</a></p>
<p><a href = 'https://bsky.app/profile/martinfowler.com'>Bluesky</a></p>
<p><a href = 'https://www.twitter.com/martinfowler'>X</a></p>
<p><a href = 'https://boardgamegeek.com/blog/13064/martins-7th-decade'>BGG</a></p>
</div>
</div>
</nav>
</nav>
<footer id='page-footer'>
<div class='tw-logo'>
<a href='https://www.thoughtworks.com/engineering'>
<img src='/thoughtworks_white.png'>
</a>
</div>
<div class='menu-button'>
<div class='icon-bars navmenu-button'></div>
</div>
<div class='copyright'>
<p>© Martin Fowler | <a href="/aboutMe.html#disclosures">Disclosures</a></p>
</div>
</footer>
<script src = '/jquery-1.11.3.min.js' type = 'text/javascript'></script>
<script src = '/mfcom.js' type = 'text/javascript'></script>
<script type = 'text/javascript'>$(document).ready(function() {
$(".contents ul ul ul").hide();
$(".contents .contents-expand").click(function() {
$(".contents ul ul ul").slideToggle(400);
});
});</script>
</body>
</html>