Laravel AWS S3 Storage image cache

Viewed 3409

I have Laravel based web and mobile application that stores images on AWS S3 and I want to add cache support because even small number of app users produce hundreds and sometimes thouthands of GET requests on AWS S3.

To get image from mobile app I use GET request that is being handled by code like this

public function showImage(....) {
  ...
  return Storage::disk('s3')->response("images/".$image->filename);
}

On the next image you can see response headers that I receive. Cache-Control shows no-cache so I assume that mobile app won't cache this image.

enter image description here

  1. How can I add cache support for this request? Should I do it?
  2. I know that Laravel Documentaion suggests caching for Filestorage - should I implement it for S3? Can it help to decrease GET requests count of read files from AWS S3? Where can I find more info about it.
2 Answers

I would suggest to use a temporary URL as described here: https://laravel.com/docs/7.x/filesystem#file-urls

Then use the Cache to store it until it is expired:

$value = Cache::remember('my-cache-key', 3600 * $hours, function () use ($hours, $image) {
    $url = Storage::disk('s3')->temporaryUrl(
        "images/".$image->filename, now()->addMinutes(60 * $hours + 1)
    ); 
});

Whenever you update the object in S3, do this to delete the cached URL:

Cache::forget('my-cache-key');

... and you will get a new URL for the new object.

You could use a CDN service like CloudFlare and set a cache header to let CloudFlare keep the cache for a certain amount of time.

$s3->putObject(file_get_contents($path), $bucket, $url, S3::ACL_PUBLIC_READ, array(), array('Cache-Control' => 'max-age=31536000, public'));

This way, files would be fetched once by CloudFlare, stored at their servers, and served to users without requesting images from S3 for every single request.

See also:
How can I reduce my data transfer cost? Amazon S3 --> Cloudflare --> Visitor
How to set the Expires and Cache-Control headers for all objects in an AWS S3 bucket with a PHP script

Related