Skip to main content
This tutorial shows you how to build a REST API using Flash load-balanced endpoints. You’ll create a multi-route API that handles text processing, demonstrates both CPU and GPU endpoints, and deploys to production.

Requirements

What you’ll build

By the end of this tutorial, you’ll have a working REST API that:
  • Accepts text input via POST /analyze
  • Returns system health via GET /health
  • Provides API information via GET /info
  • Runs GPU-accelerated sentiment analysis via POST /sentiment (optional GPU route)
  • Deploys to Runpod Serverless with proper authentication

Step 1: Set up your project

Create a new directory for your project and set up a Python virtual environment:
Install Flash using uv:
Set your API key in the environment:
Replace YOUR_API_KEY with your actual Runpod API key.

Step 2: Create the API server file

Create a new file called api.py:

Step 3: Define the load-balanced endpoint

Add the following code to api.py:
This configuration creates a CPU load-balanced endpoint that can handle multiple HTTP routes.
Worker Quota Considerations: The workers setting determines the maximum number of concurrent workers. Standard Runpod accounts have a total quota of 30 workers across all endpoints. If you have other endpoints running, you may need to reduce workers to (0, 1). Check your quota in the Runpod console.

Step 4: Add API routes

Add three routes to your API - health check, info, and text analysis:
All three routes share the same api endpoint, meaning they deploy to a single Serverless endpoint.

Step 5: Add a GPU-accelerated route (optional)

For GPU-accelerated sentiment analysis, add a separate endpoint:
This creates a second endpoint specifically for GPU-accelerated tasks.
The sentiment analysis route uses a separate GPU endpoint because it requires different hardware than the CPU routes. This is a common pattern: use CPU endpoints for lightweight API logic and GPU endpoints for ML inference.GPU Availability: Using GpuGroup.ANY provides better availability than specific GPU types like GpuGroup.ADA_24. First requests to GPU endpoints may take 3-10 minutes due to:
  • GPU provisioning (depends on current availability)
  • Dependency installation (transformers, torch)
  • Model downloads (distilbert is ~250MB)
During high demand periods, GPU provisioning may take longer. Check GPU availability in the console.

Step 6: Add the main execution block

Add the following at the end of api.py to enable local testing:

Step 7: Test locally

Run your script to test the API locally:
You should see output similar to:
The first three endpoints will run locally. The sentiment endpoint will be skipped unless you install transformers and torch locally, but it will work when deployed to Flash.
Local Testing Limitations: The GPU sentiment endpoint requires transformers and torch to be installed locally for testing. For full testing of all endpoints including GPU routes, use flash dev (covered in Step 9) instead of direct Python execution.

Step 8: Build a Flash app for production

To deploy your API to production, create a Flash app:
This creates a project structure with separate worker files. Now, split your API code into the appropriate worker files:

Create lb_worker.py (CPU routes):

Replace the contents of lb_worker.py with:

Create gpu_worker.py (GPU route):

If you added the GPU sentiment route, replace the contents of gpu_worker.py with:

Configure environment:

Replace YOUR_API_KEY with your actual Runpod API key.

Step 9: Test with the development server

Start the Flash development server:
You’ll see output showing all available endpoints:
Development Server Path Prefixes: The flash dev server adds worker file prefixes to routes (e.g., /lb_worker/health, /gpu_worker/sentiment). When deployed to production, endpoints use the paths as defined in the route decorators (e.g., /health, /sentiment) without the prefixes.
Open http://localhost:8888/docs in your browser to see the interactive API documentation. You can test all your routes directly in the Swagger UI. Test with curl:
Expected responses:
GPU Cold Starts: The first request to a GPU endpoint may take 3-10 minutes due to GPU provisioning, dependency installation, and model downloads. During high demand periods, provisioning may take longer. Subsequent requests will be much faster. The default timeout is 60 seconds, which may be too short for the first request. If you encounter timeout errors, wait and retry - the GPU may still be initializing.

Step 10: Deploy to production

When you’re ready to deploy, use flash deploy:
After deployment, Flash displays your endpoint URLs:

Step 11: Call your deployed API

Call your production endpoints with authentication:
Expected response:
Production Path Note: In production, the endpoints use the exact paths defined in your route decorators (e.g., /health, /sentiment), without the worker file prefixes used in flash dev.

Understanding the deployment architecture

Your deployed API creates two independent Serverless endpoints: Key points:
  • CPU endpoint (text-api) handles three routes on one Serverless endpoint
  • GPU endpoint (gpu-sentiment) handles GPU inference on a separate endpoint
  • Both endpoints scale independently based on load
  • All requests require authentication with your API key

Troubleshooting

Worker quota exceeded

Issue: Max workers across all endpoints must not exceed your workers quota (30) Solution:
  1. Check your current worker usage in the Runpod console
  2. Reduce workers in your configuration:
  3. Clean up unused endpoints before deploying new ones

GPU endpoint timeout

Issue: Request times out after 60 seconds on first GPU endpoint call Solutions:
  1. This is normal for the first request - GPU provisioning takes time
  2. Wait 1-3 minutes and try again
  3. Use GpuGroup.ANY instead of specific GPU types for better availability
  4. Consider using CPU for development testing:

Port already in use

Issue: ERROR: [Errno 48] Address already in use when running flash dev Solutions:

Import errors in sentiment analysis

Issue: ModuleNotFoundError: No module named 'transformers' Solution: Ensure dependencies are specified on the endpoint:
For local testing, install dependencies manually:

Endpoint stays in queue

Issue: GPU sentiment route stays in IN_QUEUE status Solutions:
  1. Check GPU availability in console
  2. Use flexible GPU selection:
  3. Increase worker quota if at limit

Next steps

Now that you’ve built a REST API with Flash, you can:

Add more routes

Expand your API with additional functionality:

Add authentication middleware

Implement custom authentication for your API:

Monitor your API

  • Track endpoint health in the Runpod console
  • Monitor request counts and error rates
  • Adjust workers based on traffic patterns

Use multiple environments

Deploy to different environments for testing: