php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63937 Upload speed 10 times slower with PHP
Submitted: 2013-01-08 07:49 UTC Modified: 2021-02-17 22:57 UTC
Votes:37
Avg. Score:4.8 ± 0.6
Reproduced:33 of 34 (97.1%)
Same Version:18 (54.5%)
Same OS:17 (51.5%)
From: levi_tedder at hotmail dot com Assigned:
Status: Verified Package: FTP related
PHP Version: Irrelevant OS: Windows
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2013-01-08 07:49 UTC] levi_tedder at hotmail dot com
Description:
------------
If using ftp_put() the upload speed is 10-20 times slower that when using a 
"regular" FTP client like Filezilla. Uploading with cUrl is equally slow. Tested 
on multiple PHP versions on several Windows operating systems and on two different 
networks, all same.

Note that downloading (ftp_get()) is equally fast as using Filezilla.

Test script:
---------------
<?php
$conn_id = ftp_connect ( "ftpserver" );
$login_result = ftp_login ( $conn_id, "username", "password" );
if ((! $conn_id) || (! $login_result)) {
	exit ( "No FTP connection" );
} else {
	ftp_pasv ( $conn_id, true );
	$size = filesize ( $localfile );
	$start_timer = time ();
	if (ftp_put ( $conn_id, "remote file", "local file", FTP_BINARY )) {
		$end_timer = time ();
		$time_spent = $end_timer - $start_timer;
		echo "Transferred $size bytes in $time_spent seconds";
	} else {
		exit ( "FTP upload error" );
	}
	ftp_close ( $conn_id );
}
?>

Expected result:
----------------
The file should be transferred at the same speed as when using a "regular" FTP 
client like Filezilla.

Actual result:
--------------
Filezilla
File transfer successful, transferred 190 923 591 bytes in 170 seconds

PHP ftp_put()
Transferred 190 923 591 bytes in 1563 seconds

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-03-31 11:01 UTC] xeon dot g8 at gmail dot com
yes experiencing this same annoying issue aswel

linux os, php version latest

using php's ftp function to upload files is way slower than using any other ftp client to transfer files from from the same two servers.

Not sure why but its very annoying that there doesn't seem to be any way php ini settings to fix this.

please fix it soon
 [2013-08-21 21:01 UTC] r dot pestel at googlemail dot com
I have the same problem with cUrl (posting files via HTTP), on Windows Server 2008 
and 2012 and Windows 7. Always about 10x slower than possible on the server side 
(If the server could send 10 mbps I get 1 mbps, even if this is 100% of my 
capacity).
 [2013-09-05 19:46 UTC] dmulder at qnx dot com
I have seen the same issue, windows 2008. Upload speeds are much slower than other platforms. I did find this bug reference in libcurl which may be relevant
http://sourceforge.net/p/curl/bugs/1188/?page=1
 [2017-09-10 10:39 UTC] awlurker at yandex dot ru
The problem still exists and is very annoying.
PHP FTP upload functionality seems to be almost unusable because of this.
 [2017-12-04 14:34 UTC] luk dot krchnak at gmail dot com
Is there any progress? I have the same issue... Thanks.
 [2018-03-20 01:20 UTC] tung12a1 at yahoo dot com
Is there any progress? I have found the same issue.
 [2021-02-17 22:57 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2021-02-17 22:57 UTC] cmb@php.net
I can confirm that ftp_put() uploads are slow on Windows.
Increasing the FTP_BUFSIZE[1] to a value just a bit smaller than
SO_SNDBUF (64KiB on my system), shows a performance improvement of
about 30%.  However, uploading from WSL1 still takes only half the
time.  There might be room for (further) improvements on Windows,
but maybe this is just a Windows limitation.  This needs further
investigation.

Note the ftp_put() relies on select(3), so performance is
certainly not optimal on either operating system.

[1] <https://github.com/php/php-src/blob/php-7.4.15/ext/ftp/ftp.h#L38>
 [2021-05-17 17:27 UTC] sudoma at seznam dot cz
Bug showed after complete upgrade (kernel, libraries, php) of our production backup-copying system.
System is connecting to FTP inside our LAN and is used to push backup video files (250+TiB in total, daily throughput approx. 160GiB) to external backup over 1Gbit infrastructure.

Before upgrade, php ftp performance was comparable to midnight commander ftp client
 ie. approx. 80MBps-90MBps.
After upgrade php performance degraded to approx. 1/6 of mc ftp which is approx. 15MBps.

I have serious backlog of 50-60TiB which i need to push through FTP and this performance regression showing after upgrade is real pain ...

command used in php script is ftp_push
there is no difference in enabling FTP_PASSIVE 
(problem manifests in active and passive mode)
mode used is FTP_BINARY

i have done some tests now and behavior is observed under:
php-7.4.14
php-7.2.34
php-5.6.29
php-5.5.37

i have tried to compile 
php-7.4.14 with FTP_BUFSIZE 65536 in ftp.h
however there seems to be no difference in behavior.

My guess is this may be problem of some underlying library which is being used in php and not being used in other clients

Any help would be greatly appreciated.
 [2021-05-20 10:48 UTC] sudoma at seznam dot cz
Workaround found:

Under php 7.4.19 problem persists.

However, under the very same version and build of php,
 where php function ftp_put() has unsatisfactory performance of 15MBps,
calling cURL to do the same job has performance comparable to other FTP clients i.e. 80MBps.

I therefore believe, this performance regression is limited to FTP extension of PHP

code:
ftp_put($this->FTPHANDLE,$dest,$src,FTP_BINARY)

code (return values checks redacted out):

$curlhandle = curl_init()
$srcfilehandle = fopen($src,'r'))
curl_setopt($curlhandle, CURLOPT_URL, 'ftp://'.$user.':'.$pass.'@'.$url.'/'.$dest);
curl_setopt($curlhandle, CURLOPT_UPLOAD, 1);
curl_setopt($curlhandle, CURLOPT_FTP_USE_EPSV, TRUE);
curl_setopt($curlhandle, CURLOPT_TRANSFERTEXT, FALSE);
curl_setopt($curlhandle, CURLOPT_INFILE, $srcfilehandle);
curl_setopt($curlhandle, CURLOPT_INFILESIZE, filesize($src));
curl_exec($curlhandle);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 08:01:29 2024 UTC