# Downloading files from google drive to server with php code is very slow

**URL:** <https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108>\
**Category:** General PHP Help\
**Created:** [April 15, 2024, 1:21pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108 "2024-04-15T13:21:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [April 15, 2024, 1:21pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/1 "2024-04-15T13:21:03Z")

</div>

Hello,

I make automatic backups with Google Drive service account using PHP.  
For example, manually downloading a 10 MB file to the remote server takes 5 minutes.  
It wasn’t this slow before, what could be the reason?

Again, downloading to local computer via PHP is equally slow

---

<div class="post-metadata">

**Author:** ![jaybo](https://www.phphelp.com/user_avatar/www.phphelp.com/jaybo/32/3923_2.png) [@jaybo](https://www.phphelp.com/u/jaybo)\
**Post date:** [April 22, 2024, 1:57pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/2 "2024-04-22T13:57:03Z")

</div>

Hi Adem,

Can you share some code to review - may help to view the steps being taken for the file downloads.

---

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [April 24, 2024, 9:44am UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/3 "2024-04-24T09:44:30Z")

</div>

I shared it on github.  
Although the description is in Turkish, it is in the google drive library plugins.

This problem did not exist at first, it was downloading very quickly.  
However, with cron jobs, I backup the databases and web directories of 10 websites on Google Drive every night at 00:00.  
I am using drive in a Normail gmail account.  
Could Google have restricted downloads because I make regular backups every night?

I didn’t make any changes to the codes.  
Thanks for be interested

> **[GitHub - adem-genc53/weblerinyonetimi: Basit amatörce yapmaya çalıştığım web...](https://github.com/adem-genc53/weblerinyonetimi)**
>
> Basit amatörce yapmaya çalıştığım web dizinleri, veritabanıları yerele, uzak FTP ve Google Drive a yedekleme scripti - adem-genc53/weblerinyonetimi

---

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [June 5, 2024, 9:12am UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/4 "2024-06-05T09:12:30Z")

</div>

While it downloads a 22 MB file in 10 minutes, the code below downloads it in 1.5 minutes.

```auto
function listFiles($secilen_dizin, $service, $folderId, $path = '') {
    $resultArray = [];
    $results = $service->files->listFiles([
        'q' => "'$folderId' in parents",
    ]);

    foreach ($results->getFiles() as $file) {
        $filePath = $path . '/' . $file->getName();

        if ($file->mimeType == 'application/vnd.google-apps.folder') {
            $resultArray = array_merge($resultArray, listFiles($secilen_dizin, $service, $file->getId(), $filePath));
            $resultArray[$file->getId()][$file->mimeType] = "/".$secilen_dizin.$filePath;
        } else {
            $resultArray[$file->getId()][$file->mimeType] = "/".$secilen_dizin.$filePath;
        }
    }
    return $resultArray;
}

if (isset($_POST['yerel_den_secilen_dosya']) && isset($_POST['google_drive_dan_secilen_dosya_id'])) {
    $yerel_hedef = rtrim($_POST['yerel_den_secilen_dosya'], '/');
    $google_kaynak = ltrim(rtrim($_POST['google_drive_dan_secilen_dosya_adini_goster'],'/'),'/');
    $fileId = $_POST['google_drive_dan_secilen_dosya_id'];

    if (pathinfo($google_kaynak, PATHINFO_EXTENSION)) {
        $file = $service->files->get($fileId, ['fields' => 'id,size']);

        if (intval($file->size) <= 0) {
            echo "Dosya boyutu geçersiz.";
            exit;
        }

        $fileSize = intval($file->size);
        $http = $client->authorize();
        $fp = fopen(rtrim($yerel_hedef,'/')."/".$google_kaynak, 'w');
        $chunkSizeBytes = 10 * 1024 * 1024; // 10 MB
        $chunkStart = 0;

        while ($chunkStart < $fileSize) {
            $chunkEnd = min($chunkStart + $chunkSizeBytes, $fileSize - 1);
            $response = $http->request(
                'GET',
                sprintf('/drive/v3/files/%s', $fileId),
                [
                    'query' => ['alt' => 'media'],
                    'headers' => [
                        'Range' => sprintf('bytes=%s-%s', $chunkStart, $chunkEnd)
                    ]
                ]
            );
            $chunkStart = $chunkEnd + 1;
            fwrite($fp, $response->getBody()->getContents());
        }

        fclose($fp);
        echo "<br /><b>Yerel </b> ".$yerel_hedef." <b>dizine</b><br />";
        echo $google_kaynak." <b>[İNDİRİLDİ]</b>";

    } else {
        $secilen_dizin = $google_kaynak;
        $googleden_secilen_dizin_arr[$fileId]['application/vnd.google-apps.folder'] = "/".$google_kaynak;
        $filePathsArray = listFiles($secilen_dizin, $service, $fileId);
        $secilen_googleden_secilen_array = array_merge($googleden_secilen_dizin_arr, $filePathsArray);

        echo "<br /><b>Yerel </b> ".$yerel_hedef." <b>dizine</b><br />";

        foreach ($secilen_googleden_secilen_array as $id => $dosya_tipi_dosya_adi) {
            foreach ($dosya_tipi_dosya_adi as $dosya_tipi => $dosya_adi) {
                if ($dosya_tipi == 'application/vnd.google-apps.folder') {
                    if (!file_exists($yerel_hedef.$dosya_adi)) {
                        mkdir($yerel_hedef.$dosya_adi, 0755, true);
                    }
                }
            }
        }

        foreach ($secilen_googleden_secilen_array as $id => $dosya_tipi_dosya_adi) {
            foreach ($dosya_tipi_dosya_adi as $dosya_tipi => $dosya_adi) {
                if ($dosya_tipi != 'application/vnd.google-apps.folder') {
                    $file = $service->files->get($id, ['fields' => 'id,size']);

                    if (intval($file->size) <= 0) {
                        echo "Dosya boyutu geçersiz.";
                        continue;
                    }

                    $fileSize = intval($file->size);
                    $http = $client->authorize();
                    $fp = fopen($yerel_hedef.$dosya_adi, 'w');
                    $chunkSizeBytes = 10 * 1024 * 1024;
                    $chunkStart = 0;

                    while ($chunkStart < $fileSize) {
                        $chunkEnd = min($chunkStart + $chunkSizeBytes, $fileSize - 1);
                        $response = $http->request(
                            'GET',
                            sprintf('/drive/v3/files/%s', $id),
                            [
                                'query' => ['alt' => 'media'],
                                'headers' => [
                                    'Range' => sprintf('bytes=%s-%s', $chunkStart, $chunkEnd)
                                ]
                            ]
                        );
                        $chunkStart = $chunkEnd + 1;
                        fwrite($fp, $response->getBody()->getContents());
                    }

                    fclose($fp);
                    echo $dosya_adi." <b>[İNDİRİLDİ]</b><br />";
                }
            }
        }
    }
} else {
    echo "Kaynak ve indirilecek dizin seçilmelidir";
}

```

However, I want to use the code below to quickly download larger GB files, but it gives an error. Can you help me?

```auto
function listFiles($secilen_dizin, $service, $folderId, $path = '') {
    $resultArray = [];
    $results = $service->files->listFiles([
        'q' => "'$folderId' in parents",
    ]);

    foreach ($results->getFiles() as $file) {
        $filePath = $path . '/' . $file->getName();

        if ($file->mimeType == 'application/vnd.google-apps.folder') {
            $resultArray = array_merge($resultArray, listFiles($secilen_dizin, $service, $file->getId(), $filePath));
            $resultArray[$file->getId()][$file->mimeType] = "/".$secilen_dizin.$filePath;
        } else {
            $resultArray[$file->getId()][$file->mimeType] = "/".$secilen_dizin.$filePath;
        }
    }
    return $resultArray;
}

if (isset($_POST['yerel_den_secilen_dosya']) && isset($_POST['google_drive_dan_secilen_dosya_id'])) {
    $yerel_hedef = rtrim($_POST['yerel_den_secilen_dosya'], '/');
    $google_kaynak = ltrim(rtrim($_POST['google_drive_dan_secilen_dosya_adini_goster'],'/'),'/');
    $fileId = $_POST['google_drive_dan_secilen_dosya_id'];

    if (pathinfo($google_kaynak, PATHINFO_EXTENSION)) {
        $file = $service->files->get($fileId, ['fields' => 'id,size']);

        if (intval($file->size) <= 0) {
            echo "Dosya boyutu geçersiz.";
            exit;
        }

        $fileSize = intval($file->size);
        $http = $client->authorize();
        $fp = fopen(rtrim($yerel_hedef, '/') . "/" . $google_kaynak, 'w');
        $chunkSizeBytes = 10 * 1024 * 1024; // 10 MB
        $chunkStart = 0;
        $multiHandle = curl_multi_init();

        while ($chunkStart < $fileSize) {
            $chunkEnd = min($chunkStart + $chunkSizeBytes, $fileSize - 1);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, sprintf('https://www.googleapis.com/drive/v3/files/%s?alt=media', $fileId));
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: Bearer ' . $http->getAccessToken(),
                'Range: bytes=' . $chunkStart . '-' . $chunkEnd
            ]);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) use ($fp) {
                fwrite($fp, $data);
                return strlen($data);
            });
            curl_multi_add_handle($multiHandle, $ch);
            $chunkStart = $chunkEnd + 1;
        }

        // Paralel istekleri gerçekleştirme
        do {
            $status = curl_multi_exec($multiHandle, $active);
            if ($active) {
                curl_multi_select($multiHandle);
            }
        } while ($active && $status == CURLM_OK);

        // Temizlik
        curl_multi_close($multiHandle);
        fclose($fp);

        echo "<br /><b>Yerel </b> " . $yerel_hedef . " <b>dizine</b><br />";
        echo $google_kaynak . " <b>[İNDİRİLDİ]</b>";

    } else {
        $secilen_dizin = $google_kaynak;
        $googleden_secilen_dizin_arr[$fileId]['application/vnd.google-apps.folder'] = "/" . $google_kaynak;
        $filePathsArray = listFiles($secilen_dizin, $service, $fileId);
        $secilen_googleden_secilen_array = array_merge($googleden_secilen_dizin_arr, $filePathsArray);

        echo "<br /><b>Yerel </b> " . $yerel_hedef . " <b>dizine</b><br />";

        foreach ($secilen_googleden_secilen_array as $id => $dosya_tipi_dosya_adi) {
            foreach ($dosya_tipi_dosya_adi as $dosya_tipi => $dosya_adi) {
                if ($dosya_tipi == 'application/vnd.google-apps.folder') {
                    if (!file_exists($yerel_hedef . $dosya_adi)) {
                        mkdir($yerel_hedef . $dosya_adi, 0755, true);
                    }
                }
            }
        }

        foreach ($secilen_googleden_secilen_array as $id => $dosya_tipi_dosya_adi) {
            foreach ($dosya_tipi_dosya_adi as $dosya_tipi => $dosya_adi) {
                if ($dosya_tipi != 'application/vnd.google-apps.folder') {
                    $file = $service->files->get($id, ['fields' => 'id,size']);

                    if (intval($file->size) <= 0) {
                        echo "Dosya boyutu geçersiz.";
                        continue;
                    }

                    $fileSize = intval($file->size);
                    $http = $client->authorize();
                    $fp = fopen($yerel_hedef . $dosya_adi, 'w');
                    $chunkSizeBytes = 10 * 1024 * 1024;
                    $chunkStart = 0;
                    $multiHandle = curl_multi_init();

                    while ($chunkStart < $fileSize) {
                        $chunkEnd = min($chunkStart + $chunkSizeBytes, $fileSize - 1);
                        $ch = curl_init();
                        curl_setopt($ch, CURLOPT_URL, sprintf('https://www.googleapis.com/drive/v3/files/%s?alt=media', $id));
                        curl_setopt($ch, CURLOPT_HTTPHEADER, [
                            'Authorization: Bearer ' . $http->getAccessToken(),
                            'Range: bytes=' . $chunkStart . '-' . $chunkEnd
                        ]);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                        curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) use ($fp) {
                            fwrite($fp, $data);
                            return strlen($data);
                        });
                        curl_multi_add_handle($multiHandle, $ch);
                        $chunkStart = $chunkEnd + 1;
                    }

                    // Paralel istekleri gerçekleştirme
                    do {
                        $status = curl_multi_exec($multiHandle, $active);
                        if ($active) {
                            curl_multi_select($multiHandle);
                        }
                    } while ($active && $status == CURLM_OK);

                    // Temizlik
                    curl_multi_close($multiHandle);
                    fclose($fp);

                    echo $dosya_adi . " <b>[İNDİRİLDİ]</b><br />";
                }
            }
        }
    }
} else {
    echo "Kaynak ve indirilecek dizin seçilmelidir";
}

```

I am using Google Drive IP “Service” account and no user confirmation is required  
The connection code is located in the file `google_drive_setup.pnp` on the download page `include 'google_drive_setup.php';` I’am adding.

```auto
function getClient() {
    $client = new \Google\Client();
    $client->setApplicationName('Google Drive API PHP Quickstart');
    $client->setScopes(\Google\Service\Drive::DRIVE);
    $client->setAuthConfig(AUTHCONFIGPATH);
    $client->setAccessType('offline');
    return $client;
}

$client = getClient();
$service = new \Google\Service\Drive($client);

```

---

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [June 12, 2024, 1:57pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/6 "2024-06-12T13:57:25Z")

</div>

Thank you for the answer,  
Slow download problem is related to encoding.  
With the latest coding it is now even faster.

> [@Adem](#):
>
> However, I want to use the code below to quickly download larger GB files, but it gives an error. Can you help me?

My last code, I want to download very large files with a parallel download system, but I am getting a lot of errors. Can you take a look at the code, where are the mistakes?

---

<div class="post-metadata">

**Author:** ![fatimaahmed](https://www.phphelp.com/user_avatar/www.phphelp.com/fatimaahmed/32/4338_2.png) [@fatimaahmed](https://www.phphelp.com/u/fatimaahmed)\
**Post date:** [July 12, 2024, 7:38am UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/7 "2024-07-12T07:38:57Z")

</div>

Hello,  
I think you have to check for high network traffic or server load, which can impede file transfers. Your PHP configuration settings, including max\_execution\_time, memory\_limit, and post\_max\_size, as inadequate settings may cause timeouts or incomplete downloads. May you consider any potential rate limits or restrictions imposed by the Google Drive API if you’re using it for backups.

---

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [July 12, 2024, 3:46pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/8 "2024-07-12T15:46:42Z")

</div>

These php settings are set to unlimited.  
I increased the speed quite a bit, the problem is related to coding.  
I’m trying to do parallel downloading for GB size files, but I’m getting an error. The sample code is above.  
I would be grateful if you help me.

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [July 12, 2024, 9:39pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/9 "2024-07-12T21:39:04Z")

</div>

@adem, the last two replies are generic chatbot generated answers, having nothing to do with your question.

What error are you getting?

---

<div class="post-metadata">

**Author:** ![Adem](https://www.phphelp.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@Adem](https://www.phphelp.com/u/Adem)\
**Post date:** [July 14, 2024, 9:30pm UTC](https://www.phphelp.com/t/downloading-files-from-google-drive-to-server-with-php-code-is-very-slow/36108/10 "2024-07-14T21:30:14Z")

</div>

PHP Fatal error: Uncaught Error: Call to undefined function GuzzleHttp\Promise\settle() →

```auto
Promise\all($promises)->wait();
Promise\settle($promises)->wait();

```

The above gives error  
and I tried both options above

```auto
use GuzzleHttp\Client;
use GuzzleHttp\Promise;

class GoogleDriveDownloader {
    private $service;
    private $client;
    private $guzzleClient;

    public function __construct($service, $client) {
        $this->service = $service;
        $this->client = $client;
        $this->guzzleClient = new Client();
    }

    private function listFiles($folderId, $path = '') {
        $resultArray = [];
        $results = $this->service->files->listFiles([
            'q' => "'$folderId' in parents",
            'fields' => 'files(id, name, mimeType)'
        ]);

        foreach ($results->getFiles() as $file) {
            $filePath = $path . '/' . $file->getName();
            if ($file->mimeType == 'application/vnd.google-apps.folder') {
                $resultArray = array_merge($resultArray, $this->listFiles($file->getId(), $filePath));
                $resultArray[$file->getId()] = ['path' => $filePath, 'mimeType' => $file->mimeType];
            } else {
                $resultArray[$file->getId()] = ['path' => $filePath, 'mimeType' => $file->mimeType];
            }
        }
        return $resultArray;
    }

    public function downloadFile($localPath, $googlePath, $fileId) {
        $file = $this->service->files->get($fileId, ['fields' => 'id,name,size,mimeType']);

        if ($file->mimeType == 'application/vnd.google-apps.folder') {
            $filePathsArray = $this->listFiles($fileId, $googlePath);
            foreach ($filePathsArray as $id => $fileInfo) {
                if ($fileInfo['mimeType'] == 'application/vnd.google-apps.folder') {
                    $folderPath = rtrim($localPath, '/') . '/' . trim($fileInfo['path'], '/');
                    if (!file_exists($folderPath)) {
                        mkdir($folderPath, 0755, true);
                    }
                }
            }
            foreach ($filePathsArray as $id => $fileInfo) {
                if ($fileInfo['mimeType'] != 'application/vnd.google-apps.folder') {
                    $this->downloadFile($localPath, $fileInfo['path'], $id);
                }
            }
        } else {
            if (intval($file->size) <= 0) {
                echo "Dosya boyutu geçersiz.";
                return;
            }

            $fileSize = intval($file->size);
            $chunkSizeBytes = 10 * 1024 * 1024; // 10 MB
            $filePath = rtrim($localPath, '/') . '/' . $googlePath;
            $promises = [];
            $accessTokenArray = $this->client->getAccessToken();
            $accessToken = is_array($accessTokenArray) ? $accessTokenArray['access_token'] : $accessTokenArray;

            for ($chunkStart = 0; $chunkStart < $fileSize; $chunkStart += $chunkSizeBytes) {
                $chunkEnd = min($chunkStart + $chunkSizeBytes, $fileSize - 1);
                $range = sprintf('bytes=%s-%s', $chunkStart, $chunkEnd);

                $promises[] = $this->guzzleClient->getAsync(sprintf('https://www.googleapis.com/drive/v3/files/%s?alt=media', $fileId), [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $accessToken,
                        'Range' => $range,
                    ]
                ])->then(function ($response) use ($filePath, $chunkStart) {
                    $file = fopen($filePath, 'c');
                    fseek($file, $chunkStart);
                    fwrite($file, $response->getBody()->getContents());
                    fclose($file);
                });
            }

            Promise\all($promises)->wait();
            echo "<br /><b>Yerel </b> " . $localPath . " <b>dizine</b><br />";
            echo $googlePath . " <b>[İNDİRİLDİ]</b>";
        }
    }
}

ob_start();
ini_set('memory_limit', '-1');
ignore_user_abort(true);
set_time_limit(3600); // 7200 saniye 120 dakikadır, 3600 1 saat

if (isset($_POST['yerel_den_secilen_dosya']) && isset($_POST['google_drive_dan_secilen_dosya_id'])) {
    $yerel_hedef = rtrim($_POST['yerel_den_secilen_dosya'], '/');
    $google_kaynak = trim($_POST['google_drive_dan_secilen_dosya_adini_goster'], '/');
    $fileId = $_POST['google_drive_dan_secilen_dosya_id'];

    $downloader = new GoogleDriveDownloader($service, $client);
    $downloader->downloadFile($yerel_hedef, $google_kaynak, $fileId);
} else {
    echo "Kaynak ve indirilecek dizin seçilmelidir";
}

```
