Skip to content

All lessons

Area 07 // DeploymentLesson 115 / 14014 min read

Serverless functions and the easy hosting route

Serverless functions run your code only when a request arrives and bill per use, while managed platforms (container hosts, Hugging Face Spaces and similar) run your app from a repo or image with little setup, which makes them the fastest way to ship most AI apps that call model APIs.

Think of it like this

Analogy

You can open a restaurant by buying a building and hiring staff (your own servers), rent a food-court stall where the landlord handles electricity and cleaning (a managed platform), or sell through a delivery kitchen that only cooks when an order arrives and charges per meal (serverless). For most new food businesses, the stall or the delivery kitchen is the sensible start.

The problem it solves

Running your own servers means patching operating systems, configuring load balancers, scaling, TLS certificates and monitoring: a lot of work before your first user. Most AI apps call hosted models over an API, so they don't need special hardware. Managed and serverless platforms let you skip most of that operations work, as long as you understand their limits.

How it works: serverless functions

  1. You write a handler: a function that receives an event (an HTTP request, a queue message, a file upload) and returns a response.
  2. The platform runs it on demand: it starts instances when requests arrive, runs many in parallel, and scales to zero when idle. You pay per invocation and duration (examples: AWS Lambda, Google Cloud Run functions, Azure Functions, Vercel and Cloudflare functions).
  3. Cold starts: a new instance needs time to start and import libraries; heavy imports (like ML libraries) make it worse. Keep packages small and create clients outside the handler so warm instances reuse them.
  4. Limits: maximum run time (minutes, not hours), memory, payload size, concurrent instances, and sometimes limited streaming support; check each platform's current limits.
  5. No local state: keep conversation history, files and caches in external services (databases, Redis, object storage).
  6. Long work goes async: the function enqueues a job and returns an ID (batch and async).

How it works: Hugging Face Spaces and managed platforms

  1. Managed container platforms (Google Cloud Run, AWS App Runner, Azure Container Apps, Fly.io, Render, Railway and others) take your Docker image or repo, give you HTTPS, autoscaling (often to zero), logs and secrets settings.
  2. Hugging Face Spaces host ML demos from a git repo: pick Gradio, Streamlit or Docker, push, and get a public URL; a free CPU tier suits demos, with paid upgrades for GPUs and persistent storage.
  3. Static and frontend hosts (Vercel, Netlify, Cloudflare Pages) serve your web UI and often include serverless functions for the API.
  4. Configure secrets in the platform's settings, never in the repo (secrets).
  5. Know when to graduate: very high steady traffic, GPUs for self-hosted models (GPU instances), special networking or long-running workers may justify Kubernetes or dedicated servers.
Pick the simplest hosting that fits the workload.

See it in code

Needs
Nothing: plain Python 3. The handler shape matches AWS Lambda behind an HTTP endpoint; the model client is a stand-in.

A serverless handler that validates input, creates its model client only on cold starts, and returns HTTP responses.

handler.py
import json
 
# A serverless function is just a handler: the platform calls it with an event and returns its response.
# This shape (event in, dict with statusCode/body out) is used by AWS Lambda behind an HTTP endpoint;
# other platforms are similar. Keep clients outside the handler so warm invocations reuse them.
INVOCATIONS = {"cold_starts": 0}
CLIENT = None
 
def get_client():
    global CLIENT
    if CLIENT is None:                     # only on a cold start (a fresh container)
        INVOCATIONS["cold_starts"] += 1
        CLIENT = lambda q: f"(model answer to: {q})"   # e.g. anthropic.Anthropic() in real code
    return CLIENT
 
def handler(event, context=None):
    body = json.loads(event.get("body") or "{}")
    question = body.get("question", "").strip()
    if len(question) < 3:
        return {"statusCode": 400, "body": json.dumps({"error": "question too short"})}
    answer = get_client()(question)
    return {"statusCode": 200, "headers": {"Content-Type": "application/json"},
            "body": json.dumps({"answer": answer})}
 
for q in ["What is RAG?", "hi", "What is an embedding?"]:
    r = handler({"body": json.dumps({"question": q})})
    print(r["statusCode"], r["body"])
print("cold starts:", INVOCATIONS["cold_starts"], "for 3 invocations")
Output
200 {"answer": "(model answer to: What is RAG?)"}
400 {"error": "question too short"}
200 {"answer": "(model answer to: What is an embedding?)"}
cold starts: 1 for 3 invocations

For the capstone's FastAPI app, a managed container platform is the easier fit: deploy the same image you built in the Docker lesson, set LLM_PROVIDER and the key as secrets, and point the platform's health check at /ready.

A real example

Example

From demo to product without a server

A two-person team built a contract-summary tool. The first demo went on Hugging Face Spaces as a Gradio app, shared with ten pilot customers within a day. When paying customers arrived, they moved the API to a managed container platform (their Docker image, autoscaling from zero to 20 instances, secrets in the platform's settings), put the frontend on a static host, and moved long document jobs to a queue with a worker service. A year later, at a few thousand users, they still hadn't needed to manage a single server.

The easy way

Start here

For a demo, use Hugging Face Spaces. For a real API that calls hosted models, deploy your Docker image to a managed container platform, add your keys as secrets, and set the health check path. Move to anything more complex only when you hit a concrete limit.

When you grow: the production setup

Teams pick per workload: serverless functions for spiky event handlers, managed containers for APIs, queues and workers for long jobs, GPU platforms or Kubernetes for self-hosted models; they manage platform config with IaC, set minimum instances for latency-critical paths to avoid cold starts, and watch platform limits and costs.

Trade-offs

What you gain

  • Minimal operations work; HTTPS, scaling and logs included.
  • Pay little or nothing when idle.
  • Very fast path from repo to URL.

What it costs you

  • Cold starts and time limits.
  • Less control; platform-specific features create lock-in.
  • Can get expensive at high, steady volume.

When not to use it

  • Long-running GPU inference with steady traffic, or strict networking and compliance needs: use dedicated infrastructure.

Common mistakes

  • Running long agent tasks inside a function until it times out.
  • Storing state in memory or on the instance disk.
  • Creating clients inside the handler on every call.
  • Shipping huge ML libraries in a function that only calls an API.
  • Leaving a public endpoint with no auth or budget (denial of wallet).

Interview questions

Try answering out loud first, then open the model answer.

When would you use serverless functions for an AI app?

Model answer

For short, spiky, event-driven work that calls hosted models, such as webhooks, small API endpoints, or ticket classification, where scaling to zero saves money. Avoid them for long-running tasks (use queues and workers), heavy self-hosted models (GPUs), or latency-critical paths where cold starts hurt, unless minimum instances are configured.

How do you reduce cold-start latency?

Model answer

Keep deployment packages small and imports light, initialise clients outside the handler, use lighter runtimes, configure minimum or provisioned instances for critical paths, and avoid loading large models in functions.

Managed container platform vs Kubernetes for an AI API?

Model answer

A managed container platform gives autoscaling, HTTPS, logs and secrets with almost no operations work, which suits most APIs that call hosted models. Kubernetes gives more control (GPU scheduling, custom networking, many services, sidecars) at the cost of significant operational complexity; it's worth it at larger scale or with self-hosted models.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01What is a cold start?
  2. 02Why create API clients outside the handler function?
  3. 03Which AI workload fits serverless functions poorly?
  4. 04What are Hugging Face Spaces commonly used for?
  5. 05Where does state like conversation history go in a serverless app?

0 of 5 answered

Key terms

Serverless function
Code that the platform runs only when a request or event arrives, scaling automatically and billing per use, with no servers for you to manage.
Cold start
The extra delay when a platform must start a fresh instance (and load code or models) before it can handle a request.
Managed platform
A hosting service that runs your app or container for you, handling servers, HTTPS, scaling and logs.
Hugging Face Spaces
Hugging Face's hosting for ML demos and apps (Gradio, Streamlit or Docker) deployed from a git repository.
Timeout
The longest a request or function may run before it is stopped. LLM calls and serverless functions both need sensible timeouts.

Before and after

Progress is saved in this browser only.