PHP Classes
elePHPant
Icontem

QoS Bandwidth Throttle in PHP: Limit the speed of files served for download

Recommend this page to a friend!
  Info   Screenshots Screenshots   View files View files (5)   DownloadInstall with Composer Download .zip   Reputation   Support forum (2)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2011-03-22 (5 years ago) RSS 2.0 feedStarStarStarStar 72%Total: 1,827 This week: 1All time: 2,082 This week: 1,047Up
Version License PHP version Categories
bandwidth-throttler 1.1.5GNU Lesser Genera...5.2.0HTTP, PHP 5, Files and Folders, Syste..., P...
Description Author

This class can be used to limit (throttle) the speed of files served for download.

It intercepts the PHP script output by setting a buffering handler that is called every time a given number of bytes are served to the browser.

The class measures the time since the last time the PHP output buffer was flushed and hold on PHP for a while if the average download speed is above a given limit.

---------------------------------------------------------------------------
There are three different bandwidth shaping mechanisms to ensure adequate Quality of Service:

1) burst transfer rate will be switched off after sending X bytes to the user (this can be helpful to send small images quickly, and limit the download speed of huge files)

2) burst transfer rate will be switched off after given period of time in seconds, then it will revert to the standard throttle speed

3) burst transfer rate will not be activated at all, the download speed limit will be constant during the whole downloading process (in this case $config->burstLimit must be equal to the $config->rateLimit)

Innovation Award
PHP Programming Innovation award nominee
January 2011
Number 2


Prize: One copy of DWebPro Standard License
If too many users access a server to download files or other resources, the server may reach to the bandwidth usage limit and the access to the server may become too slow to all users.

A solution for this problem consists in throttling the download speed, i.e., limiting the speed by which the files are served to the users that are downloading them.

This class implements a clever download speed throttling approach controlled by PHP.

It consists in capturing the output of the download scripts into a buffer, flush the buffer at a rate that does not exceed a given limit by introducing eventual pauses if the file is served at a speed above the limit.

Manuel Lemos
Picture of Artur Graniszewski
  Performance   Level  
Name: Artur Graniszewski <contact>
Classes: 13 packages by
Country: Poland Poland
Innovation award
Innovation award
Nominee: 7x

Winner: 1x

Details
INDEX

1) Terms definitions: Throttling process, Quality of Service

2) Technical aspects and caveats of Bandwidth throttling using PHP

3) Pros and cons of this class

4) PHP Class Usage

5) Example source code


1) Terms definitions [from Wikipedia] 
----------------------------------------------------------------------
a) Throttling process (computing) 

In software, a throttling process, or a throttling controller as it is sometimes called, 
is a process responsible for regulating the rate at which application processing is conducted, 
either statically or dynamically.

For example, in high throughput processing scenarios, as may be common in online transactional 
processing (OLTP) architectures, a throttling controller may be embedded in the application hosting 
platform to balance the application's outbound publishing rates with its inbound consumption rates, 
optimize available system resources for the processing profile, and prevent eventually unsustainable 
consumption. In, say, an enterprise application integration (EAI) architecture, a throttling process 
may be built into the application logic to prevent an expectedly slow end-system from becoming 
overloaded as a result of overly aggressive publishing from the middleware tier.

b) Quality of Service

In the field of computer networking and other packet-switched telecommunication networks, the traffic 
engineering term quality of service (QoS) refers to resource reservation control mechanisms rather than 
the achieved service quality. Quality of service is the ability to provide different priority to different 
applications, users, or data flows, or to guarantee a certain level of performance to a data flow. 
For example, a required bit rate, delay, jitter, packet dropping probability and/or bit error rate may 
be guaranteed. Quality of service guarantees are important if the network capacity is insufficient, 
especially for real-time streaming multimedia applications such as voice over IP, online games and IP-TV, 
since these often require fixed bit rate and are delay sensitive, and in networks where the capacity is 
a limited resource, for example in cellular data communication.

2) Technical aspects and caveats of Bandwidth throttling using PHP
----------------------------------------------------------------------
First of all, the PHP throttling mechanism is not a good equivalent of a low-level system traffic shaping.
The major problem is that PHP takes more system resources to handle the user request than a system firewall 
(standard PHP process can take as much as 15-30MB of the system memory just to send a file over a network).

Another problem is that on shared hostings support for set_time_limit() function in PHP is limited (due to 
the safe mode or other system configuration), so when the downloaded file is too big, it has to be send to the 
user in more than 30 seconds (a default PHP time limit after which request is automatically aborted). In this 
case to send something bigger, you have to ask your system administrator to increase your time limit above 30 
seconds.

The last thing to remember is that PHP can be executed on many different OS'es and APIs. For example PHP can be
installed as an Apache module (mod_php.so), or as a FastCGI module (mod_fcgi + suexec), etc. In any of this
scenarios there is a potential risk, that bandwidth throttling may be unsuccesfull because of the internal 
output buffering (see for example Apache directive "SendBufferSize" in httpd.conf, or FastCGI output buffering) 
which sometimes cannot be properly controlled in the PHP. In this case you have to ask your system administrator 
to alter configuration files respectively (this ofcourse can be problematic on shared hostings).


3) Pros and cons of this class
----------------------------------------------------------------------
a) PROS:
- small memory footprint - output is sent realtime, so even 12GB of generated data can be sent using ~8MB of RAM.
- low CPU usage - every system call (like microtime()) is done only once per packet sent, every mathematical
  calculation result is cached when necessary.
- nonintrusive throttling - you just need to do one include() in your index.php or master file to use this class
  (usually there is no need to change your own code, like phpBB or Drupal)
- working with PHP 5.0, 5.2, 5.3+, as an Apache module, FastCGI or even CLI process on all known Operating Systems.
- working out of the box!

b) CONS:
- usually needs more time than a default 30 seconds timeout set in php.ini file (for bigger files or slow transfers)
- can be scrambled by an unusual system configuration (see output buffering in caveats section)
- higher memory usage than in firewall equivalent
- can easily exhaust limit of user PHP processes set in FastCGI configuration (for example FCGI_MAX_CHILDREN), when 
  used simultaneously by many downloaders.


4) PHP Class Usage
----------------------------------------------------------------------
There are three different bandwidth shaping mechanisms to provide adequate Quality of Service:

a) burst transfer rate will be switched off after sending X bytes to the user (this can be helpful to send 
   small images quickly, and limit the download speed of huge files)

b) burst transfer rate will be switched off after given period of time in seconds, then it will revert to 
   the standard throttle speed

c) burst transfer rate will not be activated at all, the download speed limit will be constant during 
   the whole downloading process (in this case $config->burstLimit must be equal to the $config->rateLimit)

See example.php and example2.php for working implementation.

5) Example sourcecode:
----------------------------------------------------------------------
Example #1: Throttling by download duration (send files at the speed of 50.000 bytes for the first 30 seconds, 
            then slow down to the 15.000 bytes per second)

<?php

	require("./throttler.php");

	// create new config
	$config = new ThrottleConfig();
	// enable burst rate for 30 seconds
	$config->burstTimeout = 30;
	// set burst transfer rate to 50000 bytes/second
	$config->burstLimit = 50000;
	// set standard transfer rate to 15.000 bytes/second (after initial 30 seconds of burst rate)
	$config->rateLimit = 15000;
	// enable module (this is a default value)
	$config->enabled = true;

	// start throttling
	$x = new Throttle($config);

	header("Content-type: application/force-download");
	header("Content-Disposition: attachment; filename=\"test.txt\"");
	header("Content-Length: 60000000");

	// generate 60.000.000 bytes file.  
	for($i = 0; $i < 60000000; $i++) {
	    echo "A";
	} 

	?>

Example #2: Throttling by file size (send small files at the speed of 50.000 bytes per second, and bigger
            ones at the speed of 15.000 bytes per second)

	<?php

	require("./throttler.php");

	// create new config
	$config = new ThrottleConfigBySize();
	// enable burst rate for first 500000 bytes, after that revert to the standard transfer rate
	$config->burstSize = 500000;
	// set burst transfer rate to 50000 bytes/second
	$config->burstLimit = 50000;
	// set standard transfer rate to 15.000 bytes/second (after initial 30 seconds of burst rate)
	$config->rateLimit = 15000;
	// enable module (this is a default value)
	$config->enabled = true;

	// start throttling
	$x = new Throttle($config);

	header("Content-type: application/force-download");
	header("Content-Disposition: attachment; filename=\"test.txt\"");
	header("Content-Length: 60000000");

	// generate 60.000.000 bytes file.  
	for($i = 0; $i < 60000000; $i++) {
	    echo "A";
	} 
	?>
Screenshots  
  • speed_decrease.PNG
  Files folder image Files  
File Role Description
Plain text file throttler.php Class Main class
Accessible without login Plain text file example.php Example Example script
Accessible without login Plain text file example2.php Example Example script using data size as the bandwidth limit factor
Accessible without login Plain text file license.txt Lic. LPGP license
Accessible without login Plain text file readme.txt Doc. Documentation

 Version Control Unique User Downloads Download Rankings  
 0%
Total:1,827
This week:1
All time:2,082
This week:1,047Up
User Ratings User Comments (1)
 All time
Utility:93%StarStarStarStarStar
Consistency:93%StarStarStarStarStar
Documentation:80%StarStarStarStarStar
Examples:84%StarStarStarStarStar
Tests:-
Videos:-
Overall:72%StarStarStarStar
Rank:197
 
Ty for this nice class.
4 years ago (Martin D?dík)
75%StarStarStarStar