Storing Photos and Videos: Server Disk or Cloud Storage Like S3, Bunny, and GCS?

A practical comparison of keeping photos, videos, and documents on the application server versus a cloud storage service such as Amazon S3, Google Cloud Storage, Cloudflare R2, Bunny Storage, or Backblaze B2, with a monthly cost example for an application serving users in Indonesia.

Published 11 min read
Rows of servers in a data center

Every application that accepts photos or videos eventually faces the same question: should the files stay on the server that runs the application, or move to a storage service such as Amazon S3, Google Cloud Storage, or Bunny Storage? There is no single right answer. A small internal system can run for years with files on its own disk, while a marketplace with thousands of product photos or a learning platform full of videos usually outgrows it within months. Below we compare both approaches, look at the main providers, and run the numbers for a typical case.

Two Very Different Ways to Keep Files

Saving to the server disk means the application writes the upload into a folder such as storage/uploads, and the web server (Nginx, Apache, or the framework itself) sends the file back when someone asks for it. Storage, delivery, and backup are all your responsibility, and they share CPU, memory, disk, and network with the application.

Cloud storage, more precisely object storage, is a separate service that you talk to over an API. The application uploads a file and gets back a key, and users download the file from the storage service or from a CDN in front of it. The provider takes care of disks, replication, and capacity. You pay per gigabyte stored, per request, and, depending on the provider, per gigabyte downloaded.

Side-by-Side Comparison

AspectServer diskCloud storage
Initial costAlready included in the VPS or server pricePay per use, often a few dollars a month to start
CapacityFixed by the plan. When the disk is full, uploads fail and the database can stop tooGrows automatically, and you pay for what you actually store
DurabilityOne disk or one RAID array. Safety depends on your backupsCopies across several disks or facilities, for example S3 is designed for 11 nines of durability
Bandwidth to usersLimited by the server port and quota. Large videos compete with API trafficDelivered by the provider or a CDN, separate from the application server
More than one serverNeeds shared storage such as NFS or file syncing between serversEvery server reads and writes the same bucket
Backup and restoreHundreds of gigabytes to copy every night, and slow to restoreVersioning, replication, and lifecycle rules are built in
Monthly billPredictable, since it is part of the server costChanges with usage, especially download traffic
Effort for the teamSimple at first, more operational work as files growA little more work at first: credentials, signed URLs, CORS

When the Server Disk Is Still a Good Choice

  • Internal applications with a limited number of users, such as an HR or inventory system, where files are mostly PDFs and a few photos.
  • Total files that will stay in the tens of gigabytes for the next one or two years.
  • The application runs on a single server and there is no plan to add more soon.
  • Rules or contracts that require data to stay on hardware owned by the company, for example an on-premise system in a factory or a hospital.
  • There is already a tested backup that copies the upload folder to another location, not only to the same server.

Even in these cases, write the code through a storage abstraction such as the Laravel Storage facade, django-storages, or a small storage interface of your own. The application then saves and reads files without knowing where they live, and moving to S3 or another provider later becomes a configuration change rather than a rewrite.

Problems That Appear as Photos and Videos Grow

  • The disk fills up quietly. Logs, the database, and uploads usually share the same partition, so a full disk stops much more than file uploads.
  • Backups get slow and expensive. A 300 GB upload folder takes hours to copy, and restoring it after a failure keeps the application offline just as long.
  • Videos use the bandwidth meant for the application. A VPS port of 100 Mbps or even 1 Gbps fills up quickly when dozens of users watch videos at the same time, and API responses start to slow down for everyone.
  • Application workers are tied up. If files go through PHP, Node.js, or Python instead of being served directly by Nginx, every download holds a worker for the whole transfer.
  • Adding a second server becomes complicated. Files uploaded to server A are not on server B unless you set up shared storage or syncing.
  • Security mistakes are easier to make. An upload folder inside the public web root that allows scripts to run is a classic way for an attacker to upload a web shell.

The Main Cloud Storage Options

Most of the services below support the S3 API, so the same SDK and tools work with all of them by changing the endpoint and credentials. The prices are list prices in US dollars as of November 2026 and do not include tax.

ServiceStorage priceDownload to the internetNotes
Amazon S3 (Jakarta)$0.025 per GB per month$0.132 per GB after the first 100 GB free each monthThe most complete feature set. Usually paired with CloudFront for delivery
Google Cloud Storage (Jakarta)$0.023 per GB per month (Standard)Billed per GB, with Indonesia in a more expensive price band than most of AsiaA natural choice if the application already runs on Google Cloud
Cloudflare R2$0.015 per GB per month, first 10 GB freeFreeRequest fees still apply: $4.50 per million writes and $0.36 per million reads
Bunny Storage$0.01 per GB per month for one region (HDD), $0.02 for SSDThrough Bunny CDN, $0.03 per GB in Asia on the standard networkNo API fees, a $1 monthly minimum, and a Singapore storage region close to Indonesia
Backblaze B2$6.95 per TB per monthFree up to 3 times the data stored, then $0.01 per GBLow storage price, a good fit for archives and backups
Wasabi$7.99 per TB per monthNo egress feeMinimum charge of 1 TB and a 90-day minimum storage period. Read the usage terms before serving heavy public traffic
DigitalOcean Spaces$5 per month includes 250 GiB, then $0.02 per GiB1 TiB included, then $0.01 per GiBSimple pricing and a built-in CDN
Indonesian providersVaries by providerDepends on the package and providerSeveral local cloud providers offer S3-compatible storage, useful when data must stay in Indonesia

Storage is rarely the expensive part. For photos and videos, the bill is driven by how many gigabytes users download every month. That is why the same 500 GB library can cost under $10 or over $250 a month depending on how it is delivered.

Example: 500 GB of Media and 2 TB of Downloads per Month

Take a marketplace or learning platform that stores 500 GB of photos and short videos, and whose users, mostly in Indonesia, download about 2,000 GB a month. The table shows storage and delivery only. Request fees are left out because they are small at this scale: ten million image views cost around $4 on S3 and fall inside the R2 free tier.

SetupStorageDeliveryEstimated total per month
Amazon S3 Jakarta, served directly$12.50$250.80about $263
Amazon S3 Jakarta + CloudFront pay-as-you-go$12.50$120.00 (first 1 TB free, then $0.12 per GB)about $133
Amazon S3 Jakarta + CloudFront Pro flat-rate plan$12.50$15.00 (includes 50 TB and 10 million requests)about $28
Bunny Storage + Bunny CDN standard network$5.00$60.00about $65
DigitalOcean Spaces$9.30 (including the $5 base fee)$8.40about $18
Backblaze B2$3.48$5.00about $8.50
Cloudflare R2$7.35$0about $7.35

A few things the table does not show. Serving straight from S3 without a CDN is the most expensive option and also the slowest for users far from Jakarta. CloudFront flat-rate plans have fixed allowances and feature limits, so check them against your traffic before relying on them. Bunny also offers a cheaper volume network at $0.005 per GB, but it has far fewer locations, so latency for users in Indonesia should be tested first. R2 and B2 look cheapest, yet their nearest storage location is not in Indonesia, which matters for upload speed and for data location rules.

Compare that with the server disk. A VPS with 500 GB of disk and a large bandwidth quota may cost less than any of the above on paper. The real cost shows up elsewhere: an extra server or volume for backups, the hours spent when the disk fills up, and the slower application while videos are streaming.

Photos and Videos Need More Than Storage

A 6 MB photo from a phone camera should not be sent as-is to a product listing page. Generate smaller sizes and modern formats such as WebP or AVIF, either once at upload time in a background job or on the fly through an image service. Bunny Optimizer costs $9.50 per website per month, Cloudflare and the major clouds have their own image services, and imgproxy is a popular self-hosted option.

Videos have the same issue on a larger scale. A raw MP4 uploaded from a phone is large and does not adapt to the viewer connection. Video platforms transcode it into HLS with several resolutions, so a user on a slow mobile network gets 480p instead of buffering. Bunny Stream does not charge for encoding and bills storage and delivery from $0.01 and $0.005 per GB. Cloudflare Stream bills per minute stored and delivered, and on AWS the usual path is MediaConvert with S3 and CloudFront. For an application where video is central, these services are usually cheaper than building and running your own transcoding servers.

Data Location and Regulations

Photos of faces, ID cards, and medical documents count as personal data under the Indonesian Personal Data Protection Law (UU PDP). Under PP 71/2019, private electronic system operators may generally store data outside Indonesia, but sector regulators such as OJK for finance can set stricter rules. If your data must stay in the country, use the Jakarta regions of AWS or Google Cloud, or a local provider. Whatever the location, keep buckets with personal data private and share files through short-lived signed URLs.

Moving from the Server Disk to Cloud Storage

  1. 1Make sure the application reads and writes files through a storage abstraction, and that the database stores relative paths or keys, not full URLs.
  2. 2Create the bucket, keep it private, and give the application credentials that can only access that bucket.
  3. 3Copy existing files with a tool such as rclone or the AWS CLI sync command, keeping the same folder structure as keys.
  4. 4Switch new uploads to the bucket, and for a short period let the application fall back to the local disk when a file is not found yet.
  5. 5Run a final sync, compare file counts and total size, then point downloads to the CDN.
  6. 6Keep the old folder for a few weeks as a safety net before deleting it to free the disk.

A useful rule of thumb: if your files fit comfortably on one disk and are mostly read by internal staff, the server disk with a proper offsite backup is fine. Once the files are mainly photos and videos for customers, cloud storage with a CDN almost always ends up cheaper and more reliable.

Key takeaways

  • The server disk is fine for small internal applications on one server, as long as uploads are backed up somewhere else.
  • For large photo and video libraries, cloud storage removes disk-full incidents, simplifies backups, and keeps file traffic away from the application server.
  • Download traffic, not storage, drives the bill. Always put a CDN in front, or choose a provider with free or cheap egress.
  • Process images into smaller sizes and videos into HLS, using services such as Bunny Optimizer, Bunny Stream, or Cloudflare Stream when video is central.
  • Write code through a storage abstraction from day one, so moving between disk and providers is a configuration change.
Share this article

Related articles

More articles on software development, AI, cloud, and infrastructure.

Close-up of a server front panel with rows of drive bays and green status lightsCloud & DevOps

11 min read

Bare Metal, VPS, or Cloud VM: When a Dedicated Server Is Worth It

A VPS and a cloud VM share physical hardware with other customers. A bare metal server is a whole machine of your own. How the three differ in performance, scaling, and who deals with failed hardware, a price comparison for a 64 GB server, the workloads where bare metal pays off, the extra work it brings, and why server prices rose in 2026.

A bright lightning bolt striking down from a dark blue storm cloudCloud & DevOps

11 min read

Serverless in Practice: AWS Lambda, Cloud Run, Cloudflare Workers, and When They Pay Off

Serverless means paying only for the time your code runs, with no servers to patch. It is a great fit for some workloads and an expensive one for others. How AWS Lambda works, its real limits, how it compares with Cloud Run, Azure Functions, and Cloudflare Workers, and a cost calculation using Jakarta region prices.

Let’s talk

Looking for a software development partner?

Tell us about your project, what you need to build, and the challenges you are facing. We can discuss the technical approach, scope, timeline, and estimated cost.

Start a conversation