Implementing API Throttling in My PHP Project
Tags: php, api, memcached, throttling
Published: 2024-06-29 13:09:06

Today, I’m diving into a cool backend challenge I recently tackled: implementing API rate limiting and throttling using PHP and Memcached. This stuff is crucial for protecting APIs from abuse and ensuring everyone gets fair usage. Let’s break down how I solved this.

### The Challenge: API Rate Limiting and Throttling

APIs can get overwhelmed if access to them is not properly managed. That’s where rate limiting and throttling come in – they help control how many requests a user or app can make to an API within a certain timeframe. Here’s how I tackled this:

### Step 1: Defining the Rate Limit Policies

First, I had to define the rate limit policies which spell out how many requests are allowed per minute, hour, or day, and what happens when someone exceeds the limit..

**Example Policy:**
- **Free Users:** 100 requests per minute
- **Paid Users:** 1000 requests per minute

### Step 2: Choosing the Right Tools

Second, I picked Memcached for storing the request counts because it’s super fast and efficient.

### Step 3: Implementing the Rate Limiting Logic

Next, I wrote the rate limiting logic in PHP, using Memcached to store and manage request counts. Here’s a simplified version of what I did:

```php
<?php
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);

function is_rate_limited($user_id, $max_requests, $window_seconds) {
    global $memcached;
    $key = "user:$user_id:requests";
    $current_requests = $memcached->get($key);

    if ($current_requests === false) {
        $memcached->set($key, 1, $window_seconds);
        return false;
    } elseif ($current_requests < $max_requests) {
        $memcached->increment($key);
        return false;
    } else {
        return true;
    }
}

$max_requests = 100;
$window_seconds = 60;

if (is_rate_limited($user_id, $max_requests, $window_seconds)) {
    http_response_code(429);
    echo 'Rate limit exceeded. Please try again later.';
} else {
    echo 'Your request was successful.';
}
?>
```

### Step 4: Integrating with the API

Then, I integrated the rate limiting logic with the existing API endpoints. This involved adding middleware to check the rate limit before processing each request. If the limit was exceeded, the API would return a 429 status code (Too Many Requests).

### Step 5: Testing and Monitoring

Testing and monitoring were key to ensure the rate limiting was working correctly. Here’s how I set that up:

#### Testing

**Create Test Scripts:**
   - I wrote scripts to simulate high traffic and burst traffic scenarios.
   - These scripts repeatedly sent requests to the API and logged responses.

**Example Test Script in PHP:**

```php
<?php
$apiUrl = 'http://my-api-endpoint';
$requests = 120; // Number of requests to send

for ($i = 0; $i < $requests; $i++) {
    $response = file_get_contents($api_url);
    echo "Response $i: " . $response . "\n";
    usleep(500000); // Delay of 0.5 seconds between each request
}
?>
```

**Logging Rate-Limited Requests:**
   - I added logging to track when users hit the rate limit.
   - This could be useful for analyzing patterns and adjusting the rate limits as needed.

**Example Logging in PHP:**

```php
<?php
function is_rate_limited($user_id, $max_requests, $window_seconds) {
    global $memcached;
    $key = "user:$user_id:requests";
    $current_requests = $memcached->get($key);

    if ($current_requests === false) {
        $memcached->set($key, 1, $window_seconds);
        return false;
    } elseif ($current_requests < $max_requests) {
        $memcached->increment($key);
        return false;
    } else {
        error_log("Rate limit exceeded for user $user_id");
        return true;
    }
}
?>
```

### Joining the HNG Internship

Solving challenging problems like API rate limiting is why I love backend development. Now, I’m trying to take my skills to the next level by joining the [HNG Internship](https://hng.tech/internship). Even though I have a couple years of experience in backend development, I’m joining the HNG Internship to stay sharp, connect with the community, see what’s happening in the space, and maybe find some exciting job opportunities.

From what I've heard, the HNG Internship is perfect for staying updated with the latest trends and technologies. It’s also a great way to meet other passionate developers and potentially get hired by amazing companies through [HNG Hire](https://hng.tech/hire).

### Why the HNG Internship?

1. **Stay Sharp:** Continuous learning is key in tech, and the HNG Internship offers new challenges to keep my skills sharp.
2. **Connect:** Networking with other developers and mentors is invaluable for personal and professional growth.
3. **Explore Trends:** Being part of HNG helps me stay on top of the latest industry trends and innovations.
4. **Job Opportunities:** The internship could open doors to exciting job opportunities with top companies.

### Conclusion

Backend development can be tough, but with the right approach, I believe that even the most complex problems can be solved. I’m excited about the journey ahead with the HNG Internship. If you’re also interested in growing your skills, check out the [HNG Internship](https://hng.tech/internship).