All projects

CDN and media delivery

A media store that uses Telegram (MTProto) as its storage backend.

JavaScriptVueEdge delivery
webedge-cdn screenshotDev-story
01

Challenge

We wanted somewhere to keep and serve product media without paying for object storage or a CDN per project.

02

What we did

A backend that uploads files to Telegram over the MTProto protocol (using it as free storage) and a Vue admin to organise and hand out the media; delivery is fronted so files load quickly.

03

Result

Media lives on Telegram's infrastructure at no storage cost, and apps get and manage files through one admin instead of a paid bucket.

Dev-story article

CDN and media delivery: how the project was built

Telegram will hold unlimited files for free, but it is not a CDN: it throttles with FLOOD_WAIT, has no public serving model, and knows nothing about browser CORS or caching. The tension of this project was turning a chat backend into something a real frontend can hammer with 400+ image requests per page without getting the account rate-limited or leaking one user's files to another. Most of the work is the edge that sits in front of MTProto, not the storage itself.

Sections

05

Modules

05

Stack

JavaScript + Vue

01

Why the project exists

We wanted somewhere to keep and serve product media without paying for object storage or a CDN per project.

Telegram will hold unlimited files for free, but it is not a CDN: it throttles with FLOOD_WAIT, has no public serving model, and knows nothing about browser CORS or caching. The tension of this project was turning a chat backend into something a real frontend can hammer with 400+ image requests per page without getting the account rate-limited or leaking one user's files to another. Most of the work is the edge that sits in front of MTProto, not the storage itself.

02

What was built

A backend that uploads files to Telegram over the MTProto protocol (using it as free storage) and a Vue admin to organise and hand out the media; delivery is fronted so files load quickly.

A media store where uploads land in a Telegram account's Saved Messages and each file is served back through a public URL. A Node service on uWebSockets.js talks MTProto via gramjs, streams file bytes, and extracts thumbnails; an Nginx layer caches almost every response so Telegram is hit rarely; and a Vue dashboard manages folders, search, move, trash, and per-project API keys. It runs on two VPS nodes behind HAProxy.

03

Main modules and user path

M01

MTProto storage adapter (gramjs on uWebSockets.js) that uploads to Saved Messages, streams file bytes back, and forwards messages between folders for move/search — including a hand-patched mime.getExtension so downloads resolve the right file extension

M02

Nginx caching edge keyed on Origin plus a Vary: Origin header, after CORS-less <img> responses were being cached and then wrongly served to fetch() calls that needed CORS headers

M03

Auth and abuse protection: phone-number whitelist on code sending, 3 codes per 10 minutes to avoid triggering Telegram FLOOD_WAIT on the account, exponential backoff on wrong passwords, and per-IP rate limits that were tuned up to 300 r/m burst 100 for image-heavy pages

M04

Public no-auth thumbnail endpoints (/thumb, /vthumb) because <img src> can't send a Bearer token — video frames pulled with ffmpeg and cached as jpg

M05

Two-node HAProxy setup with a stick-table pinning each client to one backend, because dashboard tokens live in an in-memory Map per node while public file serving stays stateless on both

04

Architecture and technology decisions

Built with JavaScript, Vue, Edge delivery.

Node on uWebSockets.js speaking MTProto through gramjs, fronted by Nginx for caching and security headers and HAProxy for two-node round-robin with sticky sessions; the frontend is Vue with a small IndexedDB-backed folder store and a hand-rolled stale-while-revalidate query cache instead of pulling in TanStack Query.

05

Result and lessons

Media lives on Telegram's infrastructure at no storage cost, and apps get and manage files through one admin instead of a paid bucket.

A working, self-hosted media CDN backed by free Telegram storage, hardened through a long tail of real CORS, caching, and auth bugs; honestly a two-node prototype rather than a fleet, but one that serves an app-scale image library without a storage bill.

Read next

These projects share nearby technical or product decisions, so they show how the same principle behaves in another context.

Have a similar idea?

Discuss your project