DEV Community

Cover image for Serverless or Server for Django Apps?
Steve Yonkeu
Steve Yonkeu

Posted on

Serverless or Server for Django Apps?

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

Django Server Deploment
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 >>>
  1. Nginx + Certbot: Proxy, routing and SSL for our app
  2. 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....
  3. Postgres: Coming from AWS RDS. It is an AWS Managed Postgres "server".
  4. Amazon EC2: This is available on AWS Compute services

Talking about Scalability, well, I will get back to that.

Serverless Deployment

Django Serverless Deployment

{% block LittlePause %}

Wait a minute, why did AWS create serverless services and are so invested into it.

SERVERLESS IS THE FUTURE!!!
Man Screaming meme

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.

  1. API Gateway: Serving as an entry point to our app
  2. 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.
  3. Lambda Function: represents your entire Django application wrapped in a serverless environment.
  4. 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 }} 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)