Hosting Autopsy / The image that cost a month's hosting

The image that cost a month's hosting

HOSTING AUTOPSY

6 min read · 1,352 words

This is a composite case written by the editors. It is built from patterns that come up often in support work and is not the account of a particular named person or company.

A photographer on a pay-by-usage cloud plan published a picture that was picked up by a popular forum. People embedded it directly in their posts instead of saving a copy, so every view of the forum thread loaded the picture from her server. She did not know any of this was happening, because nothing on her own site looked different.

Her usual monthly bandwidth was a few gigabytes. That month it was several hundred. The invoice came as a surprise, and the explanation was a single large file.

She turned on hotlink protection, compressed the image, and set spending alerts on the account. This is a composite of cases we have seen, with the numbers rounded and illustrative, but the mechanics are accurate and the same thing happens to blogs, small shops and community sites every year.

What hotlinking is

A web page does not contain its pictures. It contains instructions: an img tag with an address, and the browser goes and fetches whatever that address points to. Nothing in the web stops that address belonging to a different site from the page. If you write a forum post with <img src="https://photos.example.com/storm.jpg">, every reader's browser fetches the picture from photos.example.com, not from the forum.

That is hotlinking, and for the person who posts it, it is convenient: no upload, no storage. For the owner of the picture it means that somebody else's audience is being served from their bandwidth allowance. The forum pays nothing. The photographer pays for every view.

ReaderForumpage text onlyPhotographerlarge image1. page2. imageBill arrives here
The reader's browser takes the page from the forum and the image from the photographer, who carries the cost.

How one file became several hundred gigabytes

The picture was a storm photograph taken on a good camera and uploaded as it came out of it: about seven megabytes, thousands of pixels wide. For her own portfolio page that was untidy but harmless. A few visitors a day, a few gigabytes a month.

Then a forum with a very large audience picked it up. The thread ran for days. The arithmetic is unforgiving, and these figures are illustrative:

ItemIllustrative figure
Image size as published7 MB
Thread views over the month45,000
Traffic from that one fileabout 315 GB
Normal monthly trafficabout 5 GB
Same image compressed to 400 KBabout 18 GB

Browsers cache images, so repeat views by the same person do not always re-download. But each forum member opens each thread on their own browser, and forums often show a thread to many people who each load it afresh. The total comes out close to size times audience.

Why it showed up as a bill and not an outage

On a fixed hosting plan, an event like this often ends in a suspension notice or a throttled account. On a pay-by-usage cloud plan, nothing stops. The platform serves every request and meters it. That is the contract: you never run out, and you pay for whatever you use.

So the site stayed up, her pages loaded and nobody complained. The first signal was the invoice at the end of the month. By then the traffic spike had passed and most of the damage was done. She only understood it after support pulled the access log and showed her one line repeating tens of thousands of times.

Finding the cause in the logs

The access log tells you which file is being requested and where the request came from. The Referer header, which browsers send, names the page that triggered the image request. On a typical Apache or nginx server in combined log format, this shows the biggest files by bytes served:

awk '{b[$7]+=$10} END {for (u in b) print b[u], u}' access.log | sort -rn | head

And this shows which pages are embedding the image:

grep "storm.jpg" access.log | awk -F'"' '{print $4}' | sort | uniq -c | sort -rn | head

The second list was long and dominated by one forum's thread address. The photographer's own pages barely appeared. That is the signature of hotlinking: many requests for one file, with a referer from a domain that is not yours.

One more detail from the logs: the requests came from thousands of different visitor addresses, spread across the world, so there was no single abuser to block. Blocking by IP address would have been hopeless. Only the referer pointed to the cause, which is why it pays to log it. If your server is configured with a custom log format that leaves it out, add it back.

The fix

She did three things, and each addresses a different part of the problem.

Hotlink protection. The web server checks the referer and refuses image requests that come from other sites. On Apache with mod_rewrite, a rule looks like this:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC]
RewriteRule \.(jpe?g|png|gif|webp)$ - [F,NC]

This returns 403 to outside referers and allows blank referers, which some privacy tools send. Many panels offer the same as a checkbox. It is a courtesy barrier, not security, since a referer can be faked, but it stops the casual embedding that causes bills like this. Some people replace the blocked image with a small placeholder, which tells the forum readers where to find the original.

Compression. A web photograph rarely needs to exceed 200 to 500 KB. Resizing to the display width and exporting at a moderate quality setting, or as WebP or AVIF, cut the file by more than ninety percent without a visible change at screen size. The page weight tool shows how much a page costs per visit.

Spending alerts. Her provider could notify her when the month's charges passed set amounts. She chose three levels and added a hard cap on one non-critical project.

Bandwidth from the thread, illustrativeOriginal 7 MBCompressed 400 KBabout 18 GBHotlink blockednear zero (small 403 replies)about 315 GB
The same audience costs very different amounts depending on what is served to them.

The month after

The provider reduced nothing: the traffic had been delivered and metered, and the terms were clear on that. The photographer paid most of the invoice, then spent an evening finding out what else on her account could behave the same way. A gallery page held forty full-size originals. A downloadable portfolio PDF was sixty megabytes. Neither had attracted any attention, but either could have.

She resized the gallery images to the widths they are actually displayed at, and replaced the PDF with a lighter version plus a request form for the full one. Her monthly figure settled back to a few gigabytes, and the dashboard now has a bandwidth graph she looks at on the first of each month.

The forum thread, for what it is worth, now shows the placeholder image. Several readers found her portfolio through it, which is the only good part of the story. Hotlinking is an unwelcome way to be discovered, but the clicks came through.

Loose ends

Is hotlinking illegal?

That depends on the country and the circumstances, and it is not a question for a hosting article. Practically, it is often more effective to block it than to argue about it.

Will blocking hotlinks hurt my search ranking?

Search engines and image search crawlers fetch images with their own referers, or none. Allowing blank referers and your own domain normally leaves them unaffected, but test any rule against the crawlers you care about.

Would a CDN have helped?

It can reduce load on the origin through caching, but you may pay for CDN traffic as well. The cost is still driven by file size and audience, so compression comes first.

Should the alert be a cap?

A cap stops the bill, but it can also stop the site. Alerts for the main site and a cap for anything that can safely go offline is a common arrangement.

What would have caught it

PreviousThe plugin that emailed every order to someone who had leftNextThe autoscaler that scaled to meet the bots

More from Hosting Autopsy

Autopsy

The launch-day database that ran out of connections

A local theatre put tickets for its autumn season on sale at noon and announced it on social media a day...

Autopsy

The migration that forgot the cron jobs

A small publishing company moved to a new host over a weekend. The work was done carefully: files copied...

Autopsy

The wildcard certificate renewal that broke the mail server

An organisation used one wildcard certificate for its website and also installed the same files on its mail...