Course-এর সূচি

15.2

Lambda-র সীমা, Concurrency আর Cold Start

চলার সীমা, reserved আর provisioned concurrency, throttling আর retry, cold start আর SnapStart।

26 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই লেসন শেষে তুমি পারবে

  • Lambda-র যে সীমাগুলো design বদলে দেয়, সেগুলো মুখস্থ বলতে (memory ১২৮ MB থেকে ১০,২৪০ MB, timeout ১৫ মিনিট, synchronous payload ৬ MB আর asynchronous ১ MB, package zip অবস্থায় ৫০ MB / unzip করে ২৫০ MB, container image ১০ GB, /tmp ৫১২ MB থেকে ১০,২৪০ MB, environment variable মিলিয়ে ৪ KB, ৫টা layer), আর প্রতিটার পাশ কাটানোর চেনা উপায়টা বলতে।
  • কেন CPU আসে memory-র সাথে (১,৭৬৯ MB-তে একটা vCPU, ১০,২৪০ MB-তে ছয়টা পর্যন্ত), আর কেন বড় function একই দামে দ্রুত চলতে পারে, সেটা বোঝাতে।
  • একটা workload-এর কত concurrency লাগবে হিসাব করতে (প্রতি সেকেন্ডে request × সেকেন্ডে গড় duration), আর সেটা account quota, প্রতি unit-এ ১০ request per second-এর নিয়ম, আর প্রতি function-এ প্রতি ১০ সেকেন্ডে ১,০০০টা নতুন execution environment-এর scaling গতির সাথে মিলিয়ে দেখতে।
  • Throttle হওয়া invocation-এর কী হয়, আগেই বলে দিতে: synchronous caller পায় 429, asynchronous event ৬ ঘণ্টা পর্যন্ত retry হয় তারপর destination বা DLQ-তে যায়, আর SQS-এর message queue-তেই থেকে যায়।
  • Reserved concurrency-কে তিনভাবে ব্যবহার করতে: নিশ্চয়তা, downstream database বাঁচানোর ছাদ, আর kill switch (০); আর জানতে যে ১০০ unit সবসময় unreserved থাকে।
  • Cold start ব্যাখ্যা করতে (Init, Invoke, Shutdown), সেটা ছোট করতে, আর provisioned concurrency (Application Auto Scaling সহ) আর SnapStart-এর মধ্যে বাছতে, SnapStart-এর uniqueness আর network connection-এর সাবধানতা সহ।

#সীমা আর concurrency কেন জরুরি

Lesson 15.1-এ Lambda-কে চেনানো হয়েছিল এভাবে: “server সামলাতে হয় না, নিজে নিজে বাড়ে, request প্রতি টাকা”। সবই সত্যি, কিন্তু Lambda বাড়ে একটা বেড়ার ভেতরে। একটা function সর্বোচ্চ ১৫ মিনিট চলতে পারে, synchronous caller-এর কাছ থেকে সর্বোচ্চ ৬ MB নিতে পারে, আর পুরো account মিলে concurrent execution-এর একটাই pool ভাগ করে। Production-এ Lambda নিয়ে বেশিরভাগ ঝামেলা আসলে code-এর bug না: হয় কোনো function এই বেড়াগুলোর একটায় ধাক্কা খায়, নয়তো এক function pool-টা খেয়ে ফেলে যেটা আরেকজনের দরকার ছিল।

এই লেসনে তিনটা জিনিস: বেড়াগুলো (সীমা), pool-টা (concurrency, reserved concurrency, throttling), আর নতুন কপি চালু হওয়ার দেরি (cold start, provisioned concurrency, SnapStart)। পরীক্ষায় তিনটাই আসে, সাধারণত একটা ঘটনার আকারে: “marketing campaign-এর সময় payment throttle হচ্ছে”, “deploy-এর পরের প্রথম request ধীর”, “একটা Java function চালু হতে কয়েক সেকেন্ড নেয়”।

#যে সীমাগুলো Lambda-র design ঠিক করে দেয়

সব quota প্রতি Region-এ (প্রতি account-এ)। প্রথম দিকের সীমাগুলো কখনো বাড়ানো যায় না; concurrency বাড়ানো যায়।

সীমামানবাড়ানো যায়?ধাক্কা খেলে কী করবে
Memory১২৮ MB থেকে ১০,২৪০ MB, ১ MB করেনাকাজ ভাগ করো, নয়তো Fargate / EC2-তে সরাও
Timeoutপ্রতি invocation-এ ৯০০ সেকেন্ড (১৫ মিনিট)নাকাজ ভাগ করতে Step Functions (lesson 15.7), নয়তো Fargate (lesson 14.2)
Synchronous payloadrequest ৬ MB, response ৬ MB (streamed response ২০০ MB)নাPresigned URL দিয়ে S3-এ upload, Lambda-কে শুধু key দাও
Asynchronous payloadপ্রতি event ১ MB (২০২৫-এর আগে ২৫৬ KB)নাData S3-এ রাখো, শুধু ঠিকানাটা পাঠাও
Environment variableসব মিলিয়ে ৪ KBনাParameter Store বা Secrets Manager (chapter 21)
.zip packageসরাসরি upload-এ zip অবস্থায় ৫০ MB, layer সহ unzip করে ২৫০ MBনাContainer image, বা বড় file init-এর সময় /tmp-তে নামাও
Container imageuncompressed ১০ GBনাএর চেয়ে বড় হলে Fargate
Layerপ্রতি function-এ ৫টানাLayer জোড়া লাগাও বা container image ব্যবহার করো
/tmp (ephemeral storage)default ৫১২ MB, সর্বোচ্চ ১০,২৪০ MBনাভাগ করা বা স্থায়ী data-র জন্য EFS বা S3
File descriptor, process আর threadপ্রতিটা ১,০২৪নাযা খোলো তা বন্ধ করো; কম thread
.zip function আর layer-এর code storageপ্রতি Region-এ ৩০০ GBনাপুরনো version মুছে ফেলো, বা code নিজের S3 bucket-এ রাখো
Concurrent executionপ্রতি account-এ প্রতি Region-এ ১,০০০হ্যাঁ, কয়েক হাজার থেকে কয়েক দশ হাজার পর্যন্তService Quotas-এ বাড়ানোর অনুরোধ, বা reserved concurrency দিয়ে ন্যায্য ভাগ
Scaling গতিপ্রতি function-এ প্রতি ১০ সেকেন্ডে ১,০০০টা নতুন execution environmentনাজানা spike-এর জন্য provisioned concurrency; SQS দিয়ে buffer

তিনটা সংখ্যায় মানুষ সবচেয়ে বেশি হোঁচট খায়:

  • Synchronous বনাম asynchronous payload। API Gateway ১০ MB-র body নেয়, কিন্তু তার পেছনের Lambda নেয় মাত্র ৬ MB। Upload-এর বেলায় উত্তর সবসময় একই: client file-টা সোজা S3-এ রাখে (lesson 10.1, presigned URL), আর Lambda পায় শুধু bucket আর key। Asynchronous-এর সীমা ২০২৫-এ ২৫৬ KB থেকে বাড়িয়ে ১ MB করা হয়েছে; পুরনো প্রশ্ন আর slide এখনো ২৫৬ KB বলে।
  • ১৫ মিনিটের timeout। এটা প্রতি invocation-এর হিসাব। এর চেয়ে লম্বা কাজ হয় ধাপে ভাগ করতে হবে (Step Functions-এর Map state প্রতিটা item-এর জন্য function-কে একবার করে ডাকে), নয়তো সেটা Lambda-র কাজই না।
  • Package-এর আকার। Unzip করা ২৫০ MB-র মধ্যে সব layer-ও ধরা। Container image হলে সীমা ১০ GB। যেসব বড় file শুধু data (একটা model, একগাদা font), সেগুলো init-এর সময় /tmp-তে নামিয়ে নেওয়া যায়; execution environment যতক্ষণ আবার ব্যবহার হয়, ততক্ষণ সেগুলো থেকে যায়।

#Memory দিয়েই CPU কেনা

Lambda-তে CPU-র কোনো setting নেই। তুমি memory বাছো, আর Lambda সেই অনুপাতে CPU (আর network bandwidth) দেয়: ১,৭৬৯ MB-তে function পায় পুরো একটা vCPU-র সমান, আর ১০,২৪০ MB-তে ছয়টা vCPU পর্যন্ত। ১২৮ MB-তে পায় একটার ছোট্ট একটা ভাগ।

তাই “function তো মাত্র ৯০ MB নেয়, ১২৮ MB দিলেই চলে” ভাবনাটা অনেক সময় ভুল সাশ্রয়। দাম হয় GB-second ধরে: memory দ্বিগুণ করলে যদি duration অর্ধেক হয়, খরচ একই থাকে, আর user অপেক্ষা করে অর্ধেক সময়। কিন্তু code যতটা CPU কাজে লাগাতে পারে তার পরে (একটা single-threaded program ছয়টা vCPU কাজে লাগাতে পারে না), বেশি memory মানে শুধু বেশি খরচ। কয়েকটা মাপ চালিয়ে দেখো (open-source AWS Lambda Power Tuning tool কাজটা করে দেয়), তারপর যেখানে লাভ থেমে যায় সেই বিন্দুটা বাছো।

যখন Lambda-র একটা সীমাই design ঠিক করে দেয়

ঢাকার একটা e-commerce shop তাদের product-photo-র backend চালায় Lambda-তে। রোজকার চারটা কাজ গিয়ে ধাক্কা খায় চারটা কড়া সীমায়: synchronous payload ৬ MB, timeout ১৫ মিনিট, unzip করা package ২৫০ MB, আর CPU যেটা শুধু memory-র সাথেই আসে। প্রতিটার পাশ কাটানোর একটা চেনা উপায় আছে।

পরিস্থিতি

Synchronous payload ৬ MB-তেই থামে: বড় file S3-এ পাঠাও, Lambda-কে দাও শুধু key।

Seller app
API Gateway
photo function
S3 bucketphotos-example
POST 8 MB
ধাপ 1 / 4
1

একজন seller API দিয়ে ৮ MB-র একটা product video upload করল। API Gateway ১০ MB পর্যন্ত body নেয়, তাই সে request-টা এগিয়ে দিল।

#Concurrency: একসাথে কয়টা

Concurrency মানে একটা function ঠিক একই মুহূর্তে কয়টা request সামলাচ্ছে। চলতে থাকা প্রতিটা request একটা করে execution environment দখল করে রাখে (তোমার code load করা একটা ছোট Firecracker microVM)। একটা environment একবারে একটাই request সামলায়; শেষ হলে পরেরটা নিতে পারে। নতুন request এসে যদি দেখে সব environment ব্যস্ত, Lambda আরেকটা বানায়, সীমার মধ্যে থেকে।

AWS documentation-এর হাতের হিসাব:

Concurrency = প্রতি সেকেন্ডে গড় request × সেকেন্ডে গড় duration

  • প্রতি সেকেন্ডে ১০০ request, প্রতিটা ০.৫ সেকেন্ড → ৫০টা concurrent execution।
  • প্রতি সেকেন্ডে ৪০০ request, প্রতিটা ০.২৫ সেকেন্ড → ১০০।
  • প্রতি সেকেন্ডে ২,০০০ request, প্রতিটা ৩ সেকেন্ড → ৬,০০০: default ১,০০০-এর অনেক ওপরে, তাই quota না বাড়ানো পর্যন্ত বেশিরভাগ request throttle হবে।

খেয়াল করো ফলটা কী কী বদলায়: traffic যতটা, duration-ও ততটাই গুরুত্বপূর্ণ। Function-এর পেছনের database ১০০ ms থেকে ১ সেকেন্ডে ধীর হয়ে গেলে একই traffic-এ দশ গুণ concurrency লাগে। “Lambda আমাদের throttle করল” ধরনের অনেক ঘটনার শুরু আসলে ধীর একটা downstream থেকে, traffic-এর spike থেকে না।

#আরও দুটো ছাদ: request per second আর scaling-এর গতি

  • প্রতি unit concurrency-তে প্রতি সেকেন্ডে ১০টা request (synchronous)। Lambda প্রতিটা execution environment-কে প্রতি সেকেন্ডে ১০টা invocation-এ বেঁধে রাখে, তাই খুব ছোট function concurrency-র আগে এই সীমাতেই আটকায়। ২০ ms-এর একটা function প্রতি সেকেন্ডে ৫,০০০ request পেলে সূত্র অনুযায়ী লাগে ৫,০০০ × ০.০২ = ১০০ concurrency, কিন্তু ১০০ unit দিয়ে প্রতি সেকেন্ডে মাত্র ১,০০০ request চলে: আসলে লাগে ৫০০।
  • Scaling-এর গতি। প্রতিটা function প্রতি ১০ সেকেন্ডে ১,০০০টা পর্যন্ত নতুন execution environment যোগ করতে পারে (নভেম্বর ২০২৩ থেকে; তার আগে ছিল account জুড়ে ৫০০ থেকে ৩,০০০-এর একটা burst, তারপর মিনিটে ৫০০, পুরনো বই-খাতায় এখনো সেটাই লেখা)। কোনো নির্দিষ্ট মাত্রায় পৌঁছাতে কত সময় লাগবে, AWS সেটা লিখে দেয় না, তবে এই হার থেকে আন্দাজ করা যায়: শূন্য থেকে ৫,০০০ concurrent-এ যেতে মোটামুটি ৪০ থেকে ৫০ সেকেন্ড (প্রথম ১,০০০ সাথে সাথেই পাওয়া যায়, আর AWS হারটা ধাপে ধাপে না, একটানা ভরে দেয়), আর ততক্ষণ বর্তমান মাত্রার ওপরের request-গুলো throttle হয়। ওই নতুন environment-গুলোর প্রতিটাই আবার একটা করে cold start।

দরকারি metric-গুলো Lambda CloudWatch-এ পাঠায় (chapter 19): ConcurrentExecutions, Throttles, Duration, Invocations, আর provisioned concurrency-র জন্য ProvisionedConcurrencyUtilization।

Concurrency আর throttling-এর হিসাব

ঈদের আগের রাতে wallet-এর pay-merchant function। Traffic কত, একটা request-এ কত সময় লাগে, account-এর limit কত, চাইলে একটা reserved concurrency, আর account-এর বাকি function-গুলো এর মধ্যেই কতটা নিয়ে বসে আছে, বেছে নাও। তারপর হিসাব করো কে throttle হবে।

প্রতি সেকেন্ডে request

গড় duration

Account-এর concurrency limit

এই function-এর reserved concurrency

বাকি function-গুলো যতটা concurrency নিচ্ছে

ফল দেখতে “হিসাব করো” চাপো।

#Throttling: concurrency ফুরিয়ে গেলে কী হয়

একটা request-এর নতুন execution environment দরকার, অথচ function সেটা পাওয়ার অধিকার রাখে না (account-এর pool খালি, নয়তো function তার reserved concurrency-তে পৌঁছে গেছে), তখন Lambda তাকে throttle করে। এরপর কী হবে, সেটা পুরোপুরি নির্ভর করে function-কে কীভাবে ডাকা হয়েছিল তার ওপর (invocation-এর ধরন, lesson 15.1)।

#Synchronous: 429 সোজা caller-এর হাতে

API Gateway, ALB, function URL, Cognito trigger বা তোমার নিজের SDK call উত্তরের জন্য অপেক্ষা করে। Throttle হলে সাথে সাথে ফেরত আসে HTTP 429 (TooManyRequestsException, “Rate Exceeded”)। Lambda কিছুই জমিয়ে রাখে না: retry caller-কেই করতে হবে, ভালো হয় exponential backoff আর jitter দিয়ে (AWS SDK throttle হলে নিজেই এটা করে)। API Gateway-র পেছনে থাকলে user দেখে 429 বা 5xx-এর error page। Retry শুধু ছোট spike মসৃণ করে; টানা বেশি চাপ সামলাতে বেশি concurrency লাগে।

#Asynchronous: Lambda তোমার হয়ে ৬ ঘণ্টা পর্যন্ত retry করে

S3 event, SNS, EventBridge আর --invocation-type Event দিয়ে করা call যায় Lambda-র ভেতরের queue-তে, আর caller সাথে সাথে পায় 202 Accepted। চেষ্টাটা throttle হলে (429) বা system error হলে (5xx) Lambda event-টা আবার queue-তে রাখে আর পরে চেষ্টা করে; বিরতি বাড়ে ১ সেকেন্ড থেকে সর্বোচ্চ ৫ মিনিট পর্যন্ত, default-এ ৬ ঘণ্টা ধরে (একে বলে maximum event age, ৬০ সেকেন্ড থেকে ৬ ঘণ্টার মধ্যে বদলানো যায়)।

Function error (তোমার code-এ exception বা timeout) আলাদা ব্যাপার: default-এ Lambda সেটা দুবার retry করে (প্রায় ১ মিনিট পরে, তারপর আরও প্রায় ২ মিনিট পরে), আর তুমি ০, ১ বা ২ retry ঠিক করে দিতে পারো। যে event-এর retry বা বয়স শেষ, সে যায় on-failure destination-এ (SQS, SNS, EventBridge, আরেকটা Lambda function বা S3, error-এর বিস্তারিত সহ) বা পুরনো ধাঁচের dead-letter queue-তে (SQS বা SNS, শুধু event)। কোনোটাই না থাকলে সেটা চুপচাপ ফেলে দেওয়া হয়।

#Event source mapping: queue নিজেই buffer

SQS, Kinesis, DynamoDB Streams, MSK আর MQ-এর বেলায় Lambda-র নিজের poller উৎসটা পড়ে, তারপর একটা batch নিয়ে function-কে synchronously ডাকে। সেই invoke throttle হলে poller শুধু একটু পিছিয়ে যায়:

  • SQS: message delete হয় না; visibility timeout শেষে আবার দৃশ্যমান হয়, আবার পড়া হয়। Visibility timeout রাখো function timeout-এর অন্তত ৬ গুণ। কোনো message বারবার ব্যর্থ হয়ে queue-এর maxReceiveCount পার হলে চলে যায় queue-এর নিজের DLQ-তে (lesson 13.2), যেটা বসানো হয় queue-এর ওপর, function-এর ওপর না।
  • Kinesis আর DynamoDB Streams: shard অপেক্ষা করে আর একই batch আবার চেষ্টা করে, যতক্ষণ না সফল হয় বা record-এর মেয়াদ ফুরায়; তাই throttle হওয়া function সেই shard-এর পেছনের সবকিছু আটকে রাখে (lesson 13.5)।

একটা SQS queue সর্বোচ্চ কয়টা কপি চালু করতে পারবে, সেটা বাঁধতে শুধু reserved concurrency-র ওপর ভরসা না করে event source mapping-এর maximum concurrency (২ থেকে ১,০০০) ব্যবহার করো: তখন poller invoke করে throttle খাওয়ার বদলে পড়াই থামিয়ে দেয়, ফলে throttle-এর কারণে message DLQ-র দিকে ঠেলে দেওয়া হয় না। Function-এর reserved concurrency রাখো তার সব queue-এর maximum concurrency-র যোগফলের সমান বা বেশি।

Throttle হলো: request-টার তাহলে কী হয়?

Function-এর হাতে concurrency না থাকলে Lambda synchronous call তোমার হয়ে কোথাও জমিয়ে রাখে না। এরপর কী হবে, সেটা নির্ভর করে function-কে কীভাবে ডাকা হয়েছিল তার ওপর: synchronously, asynchronously, নাকি এমন একটা event source mapping দিয়ে যেটা queue থেকে টেনে আনে।

পরিস্থিতি

Caller সাথে সাথে error পায়, retry তাকেই করতে হয়।

Wallet app
S3 / SQS
Lambda service
function
on-failuredestination / DLQ
Invoke (sync)
ধাপ 1 / 7
1

App balance function-কে synchronously ডাকল আর উত্তরের জন্য অপেক্ষা করছে, যেমনটা API Gateway, ALB বা SDK করে।

#পুরো account-এর একটাই pool

১,০০০টা concurrent execution ওই Region-এর account-এর, প্রতিটা function-এর আলাদা না। Default-এ প্রতিটা function একই unreserved pool থেকে নেয়, যে আগে আসে সে আগে পায়।

#গোলমেলে প্রতিবেশী

Slide যে concurrency issue নিয়ে সাবধান করে, এটাই সেটা। ধরো ALB-র পেছনের একটা function-এ অনেক user, আর সে ১,০০০-এ উঠে গেল। এখন API Gateway-র পেছনের অল্প user-এর একটা function, আর SDK দিয়ে তৃতীয় একটা function ডাকা একটা script, দুজনেই পায় 429, যদিও তারা প্রায় চলেইনি। এক function-এর ঝড় বাকি সবাইকে না খাইয়ে রাখে: একটা marketing campaign payment বসিয়ে দিতে পারে, লাগামছাড়া একটা retry loop login বসিয়ে দিতে পারে।

#Reserved concurrency: নিশ্চয়তা আর ছাদ একসাথে

Reserved concurrency একটা function-এর জন্য নির্দিষ্ট সংখ্যক concurrent execution আলাদা করে রাখে:

  • নিশ্চয়তা (মেঝে): ওই unit-গুলো অন্য কোনো function ছুঁতে পারে না। pay-merchant-এর ৩০০ reserved থাকলে campaign যা-ই করুক, সে সবসময় ৩০০টা কপি চালাতে পারবে।
  • ছাদ: function তার reservation-এর বেশি কখনো নিতে পারে না, pool-এর বাকিটা অলস পড়ে থাকলেও। Slide লেখে “reserved concurrency (= limit)”; আসলে এটা দুটোই।
  • খরচ: বিনা পয়সায়।
  • পার্শ্বপ্রতিক্রিয়া: function অলস থাকলেও reservation shared pool থেকে বেরিয়ে যায়। ৩০০ reserved হলে বাকি সব function ভাগ করে ৭০০।
  • নিয়ম: যেসব function-এর reservation নেই, তাদের জন্য Lambda সবসময় ১০০ unit unreserved রাখে। Quota ১,০০০ হলে সব function মিলিয়ে সর্বোচ্চ ৯০০ reserve করা যায়।

ছাদের দিকটা নিশ্চয়তার মতোই কাজের:

  • নাজুক downstream বাঁচাও। যে function প্রতিটা কপিতে একটা করে database connection খোলে, আর database নেয় মাত্র ১০০টা, তাকে ধরো ৫০-এ বেঁধে দাও। (অনেক function একটা database ভাগ করলে ভালো উপায় RDS Proxy, lesson 15.3।)
  • Kill switch। Reserved concurrency ০ দিলে function-এর প্রতিটা নতুন invocation সাথে সাথে throttle হয়, কিছু মুছতে বা আবার deploy করতে হয় না। যেগুলো চলছিল সেগুলো শেষ হয়; setting সরালেই আবার চালু।
  • খরচ নিয়ন্ত্রণ: ছাদ থাকলে একটা bug বা attack কত টাকা খরচ করাতে পারবে, তারও সীমা থাকে।

একটা function-এর যদি account-এর অনুমতির চেয়েও বেশি লাগে, কোনো reservation কাজে আসবে না: quota বাড়ানোর অনুরোধ করো (slide বলে “support ticket খোলো”; এখন Service Quotas console)।

পুরো account-এর জন্য একটাই concurrency pool

একটা bKash-ধাঁচের wallet একই account আর Region-এ তিনটা function চালায়: payment, একটা cashback campaign, আর রাতের report। Default-এ তিনটাই একই ১,০০০ concurrent execution থেকে নেয়। দেখো একটা লাগামছাড়া function বাকিদের কী অবস্থা করে, আর reserved concurrency কীভাবে সেটা থামায়।

পরিস্থিতি

তিনটা function দরকার মতো ১,০০০ concurrent execution ভাগ করে নেয়।

Customer
API Gateway
Schedule রাত ২টা
Reports DBসর্বোচ্চ ১০০ conn
pay-merchant১২০ চলছে
cashback-promo৪০ চলছে
nightly-report
paymentcashback

ব্যবহৃত concurrency (account limit ১,০০০)

pay-merchantcashback-promonightly-reportpool-এ খালি
120400840
ধাপ 1 / 2
1

Concurrency মানে একটা function ঠিক এই মুহূর্তে কয়টা request সামলাচ্ছে; প্রতিটা request একটা করে execution environment দখল করে রাখে। Default quota হলো প্রতি account-এ প্রতি Region-এ ১,০০০, সব function মিলিয়ে।

#Cold start

#Execution environment-এর জীবনচক্র

প্রতিটা execution environment তিনটা ধাপ পার হয়:

  1. Init: Lambda microVM বানায়, তোমার code নামায়, runtime চালু করে (Node.js, Python, Java…), আর handler-এর বাইরের code একবার চালায়: import, configuration পড়া, SDK client আর database connection বানানো। On-demand-এ Init ধাপ সর্বোচ্চ ১০ সেকেন্ড নিতে পারে।
  2. Invoke: request-এর জন্য handler চলে। Handler ফেরার পরে environment জমিয়ে রাখা হয়, আবার ব্যবহারের জন্য; তাতে আসা পরের request Init পুরোটাই এড়িয়ে যায় (warm start)।
  3. Shutdown: অনেকক্ষণ অলস থাকা environment সরিয়ে ফেলা হয়; চাপ থাকলেও Lambda কয়েক ঘণ্টা পরপর environment বদলে নেয়।

Cold start মানে এমন request যাকে Init-এর জন্য অপেক্ষা করতে হয়। এটা হয় প্রতিটা নতুন environment-এর প্রথম request-এ: deploy-এর পরে, চুপচাপ একটা সময়ের পরে, আর spike-এর সময় বাড়তি প্রতিটা concurrent request-এ। সব মিলিয়ে cold start ১%-এরও কম invocation-এ হয়, কিন্তু সেগুলো জড়ো হয় সবচেয়ে খারাপ মুহূর্তে (spike-এর শুরুতে), আর ধরা পড়ে গড়ে না, p99 latency-তে।

Init ধীর হয় কেন, মোটামুটি বেশি থেকে কম দেখা কারণ অনুযায়ী: বড় package আর অনেক dependency, ভারী framework (Java-তে Spring Boot, বড় .NET app), অনেক client বা connection বানানো, file নামানো, আর ভাষা নিজেই (Java আর .NET, Node.js আর Python-এর চেয়ে ধীরে চালু হয়)। আগস্ট ২০২৫ থেকে Lambda সব ধরনের function-এর Init ধাপের জন্য bill করে, তাই ধীর init এখন latency-র সাথে টাকাও খায়।

#Cold start ছোট করার উপায়

  • দামি setup handler-এর বাইরে রাখো (client, connection, config): সেটা চলে প্রতি environment-এ একবার, প্রতি request-এ না। কিন্তু যা টিকে থাকতেই হবে এমন data সেখানে রেখো না; environment হারিয়ে যায়।
  • Package ছাঁটো: শুধু যে dependency লাগে, tree-shaking, হালকা framework।
  • বেশি memory Init-কেও দ্রুত করে, কারণ CPU আসে memory-র সাথে।
  • VPC-র ভেতরে Lambda আগে ENI বানাতে কয়েক সেকেন্ড বাড়তি নিত। ২০১৯ থেকে VPC function ভাগ করা Hyperplane ENI ব্যবহার করে, যা function configure করার সময়ই বানানো হয়, তাই VPC এখন cold start-এ চোখে পড়ার মতো কিছু যোগ করে না (lesson 15.3)। পুরনো লেখায় এখনো আছে “cold start-এর ভয়ে VPC এড়িয়ে চলো”।
  • তাতেও না হলে: provisioned concurrency বা SnapStart, নিচে আছে।

Cold start, warm start

একটা সংবাদপত্রের “সর্বশেষ শিরোনাম” function, API Gateway দিয়ে ডাকা হয়। নতুন একটা execution environment-এ প্রথম request-কে সেটা বানানো আর init code চালানোর দাম দিতে হয়; পরের request-গুলো সেটাই আবার ব্যবহার করে।

পরিস্থিতি

নতুন environment: code নামাও, runtime চালু করো, init চালাও, তারপর handler।

পাঠক
Lambda service
execution env
DynamoDB
GET /headlines
ধাপ 1 / 6
1

সকালের প্রথম request এল। এই function-এর কোনো execution environment নেই, নয়তো সবগুলো ব্যস্ত।

#Provisioned concurrency

Provisioned concurrency তোমার বেছে দেওয়া সংখ্যক execution environment আগে থেকেই initialize করে রাখে, তাই যে request সেগুলোতে পড়ে, তাকে কখনো Init-এর জন্য অপেক্ষা করতে হয় না (দুই অঙ্কের millisecond-এ উত্তর)।

  • এটা বসে একটা published version বা alias-এ, $LATEST-এ কখনো না। Caller-কে ওই alias বা version-ই ডাকতে হবে, নইলে সে এর সুবিধা পায় না।
  • Environment বরাদ্দ করার সময় Lambda init code চালায় (এক-দুই মিনিট লাগে), আর পরে environment বদলানোর সময় আবার চালায়, তাই handler-এর বাইরের code যত বেশি পারে তত কাজ সেরে রাখুক।
  • Spillover: provisioned সংখ্যার বেশি request সাধারণ on-demand environment নেয়, সাধারণ cold start সহ, unreserved pool থেকে (বা function-এর reserved concurrency থেকে)। সেই pool-ও খালি না হলে তারা throttle হয় না।
  • Reservation-এর মতোই এটা account-এর concurrency থেকে কাটে: সর্বোচ্চ provision করা যায় unreserved quota বিয়োগ ১০০, আর function-এ reserved concurrency থাকলে provisioned ≤ reserved।
  • যতক্ষণ configure করা থাকে, ততক্ষণ টাকা লাগে, ব্যস্ত হোক বা অলস: provisioned environment-এর জন্য প্রতি GB-second-এর একটা দাম (US East-এ প্রায় $0.0000041667 প্রতি GB-second), আর চলার সময় কম duration-এর দাম ($0.0000166667-এর বদলে $0.0000097222 প্রতি GB-second)। উদাহরণ: ২ GB-র ১০০টা environment এক ঘণ্টা = ১০০ × ২ × ৩,৬০০ = ৭,২০,০০০ GB-second ≈ কোনো request আসার আগেই ঘণ্টায় প্রায় $৩।
  • সংখ্যাটা সামলায় Application Auto Scaling (alias-কে scalable target হিসেবে register করো): জানা peak-এর জন্য scheduled scaling (অফিসের ভিড়ের ১৫ মিনিট আগে বাড়াও, পরে কমাও), আর ধীরে ধীরে বদলের জন্য ProvisionedConcurrencyUtilization-এর ওপর target tracking (ধরো ০.৭)। Target tracking সাড়া দেয় কয়েক মিনিটে, তাই হঠাৎ spike ততক্ষণ উপচে পড়ে। AWS docs বলে সাধারণ peak-এর চেয়ে প্রায় ১০% বেশি provision রাখতে।

Reserved concurrencyProvisioned concurrency

  • একটা function-এর জন্য আলাদা রাখা নির্দিষ্ট সংখ্যক concurrent execution: তার জন্য নিশ্চিত, আবার তার ছাদও।
  • Environment তবুও দরকারের সময় বানানো হয়: cold start হয়ই।
  • গোলমেলে প্রতিবেশী থেকে বাঁচায়; downstream বাঁচাতে function-কে বাঁধে; ০ = kill switch।
  • বসে function-এর ওপর (সব version মিলিয়ে)।
  • বিনা পয়সায়।
  • নির্দিষ্ট সংখ্যক আগে থেকে initialize করা environment, কোনো request আসার আগেই তৈরি।
  • ওই সংখ্যা পর্যন্ত request-এর cold start দূর করে; তার বেশি হলে on-demand-এ spillover।
  • সমাধান করে latency, না খেতে পাওয়ার সমস্যা না (যদিও pool-এর unit খরচ করে)।
  • বসে version বা alias-এ, $LATEST-এ না; Application Auto Scaling দিয়ে scheduled বা target-tracking scaling।
  • configure করা প্রতিটা সেকেন্ডের জন্য টাকা লাগে।

Provisioned concurrency: প্রথম request-এর আগেই গরম

একটা Pathao-ধাঁচের ride app-এর ভাড়ার হিসাব দেওয়া API-কে ১০০ ms-এর মধ্যে উত্তর দিতেই হবে। Provisioned concurrency একটা published version বা alias-এ নির্দিষ্ট সংখ্যক environment আগে থেকেই initialize করে রাখে; Application Auto Scaling সেই সংখ্যাটা schedule ধরে বা ব্যবহার দেখে বদলাতে পারে।

পরিস্থিতি

Traffic আসার আগেই init চলে যায়, তাই কোনো request-কে তার জন্য অপেক্ষা করতে হয় না।

Rider
API Gatewayalias live
App Auto Scaling
CloudWatchutilization
warm env 1provisionedতৈরি
warm env 2provisionedতৈরি
ধাপ 1 / 3
1

Team version ৭ publish করল, alias live-কে সেদিকে দেখাল, আর alias-এ provisioned concurrency ২ দিল। এটা কাজ করে শুধু version বা alias-এ, unpublished version-এ কখনো না। এক-দুই মিনিটের মধ্যে Lambda দুটো environment বানিয়ে তাদের init code চালিয়ে রাখল।

#SnapStart

SnapStart সমস্যাটার অন্য দিকটা ধরে: environment গরম রাখার বদলে নতুন একটা চালু করাটাকেই দ্রুত করে। SnapStart চালু রেখে তুমি version publish করলে Lambda Init একবার চালায়, initialize হওয়া memory আর disk-এর একটা Firecracker snapshot নেয়, encrypt করে, আর কয়েকটা কপি cache করে রাখে। ওই version-এর নতুন environment আবার Init না চালিয়ে snapshot থেকে restore হয়, প্রায়ই কয়েক সেকেন্ডের বদলে এক সেকেন্ডেরও অনেক কম সময়ে।

  • Runtime: Java 11 আর তার পরের, Python 3.12 আর তার পরের, .NET 8 আর তার পরের (managed runtime আর তাদের base image)। Node.js, Ruby বা OS-only runtime না।
  • দাম: Java-র জন্য বাড়তি কিছু না। Python আর .NET-এ টাকা দিতে হয় snapshot cache রাখার জন্য (প্রতি GB-second, কমপক্ষে ৩ ঘণ্টা, version যতদিন active থাকে) আর প্রতিটা restore-এর জন্য। Slide বলে “Java, Python আর .NET-এ বাড়তি খরচ ছাড়া”; আসলে বিনা পয়সায় শুধু Java।
  • শুধু published version-এ (আর সেদিকে দেখানো alias-এ), $LATEST-এ না।
  • provisioned concurrency, EFS, বা ৫১২ MB-র বড় /tmp-এর সাথে চলে না।

দুটো সাবধানতা পরীক্ষার প্রশ্নেও আসে, বাস্তবের outage-এও:

  • Uniqueness। Init-এর সময় যা বানানো হয়, সব কপি হয়ে যায় প্রতিটা restore হওয়া environment-এ। Init-এ বানানো একটা random seed, একটা unique ID বা একটা secret সব কপিতে একই হবে। এগুলো বানাও restore-এর পরে: handler-এ, বা একটা after-restore runtime hook-এ (Java-তে afterRestore hook, Python-এ @register_after_restore)।
  • Network connection। Init-এর সময়, মানে publish-এর সময় খোলা connection কয়েক ঘণ্টা পরে snapshot restore হওয়ার সময় হয়তো অনেক আগেই মরে গেছে; Lambda তার অবস্থার নিশ্চয়তা দেয় না। Restore-এর পরে connection যাচাই করে আবার খোলো। AWS SDK-র বানানো connection সাধারণত নিজে থেকেই সেরে ওঠে। Init-এ আনা অস্থায়ী credential আর cache করা সময়ও নতুন করে নেওয়া উচিত।

SnapStart: init একবার, restore বহুবার

একটা Java (Spring Boot) payment-status function initialize হতে ৬ সেকেন্ড নেয়। SnapStart থাকলে তুমি version publish করার সময়ই Lambda init চালায়, initialize হওয়া memory আর disk-এর একটা snapshot রেখে দেয়, আর নতুন environment সেখান থেকেই আবার চালু করে।

পরিস্থিতি

ধীর init হয় publish-এর সময়, কোনো customer-এর request-এর সময় না।

Developer
Lambda service
Snapshot cache
execution env
Customer
publish-version
ধাপ 1 / 3
1

Published version-এর জন্য SnapStart চালু (Java 11+, Python 3.12+, .NET 8+)। Developer version ১২ publish করল।

#Cold start-এর কোন সমাধান কখন

পরিস্থিতিসবচেয়ে মানানসইকেন
ধীর Init-ওয়ালা Java, Python বা .NET function, হঠাৎ হঠাৎ trafficSnapStartপ্রতিটা নতুন environment দ্রুত চালু হয়, সারাক্ষণের কোনো খরচ নেই (Java-তে বিনা পয়সায়)
প্রতিটা request-এ কড়া latency, আগে থেকে জানা peak, যেকোনো runtimescheduled scaling সহ provisioned concurrencyProvisioned environment-এ Init-ই নেই
ধীরে চালু হওয়া Node.js functionProvisioned concurrency (SnapStart Node.js সমর্থন করে না), সাথে ছোট package
Background বা asynchronous কাজসাধারণত কিছুই নাকয়েকশো millisecond বাড়তির জন্য কেউ অপেক্ষায় বসে নেই
Handler-এর ভেতরের ভারী code-এর জন্য cold startSetup handler-এর বাইরে সরাওপ্রতি environment-এ একবার চলে

#কোথায় গোলমাল হয়

লক্ষণসম্ভাব্য কারণসমাধান
Campaign-এর সময় API 429 / 5xx দেয়, অথচ বাকি function অলস দেখায়আরেকটা function account-এর pool নিয়ে নিয়েছেজরুরি function-এ reserved concurrency; quota বাড়াও
Account-এ concurrency খালি থাকলেও function throttle হচ্ছেতার নিজের reserved concurrency-ই ছাদReservation বাড়াও বা সরাও
হঠাৎ spike-এর একদম শুরুতে throttle, তারপর ঠিকScaling গতি (প্রতি ১০ সেকেন্ডে ১,০০০) বা cold startজানা spike-এর আগে provisioned concurrency; SQS দিয়ে buffer
খুব দ্রুত function-এ কম concurrency-তেই throttleপ্রতি unit concurrency-তে প্রতি সেকেন্ডে ১০ requestConcurrency বাড়াও (reserved বা quota)
Asynchronous event উধাওOn-failure destination বা DLQ নেই; event maximum event age পার করেছেDestination দাও; DeadLetterErrors / AsyncEventsDropped-এ alarm
Code ঠিক থাকলেও SQS message DLQ-তে যাচ্ছেThrottle-এর কারণে receive খরচ হয়েছে; visibility timeout ছোটESM maximum concurrency; visibility timeout ≥ ৬ × function timeout; বেশি maxReceiveCount
“Task timed out after 900.00 seconds”কাজ ১৫ মিনিটের বেশিStep Functions, নয়তো Fargate
RequestEntityTooLargeExceptionPayload ৬ MB (sync) বা ১ MB (async)-এর বেশিPresigned S3 upload; key পাঠাও
Traffic বাড়লে database connection ফিরিয়ে দেয়প্রতিটা কপি নিজের connection খোলেছাদ হিসেবে reserved concurrency; RDS Proxy (lesson 15.3)
Provisioned concurrency থাকা সত্ত্বেও cold startCaller $LATEST ডাকে; বা provisioned সংখ্যা ছাড়িয়ে spilloverTrigger-কে alias-এ দেখাও; provisioned বাড়াও বা target tracking
Traffic প্রায় নেই, অথচ provisioned concurrency-র billসারাদিন সারারাত configure করাScheduled scaling; রাতে minimum কম
SnapStart চালুর পর duplicate ID বা একই “random” সংখ্যাUniqueness বানানো হয়েছে Init-এRestore-এর পরে বানাও (handler বা after-restore hook)
SnapStart restore-এর পরে প্রথম query ব্যর্থInit-এ খোলা connection বাসিRestore-এর পরে আবার connect করো
CPU-ভারী function ১২৮ MB-তে ধীরCPU আসে memory-র সাথেMemory বাড়াও; প্রতি request-এর খরচ মাপো

#System design-এ Lambda concurrency

  • সূত্র দিয়ে মাপো, তারপর বাড়তি জায়গা রাখো। Peak request per second × p95 duration, সাথে ধীর downstream-এর জন্য জায়গা। Account quota-র সাথে মিলিয়ে দেখো, আর বাড়ানোর অনুরোধ করো launch-এর কয়েক সপ্তাহ আগে, সেদিন না।
  • জরুরি পথ আলাদা রাখো। Payment, login আর order নেওয়ার জন্য concurrency reserve করো; campaign আর batch job shared pool-এ থাকুক। কড়া বিভাজন চাইলে আলাদা account ব্যবহার করো (প্রতিটার নিজের quota, chapter 20)।
  • Lambda-র পেছনে যা আছে তাকে বাঁচাও। Lambda database আর third-party API-র চেয়ে দ্রুত বাড়ে। Reserved concurrency বা ESM maximum concurrency দিয়ে বাঁধো, burst শুষে নিতে সামনে SQS বসাও (lesson 13.1), আর relational database-এর জন্য RDS Proxy।
  • কেউ অপেক্ষায় না থাকলে asynchronous বেছে নাও। S3 বা SQS-চালিত function throttle সামলে নেয় (retry, buffer); synchronous API throttle-কে সোজা user-এর error বানিয়ে দেয়।
  • Latency-র বাজেট। User-এর সামনের আর হঠাৎ হঠাৎ traffic: peak-এর জন্য provisioned concurrency, বা Java/Python/.NET-এ SnapStart। Background: cold start মেনে নাও।
  • সদর দরজায় throttling। API Gateway-র নিজের throttling আছে (default-এ account-এ প্রতি সেকেন্ডে ১০,০০০ request, client প্রতি usage plan, lesson 15.6); সেখানে থামানো Lambda-কে দিয়ে 429 ছোড়ানোর চেয়ে সস্তা আর ভদ্র।

#নিজে করে দেখো

Concurrency reserve করো, ইচ্ছে করে একটা function throttle করো, তারপর একটা alias-এ provisioned concurrency দাও আর schedule ধরে scale করো। Output ছোট করা; fare-quote-example function আগে থেকেই আছে।

REGION=ap-southeast-1
FN=fare-quote-example

# 1. Account-এর quota আর কতটা unreserved আছে
aws lambda get-account-settings --region $REGION \
  --query '{limit:AccountLimit.ConcurrentExecutions,unreserved:AccountLimit.UnreservedConcurrentExecutions}'
# { "limit": 1000, "unreserved": 1000 }

# 2. Memory (আর তাই CPU), timeout আর /tmp-এর আকার
aws lambda update-function-configuration --function-name $FN \
  --memory-size 1769 --timeout 30 --ephemeral-storage '{"Size": 1024}'
# "MemorySize": 1769, "Timeout": 30, "EphemeralStorage": { "Size": 1024 }

# 3. এই function-এর জন্য 300 reserve: নিশ্চয়তা আর ছাদ
aws lambda put-function-concurrency --function-name $FN --reserved-concurrent-executions 300
# { "ReservedConcurrentExecutions": 300 }
aws lambda get-account-settings --query 'AccountLimit.UnreservedConcurrentExecutions'
# 700

# 4. Kill switch: 0 দিলে প্রতিটা নতুন invocation throttle
aws lambda put-function-concurrency --function-name $FN --reserved-concurrent-executions 0
aws lambda invoke --function-name $FN --payload '{}' --cli-binary-format raw-in-base64-out out.json
# An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 2): Rate Exceeded.
aws lambda delete-function-concurrency --function-name $FN   # আবার shared pool-এ

# 5. Asynchronous invocation: 202, retry আর failure destination সহ
aws lambda put-function-event-invoke-config --function-name $FN \
  --maximum-retry-attempts 1 --maximum-event-age-in-seconds 3600 \
  --destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:ap-southeast-1:111122223333:fare-failures-example"}}'
aws lambda invoke --function-name $FN --invocation-type Event --payload '{"from":"Gulshan"}' \
  --cli-binary-format raw-in-base64-out out.json
# { "StatusCode": 202 }

# 6. Version publish, alias live সেদিকে, 20টা warm environment provision
aws lambda publish-version --function-name $FN --query Version
# "7"
aws lambda create-alias --function-name $FN --name live --function-version 7
aws lambda put-provisioned-concurrency-config --function-name $FN --qualifier live \
  --provisioned-concurrent-executions 20
# { "RequestedProvisionedConcurrentExecutions": 20, "AllocatedProvisionedConcurrentExecutions": 0, "Status": "IN_PROGRESS" }
aws lambda get-provisioned-concurrency-config --function-name $FN --qualifier live --query Status
# "READY"   (এক-দুই মিনিট পরে)

# 7. Application Auto Scaling-কে দায়িত্ব দাও: কর্মদিবসের ভিড়ে 200, পরে আবার 20
aws application-autoscaling register-scalable-target --service-namespace lambda \
  --resource-id function:$FN:live --scalable-dimension lambda:function:ProvisionedConcurrency \
  --min-capacity 20 --max-capacity 300
aws application-autoscaling put-scheduled-action --service-namespace lambda \
  --resource-id function:$FN:live --scalable-dimension lambda:function:ProvisionedConcurrency \
  --scheduled-action-name morning-rush --schedule "cron(45 1 ? * SUN-THU *)" \
  --scalable-target-action MinCapacity=200,MaxCapacity=300
# (01:45 UTC = ঢাকায় 7:45; আরেকটা action 10:30-এ MinCapacity 20-এ নামায়)

# 8. অথবা utilization 70%-এ ধরে রাখো
aws application-autoscaling put-scaling-policy --service-namespace lambda \
  --resource-id function:$FN:live --scalable-dimension lambda:function:ProvisionedConcurrency \
  --policy-name pc-70 --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{"TargetValue":0.7,"PredefinedMetricSpecification":{"PredefinedMetricType":"LambdaProvisionedConcurrencyUtilization"}}'

# 9. Java বা Python function-এ SnapStart (এরপর publish করা version-এ লাগে)
aws lambda update-function-configuration --function-name payment-status-example \
  --snap-start ApplyOn=PublishedVersions
aws lambda publish-version --function-name payment-status-example \
  --query '{v:Version,snap:SnapStart.OptimizationStatus}'
# { "v": "12", "snap": "On" }

# 10. টাকার অংশটা মুছে ফেলো
aws lambda delete-provisioned-concurrency-config --function-name $FN --qualifier live

তারপর reserved concurrency ১ রেখে function-টাকে একটা loop-এ ডাকতে থাকো, আর CloudWatch-এ তার Throttles আর ConcurrentExecutions metric দেখো: দুটো invocation একসাথে পড়লেই throttle-এর সংখ্যা বাড়তে থাকে।

#সারসংক্ষেপ

মূল কথাগুলো

  • কড়া সীমা (প্রতি Region-এ): memory ১২৮ MB–১০,২৪০ MB, timeout ১৫ মিনিট, payload sync ৬ MB / async ১ MB (২০২৫-এর আগে ২৫৬ KB), package zip ৫০ MB / unzip ২৫০ MB (layer সহ), container image ১০ GB, /tmp ৫১২ MB–১০ GB, env var ৪ KB, ৫টা layer। পাশ কাটানোর উপায়: S3 + presigned URL, Step Functions বা Fargate, container image, /tmp বা EFS।
  • CPU আসে memory-র সাথে: ১,৭৬৯ MB-তে ১টা vCPU, ১০,২৪০ MB-তে ৬টা পর্যন্ত। বেশি memory একই দামে দ্রুত হতে পারে।
  • Concurrency = প্রতি সেকেন্ডে request × duration (সেকেন্ড)। Default quota প্রতি account-এ প্রতি Region-এ ১,০০০, সব function মিলে ভাগ, বাড়ানো যায়। সাথে: প্রতি unit-এ প্রতি সেকেন্ডে ১০ request, আর scaling প্রতি function-এ প্রতি ১০ সেকেন্ডে ১,০০০ environment।
  • Throttling: synchronous → 429, client retry করে; asynchronous → Lambda ৬ ঘণ্টা পর্যন্ত retry করে (১ সেকেন্ড থেকে ৫ মিনিট backoff), তারপর on-failure destination / DLQ, নয়তো ফেলে দেয়; function error পায় ২টা retry; SQS → message queue-তেই থাকে, DLQ queue-এর ওপর; একটা queue-কে বাঁধতে ESM maximum concurrency।
  • Reserved concurrency: বিনা পয়সায়; একটা function-এর নিশ্চয়তা আর ছাদ; গোলমেলে প্রতিবেশী থেকে বাঁচায়, database-এর চাপ বাঁধে, ০ = kill switch; ১০০ unit সবসময় unreserved থাকে।
  • Cold start: প্রতিটা environment-এর প্রথম request-এর আগে Init (নতুন environment + handler-এর বাইরের code, সর্বোচ্চ ১০ সেকেন্ড, আগস্ট ২০২৫ থেকে bill হয়)। Setup handler-এর বাইরে রাখো, package ছাঁটো, memory বাড়াও।
  • Provisioned concurrency: version বা alias-এ আগে থেকে initialize করা environment; ওই সংখ্যা পর্যন্ত cold start নেই, বেশি হলে spillover; configure থাকলেই টাকা; Application Auto Scaling (scheduled, target tracking); ≤ reserved concurrency।
  • SnapStart: publish-এর সময় Init-এর পরে snapshot, init-এর বদলে restore; Java 11+, Python 3.12+, .NET 8+; বিনা পয়সায় শুধু Java; provisioned concurrency, EFS বা ৫১২ MB-র বড় /tmp-এর সাথে না; restore-এর পরে unique value নতুন করে বানাও আর আবার connect করো।