Serverless Functions & Edge Computing: The Rails Developer's Guide

A comprehensive guide for Rails developers to understand serverless functions, when to use them vs Rails, and how edge computing changes the game. Covers the mental model shift from monolith to functions, a decision framework for choosing the right tool, the hybrid Rails + serverless pattern, and the physics of why edge computing matters — all grounded in the learner's own Mac Mini setup project and Rails experience.

serverless edge computing Cloudflare Workers Cloudflare Pages KV D1 R2 AWS Lambda Rails vs serverless hybrid architecture static sites CDN latency ai-home-base by nityeshagarwal

You just deployed a static HTML page and it went live in seconds. No server, no Puma, no database.yml. What just happened — and what does it mean for everything you know about building web apps?

Part 1: What Serverless Functions Actually Are

A guide for Rails developers who've been living inside rails server and want to understand what's on the other side.

The world you know

You know what it takes to run a Rails app. You've done it. Curated Connections didn't just appear — you set up a Puma server, configured a database, wrote migrations, wired up routes, built controllers, added background jobs. You deployed it to a server that's running right now, whether anyone is using it or not.

Let's sit with that for a second, because it's the seed of everything serverless is trying to solve.

Picture your Rails app on Heroku. It's 3 AM. Nobody is visiting your site. But your dyno is up. Puma has its worker processes sitting there, connected to Postgres, waiting. Your Redis instance for Sidekiq is idling. The SSL cert is loaded. The middleware stack is warmed up. Everything is ready.

And it's costing you money to be ready.

For Curated Connections — a real product with real users — that makes total sense. You want a warm, ready application. The overhead is justified by the complexity of what you're doing: user sessions, database queries, background jobs, Turbo Streams, the whole orchestra playing together.

But now imagine a different scenario.

The moment serverless starts to make sense

Say a client asks you to build a webhook handler. Stripe sends a POST request when a payment completes. All you need to do is:

  1. Receive the POST
  2. Verify the signature
  3. Write a row to a database
  4. Return a 200

That's it. One endpoint. One action. Maybe 40 lines of Ruby.

In Rails, here's what you'd do:

  • rails new stripe-webhook (wait 30 seconds while it generates 80+ files)
  • Create a route: post '/webhooks/stripe', to: 'webhooks#stripe'
  • Create WebhooksController with one action
  • Skip CSRF for that endpoint
  • Deploy the whole Rails app to Heroku
  • Pay $7/month minimum for a dyno
  • Set up a Postgres addon (even if you barely use it)
  • Configure SSL
  • Monitor it, keep it updated, patch security vulnerabilities in gems

You just built a building to house a single desk.

This is the problem. Not that Rails is bad — Rails is extraordinary for what it does. The problem is that some tasks don't need an application. They need a function.

And that's exactly what someone eventually said:

"What if you could deploy just the function? What if you didn't need the building at all?"

What a serverless function actually is

Strip away the marketing. Strip away "the cloud" and "edge computing" and "Web3-adjacent infrastructure." Here's what a serverless function is:

You write a function that takes a request and returns a response. You deploy that function. The platform runs it when someone calls it.

That's it. That's the whole thing.

Here's a Cloudflare Worker (the kind you'd put alongside your static HTML page on Cloudflare Pages):

export default {
  async fetch(request) {
    return new Response("Hello world");
  }
};

This is a complete, deployable application. When someone hits the URL, Cloudflare spins up this function, runs it, returns "Hello world", and the function goes away. You don't have a server. You don't have a process sitting idle. You have a function that exists only in the moment it's needed.

Now here's your Stripe webhook handler — the one that took a whole Rails app before:

export default {
  async fetch(request) {
    if (request.method !== "POST") {
      return new Response("Method not allowed", { status: 405 });
    }

    const body = await request.text();
    const signature = request.headers.get("stripe-signature");

    const isValid = await verifyStripeSignature(body, signature);
    if (!isValid) {
      return new Response("Invalid signature", { status: 401 });
    }

    const event = JSON.parse(body);

    if (event.type === "payment_intent.succeeded") {
      await recordPayment(event.data.object);
    }

    return new Response("OK", { status: 200 });
  }
};

No framework. No router. No middleware stack. No ORM. Just a function that takes a request and returns a response.

You deploy this to Cloudflare. It gets a URL. Stripe sends webhooks to that URL. Each request spins up the function, runs it, done. If you get 10 webhooks a day, the function runs 10 times. If you get 10,000 in an hour, Cloudflare spins up as many instances as needed. You don't configure any of this.

And when there are zero requests? Zero cost. The function doesn't exist between calls. It's like a light that only turns on when you flip the switch — there's no bulb burning in an empty room.

Mapping it to Rails — the Rosetta Stone

Every serverless concept maps to something you already understand. The difference is in scope.

Rails Concept Serverless Equivalent Key Difference
A controller action A serverless function The function is deployed alone, not inside an app
routes.rb Platform routing (file-based or config) Cloudflare uses file paths: /functions/api/hello.js becomes /api/hello
ApplicationController + before_action chain Nothing (you rebuild what you need) No inherited auth, no logging, no CSRF — you add each thing explicitly
Middleware stack (Rack) Nothing (or platform-specific) No cookie parsing, no session handling, no parameter wrapping by default
ActiveRecord + connection pool Per-request database connections No warm pool sitting ready. You connect, query, disconnect. Or use edge databases.
rails console Nothing. There is no server to SSH into. This is the one that stings. You can't poke around in production.
rails server (Puma) The platform itself You never run a server. The platform is the server.
Environment variables Platform secrets / environment config Similar concept, different tooling

The most important row is the first one. A serverless function is literally a single controller action, ripped out of your Rails app and deployed on its own.

Two request lifecycles, side by side

                RAILS REQUEST                          SERVERLESS REQUEST
                ─────────────                          ──────────────────

          ┌──────────────────┐                    ┌──────────────────┐
          │  Request arrives  │                    │  Request arrives  │
          └────────┬─────────┘                    └────────┬─────────┘
                   │                                       │
                   ▼                                       │
          ┌──────────────────┐                             │
          │   Nginx / Load   │                             │
          │    Balancer       │                             │
          └────────┬─────────┘                             │
                   │                                       │
                   ▼                                       ▼
          ┌──────────────────┐                    ┌──────────────────┐
          │   Puma (already   │                    │  Platform spins   │
          │   running, warm)  │                    │  up your function │
          └────────┬─────────┘                    └────────┬─────────┘
                   │                                       │
                   ▼                                       │
          ┌──────────────────┐                             │
          │  Rack Middleware  │                             │
          │  (cookies, CSRF, │                             │
          │  sessions, params)│                             │
          └────────┬─────────┘                             │
                   │                                       │
                   ▼                                       │
          ┌──────────────────┐                             │
          │    Router         │                             │
          └────────┬─────────┘                             │
                   │                                       │
                   ▼                                       ▼
          ┌──────────────────┐                    ┌──────────────────┐
          │ ApplicationCtrl   │                    │                  │
          │  before_actions   │                    │   YOUR FUNCTION  │
          └────────┬─────────┘                    │   (that's it)    │
                   │                               └────────┬─────────┘
                   ▼                                       │
          ┌──────────────────┐                             │
          │  YOUR ACTION      │                             │
          └────────┬─────────┘                             │
                   │                                       │
                   ▼                                       ▼
          ┌──────────────────┐                    ┌──────────────────┐
          │ Response travels   │                    │ Response returned │
          │ back through all  │                    │ directly          │
          │ middleware layers  │                    │                  │
          └────────┬─────────┘                    └────────┬─────────┘
                   │                                       │
                   ▼                                       ▼
          ┌──────────────────┐                    ┌──────────────────┐
          │ Server stays warm │                    │  Function dies.   │
          │ waiting for next  │                    │  Gone. Nothing    │
          │ request           │                    │  is running.      │
          └──────────────────┘                    └──────────────────┘

Look at the left side. Count the boxes. That's not waste — each layer adds something valuable. But every layer is something you had to set up, configure, deploy, and keep running.

Now look at the right side. The request arrives. Your function runs. The response goes back. Done.

The mental model shift

In Rails, you think in terms of an application. Models, views, controllers, routes, concerns, jobs — all wired together into a coherent system. When you add a feature, you think about where it fits in the existing architecture. Everything knows about everything else. Your User model can be referenced from any controller, any job, any mailer. It's an organism.

In serverless, you think in terms of individual functions that respond to events. Each function is independent. It doesn't know about the other functions. It doesn't share a database connection pool. It doesn't share middleware. It doesn't share anything.

The analogy:

Rails is an orchestra. There's a conductor (the framework). There are sections (models, views, controllers). Every musician has a defined seat and knows the score. When the music plays, it's rich because everything is coordinated. But you need a concert hall (server), and the whole ensemble has to show up even if you only need the oboe for one note.

Serverless is a collection of soloists. Each one shows up only when called, plays their part, and leaves. No concert hall needed. But if you need them to play together? You have to choreograph that yourself. There's no conductor.

This is why serverless is perfect for some things and painful for others. A webhook handler? Perfect soloist. A full SaaS app? That's an orchestra piece. You want Rails for that.

Part 2: Rails vs Serverless — When Each Wins

"Wait — do I even need Rails for everything I've been using it for?"

The answer is: yes, you absolutely do. But also: no, not always.

Where Rails Absolutely Crushes Serverless

Could you have built Curated Connections with serverless? Technically, yes. Should you have? Absolutely not.

Picture your Rails app as a restaurant with a full kitchen. You've got a head chef (the framework), a prep station (ActiveRecord), a dishwasher (background jobs), a front-of-house team (ActionView / Turbo), and a manager (the router). Everything is under one roof, everyone knows the system.

Now picture building the same restaurant with serverless. Every dish is prepared by a different freelance chef in a different kitchen across the city. The appetizer chef doesn't know what the entree chef is making. Nobody shares a pantry. When table 7 has a complaint, you have to figure out which of the 15 independent kitchens messed up.

Complex business logic with model relationships. In Rails, you write has_many :subscriptions and you're done. ActiveRecord gives you eager loading, scoping, validations, callbacks — all following conventions you know. In serverless, every function is isolated. You end up recreating ActiveRecord yourself, poorly, across dozens of functions.

Stateful applications. Rails sessions, cookies, CSRF protection — all built in. Serverless functions are stateless by design. Every request starts from zero. Need to remember that a user is logged in? That's your problem now.

Admin dashboards. Drop in administrate or rails_admin and you have a full admin panel with search, filters, and CRUD for every model. Try that with serverless — you'd build an entire frontend application from scratch.

Debugging production. When something breaks, you fire up rails console and poke around. You query the database, inspect objects, test methods. In serverless? You read CloudWatch logs and guess. There is no console.

Convention-over-configuration magic. Rails lets you build a complete application in a weekend because everything is decided for you. With serverless, you'd spend the weekend deciding how to organize your functions, which database to use, and how to share code between them.

DHH's famous position is right for most applications: one monolith that does everything, scaled vertically, deployed with Kamal.

Where Serverless Crushes Rails

Not everything is a restaurant. Sometimes you just need a vending machine.

1. The Webhook Handler

Stripe sends webhook events maybe 50 times a day. Each execution takes 200ms. With Rails, you run a $7+/month server 24/7, mostly idle. With serverless, the function spins up only when Stripe calls it. At Cloudflare pricing, that's essentially free.

2. The Image Resizer

Users upload photos, you need thumbnails. With Rails, you install ImageMagick, manage disk space, hope your server has enough memory. With serverless, a function triggers on upload, resizes, stores results, vanishes. Scales to zero or a thousand.

3. The Lightweight Data API

A marketing site needs to display "23,847 users served." The data changes hourly. A serverless function reads from a cache, returns JSON, done. No ORM, no middleware. You need a vending machine, not a restaurant.

4. Static Sites That Need a Tiny Bit of Backend

This is directly what you're dealing with right now. Your setup guide is static HTML on Cloudflare Pages. What if you want a shared checklist? You don't migrate to Rails. You add one Pages Function that handles that one interaction.

5. Edge Functions

You're in India. Cloudflare has datacenters in Mumbai, Chennai, Delhi. When your function runs at the edge, response time drops from 300ms to 20ms. That's not an optimization — it's a different user experience.

The Hybrid Pattern: Rails + Serverless

Here's what experienced teams actually do: it's not either/or.

  • Rails handles the core product. Database, business logic, admin panel, authentication.
  • Serverless handles the edges. Webhook processing, image optimization, edge caching, lightweight APIs.

For Curated Connections, this could be:
- Rails app on Render — your main product
- Cloudflare Worker for edge caching — serves public pages from the nearest datacenter
- Cloudflare Worker for webhook handling — receives Stripe events
- Pages Function on your guide — adds dynamic features without touching Rails

Each tool does what it's best at.

The Decision Framework

+----------------------------------------------------------+------------------+
| Question                                                 | Reach for...     |
+----------------------------------------------------------+------------------+
| Does it need a database with complex queries?            | Rails            |
| Does it have multiple models with relationships?         | Rails            |
| Does it need admin interfaces or CRUD dashboards?        | Rails            |
| Will you need rails console to debug production?         | Rails            |
| Is it a single endpoint that responds to events?         | Serverless       |
| Does it need to run close to users globally?             | Serverless (edge)|
| Is it a static site that needs 1-2 dynamic features?    | Static + Fn      |
| Does it process files or media on demand?                | Serverless       |
| Is it a full product with auth, billing, and workflows?  | Rails            |
| Does it run infrequently (a few times per day)?          | Serverless       |
| Does it need persistent WebSocket connections?           | Rails            |
+----------------------------------------------------------+------------------+

The Rails Ecosystem Already Has Serverless Ideas Built In

Rails has been solving the same problems, just with different tools:

  • Background jobs (Solid Queue, Sidekiq) = serverless for async work. "Run this code later, not inside the web request."
  • Action Mailbox = serverless for email processing. Inbound emails arrive, Rails routes them to the right mailbox class.
  • Turbo Streams = serverless for real-time. But Rails does it with WebSockets from your single server.
  • Kamal/Docker = serverless scaling (sort of). You manage servers, but deployment feels closer to "push and forget."

The Rails philosophy: keep it all in one place. One repo, one deployment, one mental model. For most applications, that wins. But when you need something at the edge, or something that runs twice a day — that's when you reach for serverless. Not to replace Rails. To handle what Rails was never designed to handle.

Part 3: Edge Computing — Why Location Matters

The Speed of Light Is Slower Than You Think

Here's a physics problem you probably haven't thought about since JEE prep.

Light travels at 299,792 km/s in a vacuum. But your HTTP requests travel through fiber optic cable, where light moves at roughly two-thirds that speed due to the refractive index of glass. So: ~200,000 km/s.

Mumbai to New York through undersea fiber? Roughly 13,000 km.

13,000 km / 200,000 km/s = 0.065 seconds = 65ms one way

That's 65 milliseconds for a photon. Your request goes and comes back: 130ms minimum. Add routing switches, network boundaries, load balancers, and you're at ~250ms. Which is exactly what you experience with your Mac Mini every day.

Here's what makes this different from every other performance problem: you cannot optimize this away. You can't buy a faster server. You can't optimize queries. You can't add caching. The speed of light through glass fiber is a physical constant.

In Rails, when something is slow, you profile it. Find the N+1 query, add an index, move work to a background job. But 130ms of physics? That's not a code problem. That's a geometry problem.

And the only way to solve a geometry problem is to change the geometry.

What "The Edge" Actually Means

Traditional deployment: your code runs in one datacenter. Every user on earth sends requests to that one spot.

"The edge" flips this. Instead of one datacenter, your code runs in 300+ datacenters worldwide. When a user makes a request, it's handled by the nearest node.

Traditional (your Mac Mini):

  You (Mumbai)
    |
    |  ~65ms through undersea fiber, routing hops...
    |                                              |
    |                                              v
    |                                       +--------------+
    |                                       |  NYC Server  |
    |  ~65ms back                           |  (processes)  |
    |  <------------------------------------+              |
    v                                       +--------------+
  Total: ~250ms


Edge (Cloudflare Workers):

  You (Mumbai)
    |
    |  ~5ms
    |        v
    |  +--------------+
    |  | Mumbai Edge  |
    |  |  (processes)  |
    |  +--------------+
    |        |
    v  ~5ms  v
  Total: ~20ms

That's not a 2x improvement. That's 12x. And it's not because the edge server is faster — it's because it's closer. The code is identical. The physics changed.

When you deployed your guide to Cloudflare Pages, this already happened. Your HTML went to all 300+ edge locations. Someone in Bangalore loads it from India, not New York.

What Can Actually Run at the Edge

Edge functions are not servers. Think of them as middleware that runs everywhere.

What you cannot do:
- No persistent connections (no WebSockets, no database connection pools)
- Limited execution time (10-50ms CPU)
- Limited memory (~128MB)
- No filesystem access
- Small code bundles (1-10MB)

These constraints are what make 300-location deployment possible. You can't replicate PostgreSQL to 300 datacenters. You can replicate a 1MB function.

What works brilliantly:
- Authentication checks — JWT validation, API key lookup
- Redirects and URL rewrites — programmable nginx
- Cached responses — serve without touching the origin
- A/B testing — route users to variants at the edge
- Geolocation — show prices in rupees, content in local language
- Small data reads/writes — your shared checklist idea

The mental model: edge functions are for decisions and transformations, not for heavy computation or complex state.

Cloudflare's Edge Stack, Explained Simply

Platform Piece What It Is Rails Analogy
Workers Edge functions — your code at 300+ locations A single controller action, but runs in the nearest datacenter
KV Global key-value store Redis, but replicated everywhere. Eventually consistent.
D1 SQLite database at the edge Your Rails dev SQLite, but managed and globally accessible
R2 Object storage S3, but with zero egress fees
Pages Static hosting + Functions Like deploying public/ but with controller actions attached

When you deployed your guide to Pages, your HTML went everywhere. Add a functions/api/checklist.js file and that function also deploys everywhere. Mumbai user hits your API — runs in Mumbai. London user — runs in London.

How This Connects to Your Mac Mini

Let's be honest about where edge helps and where it doesn't.

Your Slack bot architecture:

You (India) -> Slack (USA) -> Mac Mini (NYC) -> Claude Code -> Mac Mini -> Slack -> You

Edge computing doesn't help here. Claude Code needs filesystem access, persistent processes, local environment. It violates every edge constraint.

But for web-based tools? Your setup guide is already at the edge. A status dashboard could run at the edge and poll your Mac Mini periodically, caching in KV. A prompt management tool runs its interface at the edge, reaching back to the Mac Mini only when needed.

The pattern: put the interface at the edge, put the heavy computation wherever it needs to be.

Your Turn: Think It Through

Look at your Mac Mini setup guide. Imagine adding three features:

(a) A shared checklist — visitors check off steps, everyone sees the same state.

(b) A "Mac Mini status" indicator — shows if your Mac Mini is online.

(c) A log of recent Slack bot interactions — last 10 things the bot did.

For each one, ask:
- Can this run entirely at the edge?
- Does it need to talk to your Mac Mini?
- What Cloudflare primitives would you use?
- Where does the data live?

Reason through the constraints. Which features are about reading small data that changes slowly (perfect for edge KV)? Which require real-time state from a specific machine (can't avoid the round trip)? Which need ordered, queryable data (maybe D1)?

This is the skill: looking at a feature and knowing, from the physics and the constraints, where it should run.

Questions & Answers

Q&A

Questions from the learner will be added here as they come up.