-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.html
289 lines (266 loc) · 15.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Serverless costs calculator for AWS Lambda</title>
<meta name="description" content="Estimate AWS costs when running serverless applications on AWS Lambda. The calculator can be used for APIs, websites and more." />
<meta property="og:title" content="Serverless costs calculator for AWS Lambda" />
<meta property="og:description" content="Estimate AWS costs when running serverless applications on AWS Lambda. The calculator can be used for APIs, websites and more." />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Serverless costs calculator" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Serverless costs calculator for AWS Lambda" />
<meta name="twitter:description" content="Estimate AWS costs when running serverless applications on AWS Lambda. The calculator can be used for APIs, websites and more." />
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Montserrat|Rubik&display=swap" rel="stylesheet">
<style>
h1, h2 {
font-family: 'Rubik', sans-serif;
}
.font-sans {
font-family: 'Montserrat', sans-serif;
}
</style>
<meta name="google-site-verification" content="RRmKDrWI2l69B0nMwv4ndrYOHSuaTBfarvCgtJxMpXA" />
</head>
<body class="bg-grey-lighter font-sans">
<div id="app" class="container mx-auto my-4 px-4 max-w-lg">
<h1 class="mt-8 mb-2 text-3xl sm:text-4xl">Serverless costs calculator</h1>
<p class="mb-8 text-gray-600 text-sm">Estimate AWS costs when running serverless applications on AWS Lambda.</p>
<div class="my-8 flex flex-wrap">
<button class="sm:flex-auto bg-indigo-500 hover:bg-indigo-400 text-white py-1 px-2 m-1 ml-0 border-b-4 border-indigo-700 hover:border-indigo-500 rounded" @click="loadSmallAPI()">Small API</button>
<button class="sm:flex-auto bg-indigo-500 hover:bg-indigo-400 text-white py-1 px-2 m-1 border-b-4 border-indigo-700 hover:border-indigo-500 rounded" @click="loadLargeAPI()">Large API</button>
<button class="sm:flex-auto bg-indigo-500 hover:bg-indigo-400 text-white py-1 px-2 m-1 border-b-4 border-indigo-700 hover:border-indigo-500 rounded" @click="loadSmallWebsite()">Small website</button>
<button class="sm:flex-auto bg-indigo-500 hover:bg-indigo-400 text-white py-1 px-2 m-1 mr-0 border-b-4 border-indigo-700 hover:border-indigo-500 rounded" @click="loadLargeWebsite()">Large website</button>
</div>
<h2 class="my-4 text-xl">Backend (assets excluded)</h2>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="requestsPerMonth">
HTTP requests per month
</label>
</div>
<div class="md:w-1/2">
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-indigo-500" id="requestsPerMonth" type="number" v-model="requestsPerMonth">
</div>
</div>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="averageExecutionTime">
Average execution time (ms)
</label>
</div>
<div class="md:w-1/2">
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-indigo-500" id="averageExecutionTime" type="number" v-model="averageExecutionTime">
</div>
</div>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="averageResponseSizeInKb">
Average response size (Kb)
</label>
</div>
<div class="md:w-1/2">
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-indigo-500" id="averageResponseSizeInKb" type="number" v-model="averageResponseSizeInKb">
</div>
</div>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="lambdaMemorySize">
Lambda size
<a class="ml-2" href="https://epsagon.com/blog/how-to-make-lambda-faster-memory-performance-benchmark/" target="_blank">
<svg class="inline fill-current h-4 w-4 text-indigo-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z"/></svg>
</a>
</label>
</div>
<div class="md:w-1/2">
<div class="inline-block relative w-full">
<select id="lambdaMemorySize" class="bg-gray-200 block appearance-none w-full border-2 border-gray-200 px-4 py-2 pr-8 text-gray-700 rounded leading-tight focus:outline-none focus:bg-white focus:border-indigo-500"
v-model="lambdaMemorySize">
<option value="128">128M</option>
<option value="256">256M</option>
<option value="512">512M</option>
<option value="1024">1024M (recommended)</option>
<option value="1792">1792M</option>
<option value="2048">2048M</option>
</select>
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
</div>
</div>
</div>
</div>
<h2 class="my-4 text-xl">Assets</h2>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="assetsCount">
Average number of assets (CSS, JS, images…) per page
</label>
</div>
<div class="md:w-1/2">
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-indigo-500" id="assetsCount" type="number" v-model="assetsCount">
</div>
</div>
<div class="md:flex md:items-center mb-6">
<div class="md:w-1/2">
<label class="block text-gray-600 md:text-right pr-4" for="assetsTotalSizeInKb">
Total assets size per page (Kb)
</label>
</div>
<div class="md:w-1/2">
<input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-indigo-500" id="assetsTotalSizeInKb" type="number" v-model="assetsTotalSizeInKb">
</div>
</div>
<h2 class="my-4 text-xl">Database</h2>
<p class="my-2 text-gray-600">
<a class="underline" href="https://aws.amazon.com/en/rds/pricing/" target="_blank">Database prices</a> can vary based on many factors, which is why we do not include it in this calculator.
</p>
<p class="my-2 text-gray-600">
For small applications, the cheapest option starts at $9.40/month (MySQL db.t3.micro reserved instance).
</p>
<h2 class="my-4 text-xl">Monthly cost</h2>
<p class="p-1 text-gray-700">
AWS Lambda
<span class="float-right">${{ lambdaTotal.toFixed(2) }}</span>
</p>
<p class="p-1 text-gray-700">
API Gateway
<span class="float-right">${{ apiGatewayTotal.toFixed(2) }}</span>
</p>
<p class="p-1 text-gray-700">
AWS S3
<span class="float-right">${{ s3Total.toFixed(2) }}</span>
</p>
<p class="p-1 text-gray-700">
CloudFront
<span class="float-right">${{ cloudFrontTotal.toFixed(2) }}</span>
</p>
<p class="my-5 p-4 text-xl uppercase border-b border-b-2 border-indigo-500 bg-gray-100 text-gray-700">
Total
<span class="float-right font-bold">${{ total.toFixed(2) }}</span>
</p>
<p class="my-8 text-sm text-gray-500">
The AWS free tier is ignored to avoid any surprise. The cost estimated above is just that: an estimation. Plan a safety margin of 50% or even 100%.
Also be aware that <a href="https://aws.amazon.com/elasticloadbalancing/pricing/" class="underline">AWS ALB</a> is a much cheaper alternative to API Gateway at scale.
It is not included in the calculator yet, that is for another rainy day ;)
</p>
<p class="mt-20 mb-8 text-xl text-right">
Serverless costs calculator by
<a class="underline" href="https://bref.sh/" title="Serverless PHP applications">bref</a>.
</p>
<p class="mb-20 text-lg text-right">
Want training? Join our
<a class="underline" href="https://training.bref.sh/?utm_source=cost-calculator&utm_medium=footer&utm_campaign=workshop" title="Serverless PHP workshop and training">Serverless PHP workshops</a>.
</p>
<p class="my-16 text-sm text-gray-500 text-center">
Need help getting started with serverless? <a href="https://null.tc/" class="underline" title="Null serverless consulting company">Get in touch</a>!
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
requestsPerMonth: 5000000.,
averageExecutionTime: 300.,
averageResponseSizeInKb: 3.,
lambdaMemorySize: 1024,
assetsCount: 5.,
assetsTotalSizeInKb: 200.,
lambdaCostPerRequest: 0.0000002,
lambdaCostPer100ms: 0.000001667,
apiGatewayCostPerMillion: 3.5,
apiGatewayDataTransferCostPerGb: 0.09,
s3CostPer1000: 0.0004,
cloudFrontCostPer10000: 0.01,
cloudFrontDataTransferCostPerGb: 0.085 + 0.02,
lambdaTotal: 0,
apiGatewayTotal: 0,
s3Total: 0,
cloudFrontTotal: 0,
total: 0,
},
created: function () {
this.loadSmallWebsite();
this.recalculate();
},
methods: {
recalculate: function () {
const pagesLoadedPerMonth = this.requestsPerMonth / 2;
const billedAverageExecutionTime = Math.max(100., this.averageExecutionTime);
const lambdaRequestsCost = this.requestsPerMonth * this.lambdaCostPerRequest;
const lambdaCostPer100msForLambda = this.lambdaCostPer100ms * this.lambdaMemorySize / 1024.;
const lambdaTimeCost = this.requestsPerMonth * billedAverageExecutionTime * lambdaCostPer100msForLambda / 100.;
this.lambdaTotal = lambdaRequestsCost + lambdaTimeCost;
const apiGatewayInvocationCosts = this.requestsPerMonth * this.apiGatewayCostPerMillion / 1000000.;
const apiGatewayDataTransferCosts = this.requestsPerMonth * this.averageResponseSizeInKb * this.apiGatewayDataTransferCostPerGb / 1024. / 1024.;
this.apiGatewayTotal = apiGatewayInvocationCosts + apiGatewayDataTransferCosts;
const s3InvocationCosts = pagesLoadedPerMonth * this.assetsCount * this.s3CostPer1000 / 1000.;
this.s3Total = s3InvocationCosts;
this.cloudFrontTotal = 0;
// Only count CloudFront if assets are involved
if (this.assetsCount > 0) {
const cloudFrontPHPInvocationCosts = this.requestsPerMonth * this.cloudFrontCostPer10000 / 10000.;
const cloudFrontPHPDataTransferCosts = this.requestsPerMonth * this.averageResponseSizeInKb * this.cloudFrontDataTransferCostPerGb / 1024. / 1024.;
const cloudFrontAssetsInvocationCosts = pagesLoadedPerMonth * this.assetsCount * this.cloudFrontCostPer10000 / 10000.;
const cloudFrontAssetsDataTransferCosts = pagesLoadedPerMonth * this.assetsTotalSizeInKb * this.cloudFrontDataTransferCostPerGb / 1024. / 1024.;
this.cloudFrontTotal = cloudFrontPHPInvocationCosts + cloudFrontPHPDataTransferCosts
+ cloudFrontAssetsInvocationCosts + cloudFrontAssetsDataTransferCosts;
}
this.total = this.lambdaTotal + this.apiGatewayTotal + this.cloudFrontTotal;
},
loadSmallAPI: function() {
this.requestsPerMonth = 3000.;
this.averageExecutionTime = 100.;
this.averageResponseSizeInKb = 0.3;
this.lambdaMemorySize = 1024;
this.assetsCount = 0.;
this.assetsTotalSizeInKb = 0.;
},
loadLargeAPI: function() {
this.requestsPerMonth = 5000000.;
this.averageExecutionTime = 100.;
this.averageResponseSizeInKb = 0.3;
this.lambdaMemorySize = 1024;
this.assetsCount = 0.;
this.assetsTotalSizeInKb = 0.;
},
loadSmallWebsite: function() {
this.requestsPerMonth = 3000.;
this.averageExecutionTime = 200.;
this.averageResponseSizeInKb = 3.;
this.lambdaMemorySize = 1024;
this.assetsCount = 5.;
this.assetsTotalSizeInKb = 200.;
},
loadLargeWebsite: function() {
this.requestsPerMonth = 5000000.;
this.averageExecutionTime = 300.;
this.averageResponseSizeInKb = 3.;
this.lambdaMemorySize = 1024;
this.assetsCount = 5.;
this.assetsTotalSizeInKb = 200.;
},
},
watch: {
requestsPerMonth: 'recalculate',
averageExecutionTime: 'recalculate',
averageResponseSizeInKb: 'recalculate',
lambdaMemorySize: 'recalculate',
assetsCount: 'recalculate',
assetsTotalSizeInKb: 'recalculate',
},
});
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-15584647-22"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-15584647-22');
</script>
</body>
</html>