https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_b964594d3d957944241961017b9eb19bf02834de44cce93d8e67dd306852dbe346167181e455e33d5268ea01d973d77bb056848546f31794f31a4c31a9da5aa3.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_09f62869dbd00446535ebe8e270406331e6f0ae459deba58094caeadc22d58825ffc99f8c217b496ec112cbb1da8b662d77b0f52eae24cc5631f95695e40d87b.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_e6b7e0bf68aa4a61d5c6a0065ec42e38a0cc53e39a4fbee057b72d4b2297b37c01e716e1e61bac7f240b5a0edbb178d37b62f7ed4ea4ea3d10e46dbe7429f326.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_bfff9e63e857e9ee612e292d4a6edf3ced64d6a756925c953a9d8f77845ff601eca64d73dfa48756b1a9f4a4d6de6127a273bcde16ddeb71a22383460f4e94b0.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_f4dd7e1d73ae5eda35ed5ad6aa965b612dbf483ece3ca50c1e8e30ad8dff1c66a160ed75e958e2db399661d229874783e0834ad813a479437035666b8e9e3386.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_4fce0769137d4cd096989b0349bc3c2bbfca79ac311fdf714c41ab24d87551c7b49b756c8a8de090b0714a0ad0560e49fa532ba5a88875ea4afd78efac464df6.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_85cec8b07d60426b11040e471babca0d2f9c8dc87a9b56e06cad39828f7f67179e29609100f282a574872c9a93fb635b25416300eb4c97bc5a653d00cf6f8dbf.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_6768e5a27d4d357347338621c0d20bd269b126d30eec796193390f2f530fbaea60af84130c46f9786114be65149e661e87d55c339219c90aa76396d7e5b734ef.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_2acd6bdff3b680341e8c727da5169a647123eb8fd0a90253161b4c3af272c15d293bf9bb217008bb13f84d1910b0e166798001f8603b6c026d5c20a76c41d47c.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_7034c614020d1a1e32fbb17b13eca17ce9a08b0e6db5f4f0e55257f3b2b00a2534d70203380a3415c2049cf9de7013bea0143be27725ad3b7baf836b357f2dbf.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_268c9bba6ba649318f0da28c37b09a9bbfa371210f9b6b52faa7fd8ae94abf6b3c3bfeb5df5705c93495ce1152ca58aeabc435d6c6c1bd959025165c3f50e086.js
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer
  • Home
  • Featured
    • Advanced Python Topics
    • AWS Learning Roadmap
    • JWT Complete Guide
    • Git CheatSheet
  • Explore
    • Programming
    • Development
      • microservices
      • Front End
    • Database
    • DevOps
    • Productivity
    • Tutorial Series
      • C# LinQ Tutorials
      • PHP Tutorials
  • Dev Tools
    • JSON Formatter
    • Diff Checker
    • JWT Decoder
    • JWT Generator
    • Base64 Converter
    • Data Format Converter
    • QR Code Generator
    • Javascript Minifier
    • CSS Minifier
    • Text Analyzer
  • About
  • Contact
CodeSamplez.com

CodeSamplez.com

Programming And Development Resources

You are here: Home / Programming / How to Efficiently Retrieve Multiple Objects from AWS S3

How to Efficiently Retrieve Multiple Objects from AWS S3

Updated May 14, 2025 by Rana Ahsan Leave a Comment ⏰ 6 minutes

AWS S3 get multiple objects with PHP

Hhandling multiple S3 objects can be a royal pain when you’re dealing with performance issues. I recently faced this exact problem while working on a project that required me to retrieve numerous media files from AWS S3, process them to create thumbnails, and display them on a webpage.

It sounds simple enough, right? Wrong.

The performance bottleneck hit me like a ton of bricks. When you’re retrieving files one after another, the wait time becomes unbearable – especially since the number of files was completely dynamic. Your users will absolutely abandon your application if they have to stare at loading screens for ages.

The Parallel Request Solution

The solution is actually quite brilliant – make multiple requests in parallel instead of sequentially. This approach dramatically reduces retrieval time to essentially the duration needed for the longest file. Instead of adding up all the wait times, you’re overlapping them!

We will be using PHP based solution in this article(the stack I had to use while dealing with my project). However, even if you are trying to achieve this in a different language, chances are you would be able to do so following similar approach shown in this guide.

Thankfully, the official Amazon PHP SDK uses the Guzzle library for HTTP requests, and since version 2.0, Guzzle has supported parallel requests. This made implementing my solution much easier than expected.

Implementation: Creating a Custom S3 Client

Let’s dive right into the code. I’ll show you exactly how I extended the S3Client class to add parallel retrieval functionality:

<?php 
namespace S3;

use Aws\S3\S3Client;
use \Aws\Common\Exception\TransferException;

/**
 * Extended S3Client class for retrieving multiple objects in parallel
 * @author Your Name
 */
class MyS3Client extends S3Client {
    
    /**
     * Retrieves multiple S3 objects in parallel
     * 
     * @param Array $configs Configuration array for each object
     * @param S3Client $client S3Client instance
     * @return void
     */
    public static function getObjects(Array $configs, S3Client $client) {
        $requests = array();
        $savePaths = array();
        
        // Create request objects for each file
        foreach ($configs as $config) {
            $url = "https://" . $config["Bucket"] . ".s3.amazonaws.com/" . $config["Key"];
            $request = $client->get($url);
            $requests[] = $request;
            $savePaths[$url] = $config["saveAs"];
        }
        
        // Send all requests in parallel
        try {
            $responses = $client->send($requests);
        } catch(TransferException $e) {
            echo $e->getError();
        }
        
        // Process all responses and save files
        foreach ($responses as $res) {
            $localPath = $savePaths[$res->getEffectiveUrl()];
            file_put_contents($localPath, $res->getBody(true));
        }
    }
}Code language: HTML, XML (xml)

How to Use the Parallel S3 Client

Using this custom client is incredibly straightforward. Here’s how you’d implement it in your project:

// Create a new instance of our custom S3 client
$s3 = new \S3\MyS3Client([
    'version' => 'latest',
    'region'  => 'us-east-1', // Change to your region
    'credentials' => [
        'key'    => 'YOUR_AWS_ACCESS_KEY',
        'secret' => 'YOUR_AWS_SECRET_KEY',
    ]
]);

// Create configuration array for multiple objects
$configs = array();

// Add first object
$configs[] = array(
    'Bucket' => "my-test-bucket",
    'Key'    => "path/to/first-object.jpg",
    'saveAs' => "local/path/first-image.jpg"
);

// Add second object
$configs[] = array(
    'Bucket' => "my-test-bucket",
    'Key'    => "path/to/second-object.jpg",
    'saveAs' => "local/path/second-image.jpg"
);

// Add as many objects as needed following the same pattern

// Retrieve all objects in parallel
\S3\MyS3Client::getObjects($configs, $s3);Code language: PHP (php)

Understanding the Implementation in Detail

Let me break down exactly what’s happening in our implementation:

  1. We extend the original S3Client class provided by the AWS PHP SDK, which means you can use it exactly like the original client with all its methods.
  2. We add a static method called getObjects() that takes two parameters:
    • An array of configurations (one for each object to be retrieved)
    • An instance of the S3 client
  3. For each object in the configs array, we:
    • Construct the S3 URL
    • Create a GET request
    • Store the request in our requests array
    • Map the URL to the local save path for later use
  4. We send all requests simultaneously using the client’s send() method with our array of requests.
  5. Once we receive the responses, we iterate through them and save each object to its designated local path.

Why a Static Method?

You might be wondering why I implemented getObjects() as a static method. The original S3Client class is structured so that most methods map directly to AWS SDK REST API commands, with additional utility methods being static. I followed this pattern for consistency.

That said, if you have a better approach to implement this as a non-static method, I’d absolutely love to hear about it! Leave a comment below with your suggestions.

Performance Benefits

The performance improvement from this approach is nothing short of impressive. Let’s put it into perspective:

  • Sequential approach: If you have 10 files taking 2 seconds each = 20 seconds total wait time
  • Parallel approach: The same 10 files = approximately 2 seconds (the time of the slowest file)

That’s a 90% reduction in wait time! Your users will definitely notice the difference, and your application will feel much more responsive.

Important Considerations

Before implementing this solution, keep these points in mind:

  1. Memory Usage: Processing multiple large files simultaneously requires more memory. Monitor your application’s memory consumption.
  2. AWS Rate Limits: Be mindful of AWS request limits. Very large numbers of parallel requests might trigger throttling.
  3. Error Handling: Our example includes basic error handling, but you should enhance it for production use.
  4. The ‘saveAs’ Parameter: Unlike single object retrieval where ‘saveAs’ is optional, it’s required here to ensure each object is saved to the correct location.

Applying This Beyond S3

The parallel request pattern isn’t limited to S3. You can apply similar techniques to other scenarios requiring multiple HTTP requests, such as:

  • Fetching data from multiple API endpoints
  • Downloading files from various sources
  • Processing batches of database records

Conclusion

Retrieving multiple S3 objects in parallel through PHP is an extremely effective way to optimize your application’s performance. By extending the AWS SDK’s S3Client class and leveraging Guzzle’s parallel request capabilities, you can dramatically reduce wait times for your users.

The code provided here is straightforward to implement and can be easily integrated into existing projects. If performance is important for your S3 operations – and let’s be honest, when isn’t it? – this approach is definitely worth implementing.

Have you tried similar optimization techniques with AWS services? I’d love to hear about your experiences in the comments!

Share if liked!

  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on X (Opens in new window) X
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pinterest (Opens in new window) Pinterest
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to share on Tumblr (Opens in new window) Tumblr
  • Click to share on Pocket (Opens in new window) Pocket

You may also like


Discover more from CodeSamplez.com

Subscribe to get the latest posts sent to your email.

First Published On: February 23, 2014 Filed Under: Programming Tagged With: aws, php

About Rana Ahsan

Rana Ahsan is a seasoned software engineer and technology leader specialized in distributed systems and software architecture. With a Master’s in Software Engineering from Concordia University, his experience spans leading scalable architecture at Coursera and TopHat, contributing to open-source projects. This blog, CodeSamplez.com, showcases his passion for sharing practical insights on programming and distributed systems concepts and help educate others.
Github | X | LinkedIn

Reader Interactions

Leave a ReplyCancel reply

Primary Sidebar

  • Facebook
  • X
  • Pinterest
  • Tumblr

Subscribe via Email

Top Picks

python local environment setup

Python Local Development Environment: Complete Setup Guide

In-Depth JWT Tutorial Guide For Beginners

JSON Web Tokens (JWT): A Complete In-Depth Beginners Tutorial

The Ultimate Git Commands CheatSheet

Git Commands Cheatsheet: The Ultimate Git Reference

web development architecture case studies

Web Development Architecture Case Studies: Lessons From Titans

static website deployment s3 cloudfront

Host Static Website With AWS S3 And CloudFront – Step By Step

Featured Dev Tools

  • Diff Checker
  • JSON Formatter

Recently Published

python file handling

Python File Handling: A Beginner’s Complete Guide

service worker best practices

Service Worker Best Practices: Security & Debugging Guide

advanced service worker features

Advanced Service Worker Features: Push Beyond the Basics

service worker framework integration

Service Workers in React: Framework Integration Guide

service worker caching strategies

Service Worker Caching Strategies: Performance & Offline Apps

Footer

Subscribe via Email

Follow Us

  • Facebook
  • X
  • Pinterest
  • Tumblr

Demos

  • Demo.CodeSamplez.com

Explore By Topics

Python | AWS | PHP | C# | Javascript

Copyright © 2025

https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_3d86243d92461c59517718e7c273383ede3f49fe331f3d2edf5d9ea4efd70ef9af004cfc54644f1ef649e03ff07e83d3413e8c38647833591f527cbc5aadb702.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_c402e38f1879c18090377fb6b73b15ac158be453ecda3a54456494fe8aba42b990c293bae5424e5643d52515ffc2067e0819995be8d07d5bba9107a96780775c.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_ffc3511227531cc335353c54c3cbbaa11d0b80e5cb117478e144436c13cd05495b67af2e8950480ed54dbdabcdcef497c90fdb9814e88fe5978e1d56ce09f2cf.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_d57da9abfef16337e5bc44c4fc6488de258896ce8a4d42e1b53467f701a60ad499eb48d8ae790779e6b4b29bd016713138cd7ba352bce5724e2d3fe05d638b27.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_d286e50977f467ebee8fecdcb44e6a6b9a29f2b911dfe58b30ff4f0545aa2b19bca73246e23de9a6d2380bf20e6b8a001b5ba2051042d104c6d411b474fd3368.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_556272a5f9c5e1b26dcf93c48dd6c60d2107db888f97b70498f312c9052331e10005db30e1259f325d650689883af8e7250f282b512037503c7b7dcf03bef034.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_dccc492dbbfdac33d1411f9df909e849c7268fcf99b43007f278cde3a0adc0ae00e8cae5ec81cf255b9a6eae74e239ba1fa935572af77173219cb081f7d2327d.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_00bacf9e36181aac2b666d110cd9d82257f846766e7041b2d7b3c909b458982931ccc9b203e37098fbdfcf43ca359cf04e3824a724a6789fc204196d3a72ad29.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_c1c18b8baf8ed2aa84a8022e80b5422016646101cc3549c023473f24ad731189d3f4e279527a58a60bef61e6f749d51f280c52a82dfdab5075e6bc20bf21b240.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_68b6d1949e90b6a37c5195ae17874e7c2455352144f28a76be0f68f7a941e6d664fa3c931485f2c5463521acdac05ff6642f0c94fa557a087caa9478d162f085.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_bb8058a9e234a7ffaa98891b1df7f6b8e67410e6984568b151daa05113b8c7f89d7b5918ae73f020998a16f7f5a087a13d6a9a5e5d7c301e2ca12fd9d1f8d177.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_647fb67570c6108fb10ae6785a1abdbecac99ffcf80351d0bef17c3cf783dce497b1895fcdaae997dacc72c359fbfb128cc1540dd7df56deb4961e1cd4b22636.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_f7a298a0f1f754623fe3b30f6910ce2c1373f715450750bd7a391571812b00df1917e2be90df6c4efc54dbdfda8616278a574dea02ba2c7a31992768df8db334.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_df30604d5842ef29888c3c1881220dc6d3f8854666d94f0680c5f38aa643c5fb79b10eb9f10998d8856eb24ca265783195937434fd6c2bb8e4846df0277a7fb7.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_f17fe6fb0993f1703181d7ae9e9ea570f3d33a43afd6f2a4567daa1a6745698c7b8193dc72d50991d2dd87cd3dcf663959206607d193a9b57926d061a1f50aef.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_945dcbab2c2a131f3c90f4fb91776b76066d589f84fb55bff25cd5d79a56218000616bfca1f0af9a74f32348693707af49e8fe624de8aa34f1e1c5b6a25709cf.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_65820d252e1b93596de6697fd5f02483f3e2524a0696c7d698b64745edb32bf5831a90e556842f5f88c8209766cc78ca3a41cf783d20236a9f90d4a7ea7b3e72.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_7286884797a1210857e2a36f8ab46604b0034b6abf512380447a5763c873db6a72b8547f660053de0ea69faef1eb64878f39ff4b0ea86c963efab95764a3bf5b.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_cbcf6c279ac6c6a25ae138bf964e64a5fd90d22dcdf8a53b6fe7b72cefa51063bfb0181a6e50dd2acdcae2795619887d1d83b10461e44e5103be756f2588d837.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_47965bc586b95810c925b9df3314e0c9a5cd121e70ca0831f87df0bc034695de4f83ecf2def86f737e14614ee138794473cf32cd3082a5d38db9dec0c1f266fa.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_12aa201cea075846d266536aa222d64d4088b851d87f55dac5e611b77add6826c8ebc6e82650fcd1a9e88a05a0072dedd195719c5f64cd4580a0acd8aee05d92.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_80a4a4c808f46b20177fec8ee1a931010e5d14047c467a7f976cb5b2529b569eeb61558804f2f1a2d2a2347a1e2041500c1b275b1b4c31bbb4b36d8b4183b2b6.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_6b8331138c6135bce7893f76010e2d9aee2b5cc249df4cb5b42fcf651216640eb6902880fff3563ebb11b643b8f71464d2b65bbefab93d987f4ff4de13ceb159.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_d87ea86dd0e7ecdd5fe7a5bb67becf943e57c3add866b456034d51663d099031bd563e12f61fdccc044969adf938a8584ed22ccd401ab8b669e20e4f92fb54e8.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_35311c3d71a3605fad4e1d6b50f3911311cdcc46418bdf56d6d0308a75a69585269ee7582a335e29989adf308fa1a81a10a2c2d4e257e9d680447a4996f6269e.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_f4fc182ef03c12e9dcadd6febc3dbaa4a29134469057ca9e8ec0be2f2de29a494514ff4b59798e74debf26f78b2df2b3e2665c69b77035761fb463b783202915.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_85c0f2769456e60153b0fd8364b82a035da53384f62de342d9bdca806f3f1ea56486919a00497a18d457949c82bf8bfacc4423fc332074ddf71a49a8fe628fff.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_1b7e49e98f5960d71636812e807832cc98a24f48bc493652ddb2f9c4ce08bc89a8fd5d9550a8e2887d1d8887ce02924a878361c296d21ceba18a56f3ace130bd.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_09eecfdd96206ed13830b4b93cfb2cc75cd38083671a34194437b5734b5bb38712209dc335b07e3266ceb3c3a44a155b9bbe5f3e0e1105b19dd45d3def76f020.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_4c089fbdb88e3b624a6f884d3ba1bf606f003bfcd3742376d0d353cd62181dc663aa3811a56361c3100de488fc4d6595a50de2b26f058921ba74f5f2c1b5be00.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_897ff6ac314c5f5e0f496c6af624bd9abf296a02cb5aeb850b9220b6dc3ce2fc4004cb02ed8b59d59d4b9c9d90f050d6eebc1d08ecaebab2f671f7d9367e6410.js
https://codesamplez.com/wp-content/cache/breeze-minification/js/breeze_67d1e619e71d36ae00ddcf85ee18628bb4eb64fcb3d6119b463e75cb987013420a21136d19cd03e6634ccc01cfa9af4a357930e4cf6900953b7812efb4f249fb.js