PHPackages                             beheh/flaps - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. beheh/flaps

AbandonedArchivedLibrary[HTTP &amp; Networking](/categories/http)

beheh/flaps
===========

Modular library for rate limiting requests in applications

0.2.0(8y ago)62243.5k—6.2%11[1 PRs](https://github.com/beheh/flaps/pulls)2ISCPHPPHP &gt;=5.3.0

Since Mar 29Pushed 8y ago3 watchersCompare

[ Source](https://github.com/beheh/flaps)[ Packagist](https://packagist.org/packages/beheh/flaps)[ Docs](https://github.com/beheh/flaps)[ RSS](/packages/beheh-flaps/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (3)Versions (6)Used By (2)

Flaps
=====

[](#flaps)

[![Travis](https://camo.githubusercontent.com/fd9e73692607c73c4b62c2747cd92b58693a4b217e34413a4a2fdb6344cbaa29/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f62656865682f666c6170732f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/beheh/flaps)[![Scrutinizer Coverage](https://camo.githubusercontent.com/e9f608ea4d15a3a380e540f29c0eba4c00b4eab50cd3efee52d337abb0dc2614/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f62656865682f666c6170732f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/beheh/flaps/?branch=master)[![Scrutinizer](https://camo.githubusercontent.com/7c10de95832790c52c2510ec88cac6d025f79d4f689301eaca452ce5fca78e30/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f62656865682f666c6170732f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/beheh/flaps/?branch=master)[![Packagist](https://camo.githubusercontent.com/5a536b0d486d457246d7c9af8cfb21019278b2e688e1e4e8df3f21cda2b548f9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f62656865682f666c6170732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/beheh/flaps)[![Packagist](https://camo.githubusercontent.com/e90d7917e7afd1abe4d89a3ee50587cb47ffebfab21bfe5519b1d4138ed1a365/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f62656865682f666c6170732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/beheh/flaps)

Flaps is a modular library for rate limiting requests in PHP applications.

The library supports custom storage backends, throttling strategies and violation handlers for flexible integration into any project.

Developed by [@beheh](https://github.com/beheh) and licensed under the ISC license.

Requirements
------------

[](#requirements)

- PHP 5.4 or newer
- Persistent-ish storage (e.g. Redis, APC or anything supported by *[Doctrine\\Cache](http://doctrine-common.readthedocs.org/en/latest/reference/caching.html)*)
- Composer

Basic usage
-----------

[](#basic-usage)

```
use Predis\Client;
use BehEh\Flaps\Storage\PredisStorage;
use BehEh\Flaps\Flaps;
use BehEh\Flaps\Throttling\LeakyBucketStrategy;

// setup with Redis as storage backend
$storage = new PredisStorage(new Client());
$flaps = new Flaps($storage);

// allow 3 requests per 5 seconds
$flaps->login->pushThrottlingStrategy(new LeakyBucketStrategy(3, '5s'));
//or $flaps->__get('login')->pushThrottlingStrategy(...)

// limit by ip (default: send "HTTP/1.1 429 Too Many Requests" and die() on violation)
$flaps->login->limit($_SERVER['REMOTE_ADDR']);
```

Why rate limit?
---------------

[](#why-rate-limit)

There are many benefits from rate limiting your web application. At any point in time your server(s) could be hit by a huge number of requests from one or many clients. These could be:

- Malicious clients trying to degrade your applications performance
- Malicious clients bruteforcing user credentials
- Bugged clients repeating requests over and over again
- Automated web crawlers enumerating usernames or email adresses
- Penetration frameworks testing for vulnerabilities
- Bots registering a large number of users
- Bots spamming links to malicious sites

Most of these problems can be solved in a variety of ways, for example by using a spam filter or a fully configured firewall. Rate limiting is nevertheless a basic tool for improving application security, but offers no full protection.

Advanced examples
-----------------

[](#advanced-examples)

### Application-handled violation

[](#application-handled-violation)

```
use BehEh\Flaps\Throttling\LeakyBucketStrategy;
use BehEh\Flaps\Violation\PassiveViolationHandler;

$flap = $flaps->__get('api');
$flap->pushThrottlingStrategy(new LeakyBucketStrategy(15, '10s'));
$flap->setViolationHandler(new PassiveViolationHandler);
if (!$flap->limit(filter_var(INPUT_GET, 'api_key'))) {
	die(json_encode(array('error' => 'too many requests')));
}
```

### Multiple throttling strategies

[](#multiple-throttling-strategies)

```
use BehEh\Flaps\Throttling\LeakyBucketStrategy;

$flap = $flaps->__get('add_comment');
$flap->pushThrottlingStrategy(new LeakyBucketStrategy(1, '30s'));
$flap->pushThrottlingStrategy(new LeakyBucketStrategy(10, '10m'));
$flap->limit($userid);
```

Storage
-------

[](#storage)

### Redis

[](#redis)

The easiest storage system to get started is Redis (via [nrk/predis](https://github.com/nrk/predis)):

```
use Predis\Client;
use BehEh\Flaps\Storage\PredisStorage;
use BehEh\Flaps\Flaps;

$storage = new PredisStorage(new Client('tcp://10.0.0.1:6379'));
$flaps = new Flaps($storage);
```

Don't forget to `composer require predis/predis`.

### Doctrine cache

[](#doctrine-cache)

You can use any of the [Doctrine cache implementations](http://doctrine-common.readthedocs.org/en/latest/reference/caching.html) by using the *DoctrineCacheAdapter*:

```
use Doctrine\Common\Cache\ApcCache;
use BehEh\Flaps\Storage\DoctrineCacheAdapter;
use BehEh\Flaps\Flaps;

$apc = new ApcCache();
$apc->setNamespace('MyApplication');
$storage = new DoctrineCacheAdapter($apc);
$flaps = new Flaps($storage);
```

The Doctrine caching implementations can be installed with `composer require doctrine/cache`.

### Custom storage

[](#custom-storage)

Alternatively you can use your own storage system by implementing *BehEh\\Flaps\\StorageInterface*.

Throttling strategies
---------------------

[](#throttling-strategies)

### Leaky bucket strategy

[](#leaky-bucket-strategy)

This strategy is based on the leaky bucket algorithm. Each unique identifier of a flap corresponds to a leaky bucket. Clients can now access the buckets as much as they like, inserting water for every request. If a request would cause the bucket to overflow, it is denied. In order to allow later requests, the bucket leaks at a fixed rate.

```
use BehEh\Flaps\Throttle\LeakyBucketStrategy;

$flap->pushThrottlingStrategy(new LeakyBucketStrategy(60, '10m'));
```

### Custom throttling strategy

[](#custom-throttling-strategy)

Once again, you can supply your own throttling strategy by implementing *BehEh\\Flaps\\ThrottlingStrategyInterface*.

Violation handler
-----------------

[](#violation-handler)

You can handle violations either using one of the included handlers or by writing your own.

HTTP violation handler
----------------------

[](#http-violation-handler)

The HTTP violation handler is the most basic violation handler, recommended for simple scripts. It simply sends the correct HTTP header (status code 429) and die()s. This is not recommended for any larger application and should be replaced by one of the more customizable handlers.

```
use BehEh\Flaps\Violation\HttpViolationHandler;

$flap->setViolationHandler(new HttpViolationHandler);
$flap->limit($identifier);  // send "HTTP/1.1 429 Too Many Requests" and die() on violation
```

Passive violation handler
-------------------------

[](#passive-violation-handler)

The passive violation handler allows you to easily react to violations. `limit()` will return false if the requests violates any throttling strategy, so you are able to log the request or return a custom error page.

```
use BehEh\Flaps\Violation\PassiveViolationHandler;

$flap->setViolationHandler(new PassiveViolationHandler);
if (!$flap->limit($identifier)) {
	// violation
}
```

### Exception violation handler

[](#exception-violation-handler)

The exception violation handler can be used in larger frameworks. It will throw a *ThrottlingViolationException* whenever a *ThrottlingStrategy* is violated. You should be able to setup your exception handler to catch any *ThrottlingViolationException*.

```
use BehEh\Flaps\Violation\ExceptionViolationHandler;
use BehEh\Flaps\Violation\ThrottlingViolationException;

$flap->setViolationHandler(new ExceptionViolationHandler);
try {
	$flap->limit($identifier); // throws ThrottlingViolationException on violation
}
catch (ThrottlingViolationException $e) {
	// violation
}
```

### Custom violation handler

[](#custom-violation-handler)

The corresponding interface for custom violation handlers is *BehEh\\Flaps\\ViolationHandlerInterface*.

### Default violation handler

[](#default-violation-handler)

The `Flaps` object can pass a default violation handler to the flaps.

```
$flaps->setDefaultViolationHandler(new CustomViolationHandler);

$flap = $flaps->__get('login');
$flap->addThrottlingStrategy(new TimeBasedThrottlingStrategy(1, '1s'));
$flap->limit($identifier); // will use CustomViolationHandler
```

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity47

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~398 days

Total

3

Last Release

3272d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/687eab5210e73ecfdc6d37d3732eeb4f96fddbfa7698e3bce49f05fabf4c953c?d=identicon)[BehEh](/maintainers/BehEh)

---

Top Contributors

[![beheh](https://avatars.githubusercontent.com/u/929769?v=4)](https://github.com/beheh "beheh (132 commits)")[![Icewild](https://avatars.githubusercontent.com/u/8243173?v=4)](https://github.com/Icewild "Icewild (2 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (1 commits)")

---

Tags

leaky-bucketphprate-limitinghttprate limitthrottle

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/beheh-flaps/health.svg)

```
[![Health](https://phpackages.com/badges/beheh-flaps/health.svg)](https://phpackages.com/packages/beheh-flaps)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.0B3.2k](/packages/guzzlehttp-psr7)[psr/http-message

Common interface for HTTP messages

7.1k1.0B5.5k](/packages/psr-http-message)[psr/http-factory

PSR-17: Common interfaces for PSR-7 HTTP message factories

1.9k692.9M1.9k](/packages/psr-http-factory)[psr/http-client

Common interface for HTTP clients

1.7k680.7M2.1k](/packages/psr-http-client)[psr/link

Common interfaces for HTTP links

2.5k144.1M68](/packages/psr-link)[rmccue/requests

A HTTP library written in PHP, for human beings.

3.6k34.5M258](/packages/rmccue-requests)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
