В целом есть такой способ.
придумываешь случайное имя файла при сохранении, например a7bc4fed72ds.jpg
и кладешь его в папку для хранения изображений, но при этом берешь, допустим первые два символа от имени файла и как папку их делаешь, то есть в данном примере:
a7/a7bc4fed72ds.jpg
Таким образом у тебя файлы лягут равномерно по разным папкам.
Но! Ты сохранишь это все в папку original, что иметь доступ к оиргинальному изображению (аватара, допустим):
storage/public/avatars/original/a7/a7bc4fed72ds.jpg
Дальше твой код должен научится генерировать разные размеры аватарок или других изображений с заданным размером и помещать их в кэш.
То есть если в коде, ты запросишь аватар пользователя, например 100x150, то где-то там внутри вызовешь метод $user->getAvatar(100,150) и он тебе должен вернуть путь к этому файлу (не забудь про симлинк).
Проверит кэш - и вернет из кэша, если он есть, иначе вернет файл нужного размера (можешь еще обратить внимание на метод fit() от популярного расширения для работы с изображениями)
Но! чтобы случайно не положить твой сервер - гдето внутри заранее определи какие размеры изображений будут использоватся на твоем сайте и сверяйся с этим списком, иначе не выдавай ничего
Все новые сгенерированные картинки я кладу по тому же принципу, но уже в папку с нужным разрешением, например:
storage/public/avatars/100x150/a7/a7bc4fed72ds.jpg
В случае, если какой-то размер изображения перестал быть нужным - то сразу целиком сносишь эту папку со всеми изображениями и все
Даже можешь все снести папки с размерами, они легко восстановятся, когда будут запрошены (из оригиналов)
Лучше по extrasmall/small/large/extralarge
Изображения обрезают же для экономии трафика на разных устройках