# SlowAPI: Secure Your FastAPI App with Rate Limiting

Have you ever experienced a sudden surge in API requests that slowed down your FastAPI app or even caused it to crash? Whether it's a malicious attack or an accidental overload, excessive requests can harm your application's performance and security.

That’s where **rate limiting** comes in! By setting limits on how often users can make requests, you can **protect your API from abuse**, **ensure fair usage**, and **maintain optimal performance**.

In this guide, we’ll **walk you through SlowAPI**, a simple yet effective way to **add rate limiting** to your FastAPI application. Whether you’re a beginner or an experienced developer, you’ll find **step-by-step instructions** to implement and customize rate limiting effortlessly.

Let’s dive in and make your API more secure and efficient! 🚀

---

## **What is Rate Limiting, and Why Do You Need It?**

Rate limiting is a technique used to **control the number of requests a client can make** within a specific timeframe. It's essential for:

✅ **Preventing API abuse** – Stops users from overwhelming your API with too many requests.  
✅ **Improving security** – Mitigates DDoS attacks and brute-force login attempts.  
✅ **Enhancing performance** – Ensures fair resource allocation and prevents slowdowns.  
✅ **Saving costs** – Reduces unnecessary server load and prevents excessive bandwidth usage.

FastAPI doesn’t have built-in rate limiting, but **SlowAPI** provides an easy way to implement it. Now, let’s set it up step by step!

---

## **Step 1: Install SlowAPI**

To get started, install the SlowAPI package using pip:

```python
pip install slowapi
```

Since SlowAPI depends on **Starlette Middleware**, FastAPI will work seamlessly with it.

---

## **Step 2: Set Up the Rate Limiter**

Now, in your FastAPI application, import and configure the **Limiter** from SlowAPI:

```python
from fastapi import FastAPI, Request
from slowapi import Limiter
from slowapi.util import get_remote_address

# Initialize the rate limiter
limiter = Limiter(key_func=get_remote_address)

# Create the FastAPI app and add the limiter
app = FastAPI()
app.state.limiter = limiter
```

Here’s what’s happening:

✅ `Limiter`: Creates a rate limiter instance.  
✅ `get_remote_address`: Uses the client’s IP address as the identifier for rate limiting.  
✅ `app.state.limiter`: Stores the limiter in the app's state for global access.

---

## **Step 3: Apply Rate Limiting to Routes**

Now, let’s apply rate limits to your API endpoints.

### **Limit Requests on a Single Route**

You can restrict a specific route using a decorator:

```python
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware
from starlette.responses import JSONResponse

# Middleware to handle rate limiting
app.add_middleware(SlowAPIMiddleware)

@app.get("/limited-route")
@limiter.limit("5/minute")  # Allows only 5 requests per minute
async def limited_endpoint(request: Request):
    return {"message": "This route is rate limited!"}
```

### **Handling Rate Limit Errors**

If a user exceeds the limit, they should receive a **clear error message**. You can define a custom error handler like this:

```python
from starlette.requests import Request

@app.exception_handler(RateLimitExceeded)
async def rate_limit_handler(request: Request, exc: RateLimitExceeded):
    return JSONResponse(
        status_code=429,
        content={"error": "Too many requests! Please try again later."}
    )
```

---

## **Step 4: Apply Global Rate Limits**

To set a **global limit** for all routes, modify the app setup:

```python
limiter = Limiter(key_func=get_remote_address, default_limits=["100/hour"])  # 100 requests per hour

app = FastAPI()
app.state.limiter = limiter
app.add_middleware(SlowAPIMiddleware)
```

Now, all routes in your API will have a global limit of **100 requests per hour** unless specified otherwise.

---

## **Step 5: Customize Rate Limits for Different Users**

You might want to allow different limits based on user roles, API keys, or authentication levels. You can customize the `key_func` to achieve this:

```python
def custom_key_func(request: Request):
    user = request.headers.get("X-User-ID", "anonymous")  # Use user ID if available
    return user

limiter = Limiter(key_func=custom_key_func, default_limits=["50/minute"])
```

This approach:  
✅ **Identifies users based on headers** (or authentication tokens).  
✅ **Prevents abuse by distinguishing between authenticated and anonymous users.**  
✅ **Allows flexible rate limits per user type.**

---

## **Final Thoughts & Next Steps**

Congratulations! 🎉 You’ve successfully implemented **rate limiting in your FastAPI app** using SlowAPI. Now, your API is more secure, efficient, and protected from abuse.

### **Next Steps:**

🚀 **Test your API** by making multiple requests to ensure rate limiting works as expected.  
🔧 **Adjust the rate limits** based on your app’s needs.  
🔑 **Implement role-based rate limits** for better control.

Rate limiting is just **one step** toward securing your FastAPI app. Want to take it further? Consider **authentication, logging, and monitoring** for a fully protected API.

Now, go ahead and **secure your API with SlowAPI today!** 🚀

If you're new to Python and want to strengthen your core knowledge, check out:  
🔹 [**Exploring Python's Core: From Basics to Behind-the-Scenes**](https://blog.bytescrum.com/exploring-pythons-core-from-basics-to-behind-the-scenes)  
🔹 [**Mastering Python Operators**](https://blog.bytescrum.com/mastering-python-operators-part-1)
