Developers’ nightmare 10 years ago and now can’t be the same. Ten years back, we had challenges on how to handle scalability, latency, cost, resource usage and downtime. Existence of challenge creates innovation and who says innovation says “SMART”.
What if I told you, you can get your app fully serverless? Sounds like a dream? Think about cloud, think about server(less/no). Somewhere below I will get you to do some comparison on this.
Without further ado, let’s get to compare these environments based on cost, architecture, ease to get started, availability and scalability. (Feel free to drop comments on your thoughts, I will love to read and learn more).
Note: Through out this blog we will use the most affordable solution and keep our wallets secure (no billing on us… we use our free tier)
Architecture
Let’s see and understand how both of these methods impacts the developers life and daily routine.
Server Deployment
Just like we see above, we have a low cost deployment for a Django Application with all functionalities present. Most of the questions in your head are soon going to be answered.
- What is this, that, this too, what about that… what is used for?
- How scalable and how reliable is this setup?
Well… Let’s go >>>
- Nginx + Certbot: Proxy, routing and SSL for our app
- Gunicorn: Do you remember the Warning Django keeps bringing when you run your app locally and it says: this is a development server try not to use this is prod? Yes, Gunicorn is our Prod server. It does a lot Read More….
- Postgres: Coming from AWS RDS. It is an AWS Managed Postgres “server”.
- Amazon EC2: This is available on AWS Compute services
Talking about Scalability, well, I will get back to that.
Serverless Deployment
{% block LittlePause %}
Wait a minute, why did AWS create serverless services and are so invested into it.
Think about you(Ze developer) not caring that much about your cloud environment. Focusing on your code, and your code.
{% endblock LittlePause %}
On the architectural diagram we have a few components, let’s talk about what does what.
- API Gateway: Serving as an entry point to our app
- Lambda: where our code runs without provisioning or managing servers. It automatically scales based on the number of incoming requests and charges only for the compute time consumed.
- Lambda Function: represents your entire Django application wrapped in a serverless environment.
- Amazon Aurora: Our serverless postgres compatible database.
Pricing / Cost / Billing
Category | Server-Based (EC2 + Nginx) | Serverless (Lambda + API Gateway + Zappa) |
---|---|---|
Pricing Model | Fixed monthly cost based on instance type. | Pay-as-you-go, charged per request and compute time. |
Compute Costs | Fixed pricing for instance type . | 1M requests free per month, then $0.20 per 1M requests. |
Free Tier Availability | EC2 t3.micro free for 12 months (750 hours/month). | 1M Lambda requests + 400,000 GB-seconds free/month. |
Traffic Handling | Manual scaling required for high traffic. | Auto-scales automatically with traffic. |
Uptime Management | Runs 24/7, charges apply even when idle. | Only charges during request handling (event-driven). |
API Gateway Costs | Not required. | Free Tier: 1M requests/month, then $3.50 per million. |
Data Transfer (to Internet) | Free for up to 100GB per month in Free Tier. | Free for up to 100GB per month in Free Tier. |
Storage Costs (RDS) | Free Tier: 750 hours db.t3.micro for 12 months. | Same Free Tier for RDS as server setup. |
Storage for Static Files (S3) | Free Tier: 5GB standard storage for 12 months. | Free Tier: 5GB storage + 20,000 GET + 2,000 PUT requests. |
SSL/TLS Certificates | Free via ACM or Let’s Encrypt. | Free via ACM (Amazon Certificate Manager). |
Cold Start Delays | Not applicable (server always running). | Cold starts possible after inactivity. |
Maintenance | Manual OS patching, scaling, and monitoring. | Fully managed, no server maintenance required. |
Best for | Steady traffic and continuous workloads. | Variable traffic and unpredictable workloads. |
Cost Estimation (After Free Tier) | ~$50-$70/month (EC2 + RDS + S3 + Transfer). | ~$5-$30/month (depends on request volume). |
Scalability
You had scalability in your head since from the diagram above, get satisfied.
Category | Server-Based (EC2 + Nginx) | Serverless (Lambda + API Gateway + Zappa) |
---|---|---|
Scalability Type | Vertical Scaling (Scaling Up) by increasing instance size or Horizontal Scaling by adding more instances (manually or via Auto Scaling Groups). | Horizontal Scaling (Scaling Out) by adding more Lambda function instances automatically. |
Automatic Scaling | Requires Manual Configuration (Auto Scaling Groups). | Automatic and Fully Managed Scaling by AWS based on incoming traffic. |
Performance During Scale | Dependent on instance size and type (CPU, RAM). Needs larger instances for increased load. | Lambda creates more instances as traffic spikes, handling thousands of requests simultaneously. |
Scaling Speed | Slower due to instance launch times and warm-up. | Instant Scaling as Lambda spins up new containers rapidly. |
Cold Starts | Not applicable (server always running). | Yes, cold starts occur after a period of inactivity but can be reduced with provisioned concurrency. |
Concurrency Limits | Limited by Instance Type Capacity. Manual intervention needed for multiple servers. | Scales Concurrently and Infinitely (Default 1,000 concurrent executions, adjustable). |
High Traffic Handling | Needs proactive scaling adjustments or larger instances for sudden traffic spikes. | Handles sudden traffic spikes seamlessly by auto-scaling. |
Resource Management | Fixed resources per instance, even during low traffic periods. | Dynamically allocates resources based on traffic. |
Global Scalability | Needs manual deployment in multiple regions. | Lambda supports multi-region replication for global scaling with minimal configuration. |
Maintenance During Scaling | Needs manual load balancing setup (ELB, ALB). | No infrastructure to manage, auto-scales seamlessly. |
Best For | Predictable and steady workloads with constant traffic. | Unpredictable traffic, event-driven workloads, and bursty traffic. |
Automation
Both of these setups can have setups easy to automate via GitHub CI/CD.
Serverless
name: Deploy Zappa to AWS
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy with Zappa
runs-on: ubuntu-latest
environment: production
steps:
# Step 1: Check out code
- name: Checkout Code
uses: actions/checkout@v4
# Step 2: Set up Python version
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.12
# Step 3: Install Dependencies
- name: Install Dependencies
run: |
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pip install zappa
# Step 4: Create AWS Profile (Explicit Configuration)
- name: Create AWS Profile
run: |
mkdir -p ~/.aws
echo "[default]" > ~/.aws/credentials
echo "aws_access_key_id=${{ secrets.AWS_ACCESS_KEY_ID }}" >> ~/.aws/credentials
echo "aws_secret_access_key=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> ~/.aws/credentials
echo "[default]" > ~/.aws/config
echo "region = ${{ secrets.AWS_REGION }}" >> ~/.aws/config
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
# Step 5: Validate AWS Credentials and Profile
- name: Validate AWS Configuration
run: |
aws configure list
aws sts get-caller-identity
# Step 6: Deploy/Update Zappa
- name: Deploy to AWS Lambda with Zappa
run: |
source .venv/bin/activate
zappa deploy ${{ secrets.ZAPPA_ENV }} || zappa update ${{ secrets.ZAPPA_ENV }}
Server
name: Deploy Django and Celery to EC2 instance
on:
push:
branches:
- main
jobs:
deploy_project:
name: Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.7
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44.5.7
with:
since_last_remote_commit: true
separator: ","
- name: Copy files via scp using SSH key
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.DEPLOY_KEY }}
port: ${{ secrets.PORT }}
source: "."
target: ${{ github.event.repository.name }}
build_project:
name: Build
needs: deploy_project
runs-on: ubuntu-latest
steps:
- name: Executing remote SSH commands using SSH key
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.DEPLOY_KEY }}
port: ${{ secrets.PORT }}
script: |
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart all
Tutorial
Subscribe and check the video you need On My YouTube Channel and My GitHub for the source code and sample tutorial.
Conclusion
Make the choice which is best for you and drop your thoughts in the comment section.
Source link
lol