├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── analyse-code-size.js ├── analyse-lang.js ├── build.sh ├── csharp ├── .npmignore ├── Handler.cs ├── build.ps1 ├── build.sh ├── project.csproj └── serverless.yml ├── download-stats.js ├── golang ├── .npmignore ├── build.sh ├── handler.go └── serverless.yml ├── invoke-functions.js ├── java ├── .npmignore ├── hello.iml ├── pom.xml ├── serverless.yml └── src │ └── main │ ├── java │ └── com │ │ └── serverless │ │ ├── ApiGatewayResponse.java │ │ ├── Handler.java │ │ └── Response.java │ └── resources │ └── log4j.properties ├── nodejs6-diff-package-size ├── bluebird-lodash-only │ ├── handler.js │ └── package.json ├── bluebird-only │ ├── handler.js │ └── package.json ├── extra-extra-extra-large-deps │ ├── handler.js │ └── package.json ├── extra-extra-large-deps │ ├── handler.js │ └── package.json ├── extra-large-deps │ ├── handler.js │ └── package.json ├── large-deps │ ├── handler.js │ └── package.json ├── no-deps │ └── handler.js └── serverless.yml ├── nodejs6 ├── .npmignore ├── handler.js └── serverless.yml ├── package.json ├── python ├── .npmignore ├── handler.py └── serverless.yml └── results.csv /.gitignore: -------------------------------------------------------------------------------- 1 | .serverless/ 2 | 3 | csharp/bin 4 | csharp/obj 5 | 6 | .idea/ 7 | 8 | java/target/ 9 | 10 | node_modules/ 11 | 12 | golang/bin -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Yan Cui 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lambda-coldstart-comparison 2 | Comparing the coldstart time of AWS Lambda functions using a variety of language runtime and memory size 3 | -------------------------------------------------------------------------------- /analyse-code-size.js: -------------------------------------------------------------------------------- 1 | // set this to your plot.ly account 2 | const username = process.env.USERNAME; 3 | const api_key = process.env.API_KEY; 4 | 5 | const _ = require('lodash'); 6 | const co = require('co'); 7 | const Promise = require('bluebird'); 8 | const plotly = require('plotly')(username, api_key); 9 | const fs = Promise.promisifyAll(require("fs")); 10 | const math = require('mathjs'); 11 | const Stats = require('fast-stats').Stats; 12 | 13 | const CodeSizes = { 14 | 'no-deps': 366, // 366 bytes 15 | 'bluebird-only': 185 * 1024, // 185KB 16 | 'bluebird-lodash-only': 895.8 * 1024, // 895.8KB 17 | 'large-deps': 5.5 * 1024 * 1024, // 5.5MB 18 | 'extra-large-deps': 14.3 * 1024 * 1024 // 14.3MB 19 | }; 20 | 21 | let readStats = co.wrap(function* () { 22 | let contents = yield fs.readFileAsync('results.csv', 'utf-8'); 23 | let rows = contents 24 | .split('\n') 25 | .filter(str => str.match(/aws-coldstart-nodejs6-package-size-dev-(.*)-(\d+\d*)/i)) 26 | .map(str => { 27 | let parts = str.split(','); 28 | let funcName = parts[0]; 29 | let matchRes = funcName.match(/aws-coldstart-nodejs6-package-size-dev-(.*)-(\d+\d*)/i); 30 | 31 | let group = matchRes[1]; 32 | let memorySize = parseInt(matchRes[2]); 33 | 34 | return { 35 | function: parts[0], 36 | codeSize: CodeSizes[group], 37 | memorySize: memorySize, 38 | value: parts[2] 39 | }; 40 | }); 41 | 42 | return rows; 43 | }); 44 | 45 | let boxPlot = co.wrap(function*() { 46 | let rows = _.sortBy(yield readStats(), r => r.memorySize); 47 | 48 | let byLang = { 49 | csharp: { y: [], x: [], type: "box", boxpoints: "all", name: "csharp" }, 50 | java: { y: [], x: [], type: "box", boxpoints: "all", name: "java" }, 51 | python: { y: [], x: [], type: "box", boxpoints: "all", name: "python" }, 52 | nodejs6: { y: [], x: [], type: "box", boxpoints: "all", name: "nodejs6" } 53 | } 54 | 55 | rows.forEach(row => { 56 | byLang[row.lang].y.push(row.value); 57 | byLang[row.lang].x.push(`${row.memorySize}MB`); 58 | }); 59 | 60 | let data = _.values(byLang); 61 | let layout = { 62 | yaxis: { 63 | title: "cold start (milliseconds)", 64 | zeroline: false 65 | }, 66 | xaxis: { 67 | title: "memory size" 68 | }, 69 | boxmode: "group" 70 | }; 71 | 72 | let graphOptions = { filename: "cold-start-by-language", fileopt: "overwrite" }; 73 | plotly.plot(data, graphOptions, function (err, msg) { 74 | let childProc = require('child_process'); 75 | console.log(msg); 76 | 77 | childProc.exec(`open -a "Google Chrome" ${msg.url}`); 78 | }); 79 | 80 | }); 81 | 82 | let calcStats = co.wrap(function*() { 83 | let rows = yield readStats(); 84 | let byCodeSize = _.groupBy(rows, r => `${r.codeSize}-${r.memorySize}MB`); 85 | 86 | let statsByCodeSize = _.mapValues( 87 | byCodeSize, 88 | rs => { 89 | let values = rs.map(r => r.value); 90 | let stats = new Stats(); 91 | stats.push(values); 92 | 93 | return { 94 | codeSize: rs[0].codeSize, 95 | memorySize: rs[0].memorySize, 96 | stddev: math.std(values), 97 | mean: math.mean(values), 98 | median: math.median(values), 99 | '95%-tile': stats.percentile(95), 100 | '99%-tile': stats.percentile(99) 101 | }; 102 | }); 103 | 104 | console.log('codesize (bytes),memory size,std dev,mean,median,95%-tile,99%-tile'); 105 | for (let x of _.values(statsByCodeSize)) { 106 | console.log(`${x.codeSize},${x.memorySize},${x.stddev},${x.mean},${x.median},${x['95%-tile']},${x['99%-tile']}`); 107 | } 108 | }); 109 | 110 | // boxPlot(); 111 | calcStats(); -------------------------------------------------------------------------------- /analyse-lang.js: -------------------------------------------------------------------------------- 1 | // set this to your plot.ly account 2 | const username = process.env.USERNAME; 3 | const api_key = process.env.API_KEY; 4 | 5 | const _ = require('lodash'); 6 | const co = require('co'); 7 | const Promise = require('bluebird'); 8 | const plotly = require('plotly')(username, api_key); 9 | const fs = Promise.promisifyAll(require("fs")); 10 | const math = require('mathjs'); 11 | const Stats = require('fast-stats').Stats; 12 | 13 | let readStats = co.wrap(function* () { 14 | let contents = yield fs.readFileAsync('results.csv', 'utf-8'); 15 | let rows = contents 16 | .split('\n') 17 | .filter(str => str.match(/aws-coldstart-(\w+\w*)-dev-memory-(\d+\d*)/i)) 18 | .map(str => { 19 | let parts = str.split(','); 20 | let funcName = parts[0]; 21 | let matchRes = funcName.match(/aws-coldstart-(\w+\w*)-dev-memory-(\d+\d*)/i); 22 | 23 | let lang = matchRes[1]; 24 | let memorySize = parseInt(matchRes[2]); 25 | 26 | return { 27 | function: parts[0], 28 | lang: lang, 29 | memorySize: memorySize, 30 | value: parts[2] 31 | }; 32 | }); 33 | 34 | return rows; 35 | }); 36 | 37 | let boxPlot = co.wrap(function*() { 38 | let rows = _.sortBy(yield readStats(), r => r.memorySize); 39 | 40 | let byLang = { 41 | csharp: { y: [], x: [], type: "box", boxpoints: "all", name: "csharp" }, 42 | java: { y: [], x: [], type: "box", boxpoints: "all", name: "java" }, 43 | python: { y: [], x: [], type: "box", boxpoints: "all", name: "python" }, 44 | nodejs6: { y: [], x: [], type: "box", boxpoints: "all", name: "nodejs6" }, 45 | golang: { y:[], x: [], type: "box", boxpoints: "all", name: "golang"} 46 | } 47 | 48 | rows.forEach(row => { 49 | byLang[row.lang].y.push(row.value); 50 | byLang[row.lang].x.push(`${row.memorySize}MB`); 51 | }); 52 | 53 | let data = _.values(byLang); 54 | let layout = { 55 | yaxis: { 56 | title: "cold start (milliseconds)", 57 | zeroline: false 58 | }, 59 | xaxis: { 60 | title: "memory size" 61 | }, 62 | boxmode: "group" 63 | }; 64 | 65 | let graphOptions = { filename: "cold-start-by-language", fileopt: "overwrite" }; 66 | plotly.plot(data, graphOptions, function (err, msg) { 67 | let childProc = require('child_process'); 68 | console.log(msg); 69 | 70 | childProc.exec(`open -a "Google Chrome" ${msg.url}`); 71 | }); 72 | 73 | }); 74 | 75 | let calcStats = co.wrap(function*() { 76 | let rows = yield readStats(); 77 | let byLangSize = _.groupBy(rows, r => `${r.lang}-${r.memorySize}MB`); 78 | 79 | let statsByLangSize = _.mapValues( 80 | byLangSize, 81 | rs => { 82 | let values = rs.map(r => r.value); 83 | let stats = new Stats(); 84 | stats.push(values); 85 | 86 | return { 87 | lang: rs[0].lang, 88 | memorySize: rs[0].memorySize, 89 | stddev: math.std(values), 90 | mean: math.mean(values), 91 | median: math.median(values), 92 | '95%-tile': stats.percentile(95), 93 | '99%-tile': stats.percentile(99) 94 | }; 95 | }); 96 | 97 | console.log('lang,memory size,std dev,mean,median,95%-tile,99%-tile'); 98 | for (let x of _.values(statsByLangSize)) { 99 | console.log(`${x.lang},${x.memorySize},${x.stddev},${x.mean},${x.median},${x['95%-tile']},${x['99%-tile']}`); 100 | } 101 | }); 102 | 103 | boxPlot(); 104 | // calcStats(); -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | declare -a folders=("csharp" "java" "python" "golang" "nodejs6" "nodejs6-diff-package-size") 3 | 4 | export AWS_PROFILE=personal 5 | 6 | for i in `seq 1 10`; 7 | do 8 | for folder in "${folders[@]}" 9 | do 10 | cd $folder 11 | pwd 12 | 13 | sls deploy 14 | 15 | cd .. 16 | done 17 | 18 | node invoke-functions.js 19 | done 20 | -------------------------------------------------------------------------------- /csharp/.npmignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Visual Studio 2015 cache/options directory 25 | .vs/ 26 | # Uncomment if you have tasks that create the project's static files in wwwroot 27 | #wwwroot/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # DNX 43 | project.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opendb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | *.sap 88 | 89 | # TFS 2012 Local Workspace 90 | $tf/ 91 | 92 | # Guidance Automation Toolkit 93 | *.gpState 94 | 95 | # ReSharper is a .NET coding add-in 96 | _ReSharper*/ 97 | *.[Rr]e[Ss]harper 98 | *.DotSettings.user 99 | 100 | # JustCode is a .NET coding add-in 101 | .JustCode 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | _NCrunch_* 111 | .*crunch*.local.xml 112 | nCrunchTemp_* 113 | 114 | # MightyMoose 115 | *.mm.* 116 | AutoTest.Net/ 117 | 118 | # Web workbench (sass) 119 | .sass-cache/ 120 | 121 | # Installshield output folder 122 | [Ee]xpress/ 123 | 124 | # DocProject is a documentation generator add-in 125 | DocProject/buildhelp/ 126 | DocProject/Help/*.HxT 127 | DocProject/Help/*.HxC 128 | DocProject/Help/*.hhc 129 | DocProject/Help/*.hhk 130 | DocProject/Help/*.hhp 131 | DocProject/Help/Html2 132 | DocProject/Help/html 133 | 134 | # Click-Once directory 135 | publish/ 136 | 137 | # Publish Web Output 138 | *.[Pp]ublish.xml 139 | *.azurePubxml 140 | # TODO: Comment the next line if you want to checkin your web deploy settings 141 | # but database connection strings (with potential passwords) will be unencrypted 142 | *.pubxml 143 | *.publishproj 144 | 145 | # NuGet Packages 146 | *.nupkg 147 | # The packages folder can be ignored because of Package Restore 148 | **/packages/* 149 | # except build/, which is used as an MSBuild target. 150 | !**/packages/build/ 151 | # Uncomment if necessary however generally it will be regenerated when needed 152 | #!**/packages/repositories.config 153 | # NuGet v3's project.json files produces more ignoreable files 154 | *.nuget.props 155 | *.nuget.targets 156 | 157 | # Microsoft Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Microsoft Azure Emulator 162 | ecf/ 163 | rcf/ 164 | 165 | # Microsoft Azure ApplicationInsights config file 166 | ApplicationInsights.config 167 | 168 | # Windows Store app package directory 169 | AppPackages/ 170 | BundleArtifacts/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | ~$* 181 | *~ 182 | *.dbmdl 183 | *.dbproj.schemaview 184 | *.pfx 185 | *.publishsettings 186 | node_modules/ 187 | orleans.codegen.cs 188 | 189 | # RIA/Silverlight projects 190 | Generated_Code/ 191 | 192 | # Backup & report files from converting an old project file 193 | # to a newer Visual Studio version. Backup files are not needed, 194 | # because we have git ;-) 195 | _UpgradeReport_Files/ 196 | Backup*/ 197 | UpgradeLog*.XML 198 | UpgradeLog*.htm 199 | 200 | # SQL Server files 201 | *.mdf 202 | *.ldf 203 | 204 | # Business Intelligence projects 205 | *.rdl.data 206 | *.bim.layout 207 | *.bim_*.settings 208 | 209 | # Microsoft Fakes 210 | FakesAssemblies/ 211 | 212 | # GhostDoc plugin setting file 213 | *.GhostDoc.xml 214 | 215 | # Node.js Tools for Visual Studio 216 | .ntvs_analysis.dat 217 | 218 | # Visual Studio 6 build log 219 | *.plg 220 | 221 | # Visual Studio 6 workspace options file 222 | *.opt 223 | 224 | # Visual Studio LightSwitch build output 225 | **/*.HTMLClient/GeneratedArtifacts 226 | **/*.DesktopClient/GeneratedArtifacts 227 | **/*.DesktopClient/ModelManifest.xml 228 | **/*.Server/GeneratedArtifacts 229 | **/*.Server/ModelManifest.xml 230 | _Pvt_Extensions 231 | 232 | # Paket dependency manager 233 | .paket/paket.exe 234 | 235 | # FAKE - F# Make 236 | .fake/ 237 | *.orig 238 | 239 | # macOS 240 | .DS_Store 241 | 242 | # JetBrains Rider C# IDE 243 | .idea* 244 | 245 | # Serverless directories 246 | .serverless 247 | -------------------------------------------------------------------------------- /csharp/Handler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Amazon.Lambda.Core; 3 | using Amazon.Lambda.APIGatewayEvents; 4 | using System.Net; 5 | 6 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] 7 | namespace AwsDotnetCsharp 8 | { 9 | public class Handler 10 | { 11 | public APIGatewayProxyResponse Hello(APIGatewayProxyRequest request, ILambdaContext context) 12 | { 13 | return new APIGatewayProxyResponse { 14 | StatusCode = (int)HttpStatusCode.OK, 15 | Body = "Hello" 16 | }; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /csharp/build.ps1: -------------------------------------------------------------------------------- 1 | # from http://stackoverflow.com/questions/1153126/how-to-create-a-zip-archive-with-powershell#answer-13302548 2 | function ZipFiles( $zipfilename, $sourcedir ) 3 | { 4 | Add-Type -Assembly System.IO.Compression.FileSystem 5 | $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal 6 | [System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir, 7 | $zipfilename, $compressionLevel, $false) 8 | } 9 | 10 | dotnet restore 11 | dotnet publish -c release 12 | if ($LASTEXITCODE -ne 0) { return } 13 | 14 | $publishDirectory = "bin/release/netcoreapp1.0/publish" 15 | $packageName = "deploy-package.zip" 16 | 17 | rm "$publishDirectory/$packageName" -ErrorAction SilentlyContinue 18 | ZipFiles "$(pwd)/$packageName" "$(pwd)/$publishDirectory" 19 | mv "$packageName" $publishDirectory 20 | -------------------------------------------------------------------------------- /csharp/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dotnet restore 4 | dotnet lambda package -c Release -f netcoreapp2.0 -o bin/deploy-package.zip -------------------------------------------------------------------------------- /csharp/project.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CsharpHandlers 5 | CsharpHandlers 6 | netcoreapp2.0 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /csharp/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-csharp 2 | 3 | provider: 4 | name: aws 5 | runtime: dotnetcore2.0 6 | versionFunctions: false 7 | 8 | package: 9 | artifact: bin/deploy-package.zip 10 | 11 | functions: 12 | memory-128: 13 | handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello 14 | memorySize: 128 15 | 16 | memory-256: 17 | handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello 18 | memorySize: 256 19 | 20 | memory-512: 21 | handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello 22 | memorySize: 512 23 | 24 | memory-1024: 25 | handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello 26 | memorySize: 1024 27 | 28 | memory-1536: 29 | handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello 30 | memorySize: 1536 -------------------------------------------------------------------------------- /download-stats.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const co = require('co'); 5 | const Promise = require('bluebird'); 6 | const AWS = require('aws-sdk'); 7 | AWS.config.region = 'us-east-1'; 8 | const cloudwatch = Promise.promisifyAll(new AWS.CloudWatch()); 9 | const Lambda = new AWS.Lambda(); 10 | 11 | const START_TIME = new Date('2017-06-07T01:00:00.000Z'); 12 | const DAYS = 2; 13 | const ONE_DAY = 24 * 60 * 60 * 1000; 14 | 15 | let addDays = (startDt, n) => new Date(startDt.getTime() + ONE_DAY * n); 16 | 17 | let getFuncStats = co.wrap(function* (funcName) { 18 | let getStats = co.wrap(function* (startTime, endTime) { 19 | let req = { 20 | MetricName: 'Duration', 21 | Namespace: 'AWS/Lambda', 22 | Period: 60, 23 | Dimensions: [ { Name: 'FunctionName', Value: funcName } ], 24 | Statistics: [ 'Maximum' ], 25 | Unit: 'Milliseconds', 26 | StartTime: startTime, 27 | EndTime: endTime 28 | }; 29 | let resp = yield cloudwatch.getMetricStatisticsAsync(req); 30 | 31 | return resp.Datapoints.map(dp => { 32 | return { 33 | timestamp: dp.Timestamp, 34 | value: dp.Maximum 35 | }; 36 | }); 37 | }); 38 | 39 | let stats = []; 40 | for (let i = 0; i < DAYS; i++) { 41 | // CloudWatch only allows us to query 1440 data points per request, which 42 | // at 1 min period is 24 hours 43 | let startTime = addDays(START_TIME, i); 44 | let endTime = addDays(startTime, 1); 45 | let oneDayStats = yield getStats(startTime, endTime); 46 | 47 | stats = stats.concat(oneDayStats); 48 | } 49 | 50 | return _.sortBy(stats, s => s.timestamp); 51 | }); 52 | 53 | let listFunctions = co.wrap(function* (marker, acc) { 54 | acc = acc || []; 55 | 56 | let resp = yield Lambda.listFunctions({ Marker: marker, MaxItems: 100 }).promise(); 57 | 58 | let functions = resp.Functions 59 | .map(f => f.FunctionName) 60 | .filter(fn => fn.includes("aws-coldstart") && !fn.endsWith("run")); 61 | 62 | acc = acc.concat(functions); 63 | 64 | if (resp.NextMarker) { 65 | return yield listFunctions(resp.NextMarker, acc); 66 | } else { 67 | return acc; 68 | } 69 | }); 70 | 71 | listFunctions() 72 | .then(co.wrap(function* (funcs) { 73 | for (let func of funcs) { 74 | let stats = yield getFuncStats(func); 75 | stats.forEach(stat => console.log(`${func},${stat.timestamp},${stat.value}`)); 76 | } 77 | })); -------------------------------------------------------------------------------- /golang/.npmignore: -------------------------------------------------------------------------------- 1 | .serverless 2 | bin -------------------------------------------------------------------------------- /golang/build.sh: -------------------------------------------------------------------------------- 1 | GOOS=linux GOARCH=amd64 go build -o bin/handler handler.go 2 | cd bin 3 | zip deploy-package.zip handler -------------------------------------------------------------------------------- /golang/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/aws/aws-lambda-go/events" 5 | "github.com/aws/aws-lambda-go/lambda" 6 | ) 7 | 8 | // Hello just returns Hello 9 | func Hello() (events.APIGatewayProxyResponse, error) { 10 | return events.APIGatewayProxyResponse{ 11 | Body: "hello", 12 | StatusCode: 200, 13 | }, nil 14 | } 15 | 16 | func main() { 17 | lambda.Start(Hello) 18 | } 19 | -------------------------------------------------------------------------------- /golang/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-golang 2 | 3 | provider: 4 | name: aws 5 | runtime: go1.x 6 | versionFunctions: false 7 | 8 | package: 9 | artifact: bin/deploy-package.zip 10 | 11 | functions: 12 | memory-128: 13 | handler: handler 14 | memorySize: 128 15 | 16 | memory-256: 17 | handler: handler 18 | memorySize: 256 19 | 20 | memory-512: 21 | handler: handler 22 | memorySize: 512 23 | 24 | memory-1024: 25 | handler: handler 26 | memorySize: 1024 27 | 28 | memory-1536: 29 | handler: handler 30 | memorySize: 1536 -------------------------------------------------------------------------------- /invoke-functions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const co = require('co'); 4 | const AWS = require('aws-sdk'); 5 | AWS.config.region = 'us-east-1'; 6 | const Lambda = new AWS.Lambda(); 7 | 8 | let functions = []; 9 | 10 | let listFunctions = co.wrap(function* (marker, acc) { 11 | acc = acc || []; 12 | 13 | let resp = yield Lambda.listFunctions({ Marker: marker, MaxItems: 100 }).promise(); 14 | 15 | let functions = resp.Functions 16 | .map(f => f.FunctionName) 17 | .filter(fn => fn.includes("aws-coldstart") && !fn.endsWith("run")); 18 | 19 | acc = acc.concat(functions); 20 | 21 | if (resp.NextMarker) { 22 | return yield listFunctions(resp.NextMarker, acc); 23 | } else { 24 | return acc; 25 | } 26 | }); 27 | 28 | let run = co.wrap(function* () { 29 | if (functions.length == 0) { 30 | console.log("fetching relevant functions..."); 31 | 32 | functions = yield listFunctions(); 33 | console.log(`found ${functions.length} functions`); 34 | } 35 | 36 | console.log("invoking $LATEST..."); 37 | for (let func of functions) { 38 | yield Lambda.invoke({ 39 | FunctionName: func, 40 | InvocationType: "Event" 41 | }).promise(); 42 | } 43 | }); 44 | 45 | run(); -------------------------------------------------------------------------------- /java/.npmignore: -------------------------------------------------------------------------------- 1 | *.class 2 | target 3 | /bin/ 4 | /.settings/ 5 | .project 6 | .classpath 7 | 8 | # Package Files 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | # Serverless directories 14 | .serverless -------------------------------------------------------------------------------- /java/hello.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.serverless 5 | hello 6 | jar 7 | dev 8 | hello 9 | 10 | 11 | 1.8 12 | 1.8 13 | UTF-8 14 | 15 | 16 | 17 | 18 | com.amazonaws 19 | aws-lambda-java-core 20 | 1.1.0 21 | 22 | 23 | com.amazonaws 24 | aws-lambda-java-log4j 25 | 1.0.0 26 | 27 | 28 | com.fasterxml.jackson.core 29 | jackson-core 30 | 2.8.5 31 | 32 | 33 | com.fasterxml.jackson.core 34 | jackson-databind 35 | 2.8.5 36 | 37 | 38 | com.fasterxml.jackson.core 39 | jackson-annotations 40 | 2.8.5 41 | 42 | 43 | 44 | 45 | 46 | 55 | 56 | org.apache.maven.plugins 57 | maven-shade-plugin 58 | 2.3 59 | 60 | false 61 | 62 | 63 | 64 | package 65 | 66 | shade 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /java/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-java 2 | 3 | provider: 4 | name: aws 5 | runtime: java8 6 | versionFunctions: false 7 | 8 | package: 9 | artifact: target/hello-dev.jar 10 | 11 | functions: 12 | memory-128: 13 | handler: com.serverless.Handler 14 | memorySize: 128 15 | 16 | memory-256: 17 | handler: com.serverless.Handler 18 | memorySize: 256 19 | 20 | memory-512: 21 | handler: com.serverless.Handler 22 | memorySize: 512 23 | 24 | memory-1024: 25 | handler: com.serverless.Handler 26 | memorySize: 1024 27 | 28 | memory-1536: 29 | handler: com.serverless.Handler 30 | memorySize: 1536 -------------------------------------------------------------------------------- /java/src/main/java/com/serverless/ApiGatewayResponse.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.Base64; 5 | import java.util.Collections; 6 | import java.util.Map; 7 | 8 | import org.apache.log4j.Logger; 9 | 10 | import com.fasterxml.jackson.core.JsonProcessingException; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | 13 | public class ApiGatewayResponse { 14 | 15 | private final int statusCode; 16 | private final String body; 17 | private final Map headers; 18 | private final boolean isBase64Encoded; 19 | 20 | public ApiGatewayResponse(int statusCode, String body, Map headers, boolean isBase64Encoded) { 21 | this.statusCode = statusCode; 22 | this.body = body; 23 | this.headers = headers; 24 | this.isBase64Encoded = isBase64Encoded; 25 | } 26 | 27 | public int getStatusCode() { 28 | return statusCode; 29 | } 30 | 31 | public String getBody() { 32 | return body; 33 | } 34 | 35 | public Map getHeaders() { 36 | return headers; 37 | } 38 | 39 | // API Gateway expects the property to be called "isBase64Encoded" => isIs 40 | public boolean isIsBase64Encoded() { 41 | return isBase64Encoded; 42 | } 43 | 44 | public static Builder builder() { 45 | return new Builder(); 46 | } 47 | 48 | public static class Builder { 49 | 50 | private static final Logger LOG = Logger.getLogger(ApiGatewayResponse.Builder.class); 51 | 52 | private static final ObjectMapper objectMapper = new ObjectMapper(); 53 | 54 | private int statusCode = 200; 55 | private Map headers = Collections.emptyMap(); 56 | private String rawBody; 57 | private Object objectBody; 58 | private byte[] binaryBody; 59 | private boolean base64Encoded; 60 | 61 | public Builder setStatusCode(int statusCode) { 62 | this.statusCode = statusCode; 63 | return this; 64 | } 65 | 66 | public Builder setHeaders(Map headers) { 67 | this.headers = headers; 68 | return this; 69 | } 70 | 71 | /** 72 | * Builds the {@link ApiGatewayResponse} using the passed raw body string. 73 | */ 74 | public Builder setRawBody(String rawBody) { 75 | this.rawBody = rawBody; 76 | return this; 77 | } 78 | 79 | /** 80 | * Builds the {@link ApiGatewayResponse} using the passed object body 81 | * converted to JSON. 82 | */ 83 | public Builder setObjectBody(Object objectBody) { 84 | this.objectBody = objectBody; 85 | return this; 86 | } 87 | 88 | /** 89 | * Builds the {@link ApiGatewayResponse} using the passed binary body 90 | * encoded as base64. {@link #setBase64Encoded(boolean) 91 | * setBase64Encoded(true)} will be in invoked automatically. 92 | */ 93 | public Builder setBinaryBody(byte[] binaryBody) { 94 | this.binaryBody = binaryBody; 95 | setBase64Encoded(true); 96 | return this; 97 | } 98 | 99 | /** 100 | * A binary or rather a base64encoded responses requires 101 | *
    102 | *
  1. "Binary Media Types" to be configured in API Gateway 103 | *
  2. a request with an "Accept" header set to one of the "Binary Media 104 | * Types" 105 | *
106 | */ 107 | public Builder setBase64Encoded(boolean base64Encoded) { 108 | this.base64Encoded = base64Encoded; 109 | return this; 110 | } 111 | 112 | public ApiGatewayResponse build() { 113 | String body = null; 114 | if (rawBody != null) { 115 | body = rawBody; 116 | } else if (objectBody != null) { 117 | try { 118 | body = objectMapper.writeValueAsString(objectBody); 119 | } catch (JsonProcessingException e) { 120 | LOG.error("failed to serialize object", e); 121 | throw new RuntimeException(e); 122 | } 123 | } else if (binaryBody != null) { 124 | body = new String(Base64.getEncoder().encode(binaryBody), StandardCharsets.UTF_8); 125 | } 126 | return new ApiGatewayResponse(statusCode, body, headers, base64Encoded); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /java/src/main/java/com/serverless/Handler.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import java.util.Map; 4 | 5 | import com.amazonaws.services.lambda.runtime.Context; 6 | import com.amazonaws.services.lambda.runtime.RequestHandler; 7 | 8 | public class Handler implements RequestHandler, ApiGatewayResponse> { 9 | 10 | @Override 11 | public ApiGatewayResponse handleRequest(Map input, Context context) { 12 | return ApiGatewayResponse.builder() 13 | .setStatusCode(200) 14 | .setObjectBody("hello") 15 | .build(); 16 | } 17 | } -------------------------------------------------------------------------------- /java/src/main/java/com/serverless/Response.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | public class Response { 4 | 5 | private final String body; 6 | private final Integer status; 7 | 8 | public Response(String body, Integer status) { 9 | this.body = body; 10 | this.status = status; 11 | } 12 | 13 | public String getBody() { 14 | return this.body; 15 | } 16 | 17 | public Integer getInput() { 18 | return this.status; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 5 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c:%L - %m%n 7 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/bluebird-lodash-only/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Promise = require('bluebird'); 4 | const _ = require('lodash'); 5 | 6 | module.exports.handler = (event, context, callback) => { 7 | const response = { 8 | statusCode: 200, 9 | body: JSON.stringify({ 10 | msg: "hello" 11 | }) 12 | }; 13 | 14 | callback(null, response); 15 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/bluebird-lodash-only/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bluebird-lodash-only", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bluebird": "^3.5.0", 13 | "lodash": "^4.17.4" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/bluebird-only/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Promise = require('bluebird'); 4 | 5 | module.exports.handler = (event, context, callback) => { 6 | const response = { 7 | statusCode: 200, 8 | body: JSON.stringify({ 9 | msg: "hello" 10 | }) 11 | }; 12 | 13 | callback(null, response); 14 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/bluebird-only/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bluebird-only", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bluebird": "^3.5.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-extra-extra-large-deps/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('bluebird'); 4 | require('lodash'); 5 | require('superagent-promise')(require('superagent'), Promise); 6 | require('googleapis'); 7 | require('aws-sdk'); 8 | require('co'); 9 | require('fb'); 10 | require('imagemagick'); 11 | require('mongodb'); 12 | require('request-promise'); 13 | require('neo4j'); 14 | require('sinon'); 15 | require('react'); 16 | require('react-dom'); 17 | require('underscore'); 18 | require('commander'); 19 | require('jquery'); 20 | require('express'); 21 | require('body-parser'); 22 | require('cheerio'); 23 | require("glob"); 24 | require('classnames'); 25 | require('uuid/v1'); 26 | require('http'); 27 | require("redis"); 28 | 29 | module.exports.handler = (event, context, callback) => { 30 | const response = { 31 | statusCode: 200, 32 | body: JSON.stringify({ 33 | msg: "hello" 34 | }) 35 | }; 36 | 37 | callback(null, response); 38 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-extra-extra-large-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda-coldstart-comparison", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aws-sdk": "^2.32.0", 13 | "babel-core": "^6.25.0", 14 | "bluebird": "^3.5.0", 15 | "body-parser": "^1.17.2", 16 | "bower": "^1.8.0", 17 | "chai": "^3.5.0", 18 | "chalk": "^1.1.3", 19 | "cheerio": "^1.0.0-rc.1", 20 | "classnames": "^2.2.5", 21 | "co": "^4.6.0", 22 | "commander": "^2.9.0", 23 | "express": "^4.15.3", 24 | "fb": "^1.1.1", 25 | "glob": "^7.1.2", 26 | "googleapis": "^18.0.0", 27 | "grunt": "^1.0.1", 28 | "gulp": "^3.9.1", 29 | "gulp-util": "^3.0.8", 30 | "imagemagick": "^0.1.3", 31 | "jquery": "^3.2.1", 32 | "lodash": "^4.17.4", 33 | "mocha": "^3.2.0", 34 | "mongodb": "^2.2.25", 35 | "neo4j": "^2.0.0-RC2", 36 | "node-uuid": "^1.4.8", 37 | "react": "^15.6.1", 38 | "react-dom": "^15.6.1", 39 | "redis": "^2.7.1", 40 | "redux": "^3.7.0", 41 | "request": "^2.81.0", 42 | "request-promise": "^4.2.0", 43 | "serverless": "^1.15.3", 44 | "sinon": "^2.1.0", 45 | "socket.io": "^2.0.3", 46 | "superagent": "^3.5.2", 47 | "superagent-promise": "^1.1.0", 48 | "underscore": "^1.8.3", 49 | "webpack": "^2.6.1", 50 | "yeoman-generator": "^1.1.1" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-extra-large-deps/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('bluebird'); 4 | require('lodash'); 5 | require('superagent-promise')(require('superagent'), Promise); 6 | require('googleapis'); 7 | require('aws-sdk'); 8 | require('co'); 9 | require('fb'); 10 | require('imagemagick'); 11 | require('mongodb'); 12 | require('request-promise'); 13 | require('neo4j'); 14 | require('sinon'); 15 | require('react'); 16 | require('react-dom'); 17 | require('underscore'); 18 | require('commander'); 19 | require('jquery'); 20 | require('express'); 21 | 22 | module.exports.handler = (event, context, callback) => { 23 | const response = { 24 | statusCode: 200, 25 | body: JSON.stringify({ 26 | msg: "hello" 27 | }) 28 | }; 29 | 30 | callback(null, response); 31 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-extra-large-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda-coldstart-comparison", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aws-sdk": "^2.32.0", 13 | "babel-core": "^6.25.0", 14 | "bluebird": "^3.5.0", 15 | "chai": "^3.5.0", 16 | "chalk": "^1.1.3", 17 | "co": "^4.6.0", 18 | "commander": "^2.9.0", 19 | "express": "^4.15.3", 20 | "fb": "^1.1.1", 21 | "googleapis": "^18.0.0", 22 | "imagemagick": "^0.1.3", 23 | "jquery": "^3.2.1", 24 | "lodash": "^4.17.4", 25 | "mocha": "^3.2.0", 26 | "mongodb": "^2.2.25", 27 | "neo4j": "^2.0.0-RC2", 28 | "react": "^15.6.1", 29 | "react-dom": "^15.6.1", 30 | "request": "^2.81.0", 31 | "request-promise": "^4.2.0", 32 | "serverless": "^1.15.3", 33 | "sinon": "^2.1.0", 34 | "superagent": "^3.5.2", 35 | "superagent-promise": "^1.1.0", 36 | "underscore": "^1.8.3", 37 | "yeoman-generator": "^1.1.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-large-deps/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('bluebird'); 4 | require('lodash'); 5 | require('superagent-promise')(require('superagent'), Promise); 6 | require('googleapis'); 7 | require('aws-sdk'); 8 | require('co'); 9 | require('fb'); 10 | require('imagemagick'); 11 | require('mongodb'); 12 | require('request-promise'); 13 | require('neo4j'); 14 | require('sinon'); 15 | 16 | module.exports.handler = (event, context, callback) => { 17 | const response = { 18 | statusCode: 200, 19 | body: JSON.stringify({ 20 | msg: "hello" 21 | }) 22 | }; 23 | 24 | callback(null, response); 25 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/extra-large-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda-coldstart-comparison", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aws-sdk": "^2.32.0", 13 | "bluebird": "^3.5.0", 14 | "chai": "^3.5.0", 15 | "co": "^4.6.0", 16 | "fb": "^1.1.1", 17 | "googleapis": "^18.0.0", 18 | "imagemagick": "^0.1.3", 19 | "lodash": "^4.17.4", 20 | "mocha": "^3.2.0", 21 | "mongodb": "^2.2.25", 22 | "neo4j": "^2.0.0-RC2", 23 | "request": "^2.81.0", 24 | "request-promise": "^4.2.0", 25 | "sinon": "^2.1.0", 26 | "superagent": "^3.5.2", 27 | "superagent-promise": "^1.1.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/large-deps/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Promise = require('bluebird'); 4 | const _ = require('lodash'); 5 | const http = require('superagent-promise')(require('superagent'), Promise); 6 | const google = require('googleapis'); 7 | 8 | module.exports.handler = (event, context, callback) => { 9 | const response = { 10 | statusCode: 200, 11 | body: JSON.stringify({ 12 | msg: "hello" 13 | }) 14 | }; 15 | 16 | callback(null, response); 17 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/large-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "large-deps", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bluebird": "^3.5.0", 13 | "googleapis": "^18.0.0", 14 | "lodash": "^4.17.4", 15 | "superagent": "^3.5.2", 16 | "superagent-promise": "^1.1.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /nodejs6-diff-package-size/no-deps/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let isColdstart = false; 4 | 5 | module.exports.handler = (event, context, callback) => { 6 | if (!isColdstart) { 7 | isColdstart = true; 8 | console.log("this is a coldstart"); 9 | } 10 | 11 | const response = { 12 | statusCode: 200, 13 | body: JSON.stringify({ 14 | msg: "hello" 15 | }) 16 | }; 17 | 18 | callback(null, response); 19 | }; -------------------------------------------------------------------------------- /nodejs6-diff-package-size/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-nodejs6-package-size 2 | 3 | provider: 4 | name: aws 5 | runtime: nodejs4.3 6 | versionFunctions: false 7 | 8 | package: 9 | individually: true 10 | exclude: 11 | - no-deps/** 12 | - bluebird-only/** 13 | - bluebird-lodash-only/** 14 | - large-deps/** 15 | - extra-large-deps/** 16 | - extra-extra-large-deps/** 17 | - extra-extra-extra-large-deps/** 18 | - ping/** 19 | 20 | functions: 21 | no-deps-128: 22 | handler: no-deps/handler.handler 23 | memorySize: 128 24 | package: 25 | include: 26 | - no-deps/** 27 | no-deps-256: 28 | handler: no-deps/handler.handler 29 | memorySize: 256 30 | package: 31 | include: 32 | - no-deps/** 33 | no-deps-512: 34 | handler: no-deps/handler.handler 35 | memorySize: 512 36 | package: 37 | include: 38 | - no-deps/** 39 | no-deps-1024: 40 | handler: no-deps/handler.handler 41 | memorySize: 1024 42 | package: 43 | include: 44 | - no-deps/** 45 | no-deps-1536: 46 | handler: no-deps/handler.handler 47 | memorySize: 1536 48 | package: 49 | include: 50 | - no-deps/** 51 | 52 | bluebird-only-128: 53 | handler: bluebird-only/handler.handler 54 | memorySize: 128 55 | package: 56 | include: 57 | - bluebird-only/** 58 | bluebird-only-256: 59 | handler: bluebird-only/handler.handler 60 | memorySize: 256 61 | package: 62 | include: 63 | - bluebird-only/** 64 | bluebird-only-512: 65 | handler: bluebird-only/handler.handler 66 | memorySize: 512 67 | package: 68 | include: 69 | - bluebird-only/** 70 | bluebird-only-1024: 71 | handler: bluebird-only/handler.handler 72 | memorySize: 1024 73 | package: 74 | include: 75 | - bluebird-only/** 76 | bluebird-only-1536: 77 | handler: bluebird-only/handler.handler 78 | memorySize: 1536 79 | package: 80 | include: 81 | - bluebird-only/** 82 | 83 | bluebird-lodash-only-128: 84 | handler: bluebird-lodash-only/handler.handler 85 | memorySize: 128 86 | package: 87 | include: 88 | - bluebird-lodash-only/** 89 | bluebird-lodash-only-256: 90 | handler: bluebird-lodash-only/handler.handler 91 | memorySize: 256 92 | package: 93 | include: 94 | - bluebird-lodash-only/** 95 | bluebird-lodash-only-512: 96 | handler: bluebird-lodash-only/handler.handler 97 | memorySize: 512 98 | package: 99 | include: 100 | - bluebird-lodash-only/** 101 | bluebird-lodash-only-1024: 102 | handler: bluebird-lodash-only/handler.handler 103 | memorySize: 1024 104 | package: 105 | include: 106 | - bluebird-lodash-only/** 107 | bluebird-lodash-only-1536: 108 | handler: bluebird-lodash-only/handler.handler 109 | memorySize: 1536 110 | package: 111 | include: 112 | - bluebird-lodash-only/** 113 | 114 | L-deps-128: 115 | handler: large-deps/handler.handler 116 | memorySize: 128 117 | package: 118 | include: 119 | - large-deps/** 120 | L-deps-256: 121 | handler: large-deps/handler.handler 122 | memorySize: 256 123 | package: 124 | include: 125 | - large-deps/** 126 | L-deps-512: 127 | handler: large-deps/handler.handler 128 | memorySize: 512 129 | package: 130 | include: 131 | - large-deps/** 132 | L-deps-1024: 133 | handler: large-deps/handler.handler 134 | memorySize: 1024 135 | package: 136 | include: 137 | - large-deps/** 138 | L-deps-1536: 139 | handler: large-deps/handler.handler 140 | memorySize: 1536 141 | package: 142 | include: 143 | - large-deps/** 144 | 145 | XL-deps-128: 146 | handler: extra-large-deps/handler.handler 147 | memorySize: 128 148 | package: 149 | include: 150 | - extra-large-deps/** 151 | XL-deps-256: 152 | handler: extra-large-deps/handler.handler 153 | memorySize: 256 154 | package: 155 | include: 156 | - extra-large-deps/** 157 | XL-deps-512: 158 | handler: extra-large-deps/handler.handler 159 | memorySize: 512 160 | package: 161 | include: 162 | - extra-large-deps/** 163 | XL-deps-1024: 164 | handler: extra-large-deps/handler.handler 165 | memorySize: 1024 166 | package: 167 | include: 168 | - extra-large-deps/** 169 | XL-deps-1536: 170 | handler: extra-large-deps/handler.handler 171 | memorySize: 1536 172 | package: 173 | include: 174 | - extra-large-deps/** 175 | 176 | XXL-deps-128: 177 | handler: extra-extra-large-deps/handler.handler 178 | memorySize: 128 179 | package: 180 | include: 181 | - extra-extra-large-deps/** 182 | XXL-deps-256: 183 | handler: extra-extra-large-deps/handler.handler 184 | memorySize: 256 185 | package: 186 | include: 187 | - extra-extra-large-deps/** 188 | XXL-deps-512: 189 | handler: extra-extra-large-deps/handler.handler 190 | memorySize: 512 191 | package: 192 | include: 193 | - extra-extra-large-deps/** 194 | XXL-deps-1024: 195 | handler: extra-extra-large-deps/handler.handler 196 | memorySize: 1024 197 | package: 198 | include: 199 | - extra-extra-large-deps/** 200 | XXL-deps-1536: 201 | handler: extra-extra-large-deps/handler.handler 202 | memorySize: 1536 203 | package: 204 | include: 205 | - extra-extra-large-deps/** 206 | 207 | XXXL-deps-128: 208 | handler: extra-extra-extra-large-deps/handler.handler 209 | memorySize: 128 210 | package: 211 | include: 212 | - extra-extra-extra-large-deps/** 213 | XXXL-deps-256: 214 | handler: extra-extra-extra-large-deps/handler.handler 215 | memorySize: 256 216 | package: 217 | include: 218 | - extra-extra-extra-large-deps/** 219 | XXXL-deps-512: 220 | handler: extra-extra-extra-large-deps/handler.handler 221 | memorySize: 512 222 | package: 223 | include: 224 | - extra-extra-extra-large-deps/** 225 | XXXL-deps-1024: 226 | handler: extra-extra-extra-large-deps/handler.handler 227 | memorySize: 1024 228 | package: 229 | include: 230 | - extra-extra-extra-large-deps/** 231 | XXXL-deps-1536: 232 | handler: extra-extra-extra-large-deps/handler.handler 233 | memorySize: 1536 234 | package: 235 | include: 236 | - extra-extra-extra-large-deps/** -------------------------------------------------------------------------------- /nodejs6/.npmignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /nodejs6/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = (event, context, callback) => { 4 | const response = { 5 | statusCode: 200, 6 | body: "hello" 7 | }; 8 | 9 | callback(null, response); 10 | 11 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 12 | // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event }); 13 | }; 14 | -------------------------------------------------------------------------------- /nodejs6/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-nodejs6 2 | 3 | provider: 4 | name: aws 5 | runtime: nodejs6.10 6 | versionFunctions: false 7 | 8 | functions: 9 | memory-128: 10 | handler: handler.hello 11 | memorySize: 128 12 | 13 | memory-256: 14 | handler: handler.hello 15 | memorySize: 256 16 | 17 | memory-512: 18 | handler: handler.hello 19 | memorySize: 512 20 | 21 | memory-1024: 22 | handler: handler.hello 23 | memorySize: 1024 24 | 25 | memory-1536: 26 | handler: handler.hello 27 | memorySize: 1536 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lambda-coldstart-comparison", 3 | "version": "1.0.0", 4 | "description": "Comparing the coldstart time of AWS Lambda functions using a variety of language runtime and memory size", 5 | "main": "invoke-functions.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/theburningmonk/lambda-coldstart-comparison.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/theburningmonk/lambda-coldstart-comparison/issues" 17 | }, 18 | "homepage": "https://github.com/theburningmonk/lambda-coldstart-comparison#readme", 19 | "dependencies": { 20 | "aws-sdk": "^2.64.0", 21 | "bluebird": "^3.5.0", 22 | "co": "^4.6.0", 23 | "fast-stats": "0.0.3", 24 | "lodash": "^4.17.4", 25 | "mathjs": "^3.13.3", 26 | "plotly": "^1.0.6" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /python/.npmignore: -------------------------------------------------------------------------------- 1 | # Distribution / packaging 2 | .Python 3 | env/ 4 | build/ 5 | develop-eggs/ 6 | dist/ 7 | downloads/ 8 | eggs/ 9 | .eggs/ 10 | lib/ 11 | lib64/ 12 | parts/ 13 | sdist/ 14 | var/ 15 | *.egg-info/ 16 | .installed.cfg 17 | *.egg 18 | 19 | # Serverless directories 20 | .serverless -------------------------------------------------------------------------------- /python/handler.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def hello(event, context): 4 | return { 5 | "statusCode": 200, 6 | "body": "hello" 7 | } 8 | -------------------------------------------------------------------------------- /python/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-coldstart-python 2 | 3 | provider: 4 | name: aws 5 | runtime: python3.6 6 | versionFunctions: false 7 | 8 | functions: 9 | memory-128: 10 | handler: handler.hello 11 | memorySize: 128 12 | 13 | memory-256: 14 | handler: handler.hello 15 | memorySize: 256 16 | 17 | memory-512: 18 | handler: handler.hello 19 | memorySize: 512 20 | 21 | memory-1024: 22 | handler: handler.hello 23 | memorySize: 1024 24 | 25 | memory-1536: 26 | handler: handler.hello 27 | memorySize: 1536 --------------------------------------------------------------------------------