I quit paying for cloud storage. Here's what I did instead.
Last month, my S3 bill hit $47 for what was basically a bunch of project assets and backups. Not catastrophic, but annoying enough to make me think: where can I store files for free, permanently, with no limits?
The answer was staring at me from my taskbar: Telegram.
Telegram stores unlimited files (up to 2GB each) for free. Forever. No storage quotas, no egress fees, no "your free tier expires in 30 days" emails. I just needed a way to use it like a normal storage service.
So I built TG-S3 — a fully S3-compatible object storage backend that uses Telegram as its storage layer, runs on Cloudflare Workers, and costs exactly $0.
The Idea in 30 Seconds
Your app ──▶ S3 API ──▶ Cloudflare Worker ──▶ Telegram
│
D1 (metadata)
R2 (cache)
You point any S3 client — aws-cli, rclone, your favorite SDK — at a Cloudflare Worker URL. The worker handles authentication, stores metadata in Cloudflare D1, and persists the actual files as Telegram messages. Reads go through a three-tier cache so you're not hammering the Telegram API on every request.
That's it. Free storage. Standard API. Zero servers to manage.
Why Telegram Actually Works as a Storage Backend
I know what you're thinking: "This is cursed." Maybe. But consider:
Telegram has no storage limits. You can upload unlimited files to a group/channel. They've never deleted old content or imposed retroactive quotas.
Files persist indefinitely. Messages in Telegram groups don't expire. I have files from 2017 that are still downloadable.
The Bot API is solid. File upload/download is well-documented, rate limits are generous, and the API is reliable.
The file size limit is 2GB (with Local Bot API). That covers 99% of use cases.
The tradeoff? Latency on cache misses. Which brings us to...
The Three-Tier Cache That Makes It Fast
Raw Telegram API calls are slow (~500ms-2s per file). Nobody wants that for hot files. TG-S3 solves this with three caching layers:
| Layer | Backend | Speed | Cost |
|---|---|---|---|
| L1 | Cloudflare CDN (Cache API) | ~5ms | Free |
| L2 | Cloudflare R2 | ~20ms | Free (10GB) |
| L3 | Telegram API | ~500ms+ | Free |
First read: File comes from Telegram (~1s), gets cached in R2 and CF CDN.
Second read: Served from CDN edge in ~5ms. That's faster than most S3 setups.
For write-heavy workloads, files go to Telegram first (source of truth), then propagate to cache asynchronously. Cache invalidation is automatic on delete/overwrite.
Real S3 Compatibility — Not a Toy
This isn't a "it kinda works with GET and PUT" situation. TG-S3 implements 21 S3 operations:
- Object CRUD: GetObject, PutObject, HeadObject, DeleteObject, DeleteObjects, CopyObject
- Listing: ListObjectsV2, ListObjects (v1)
- Multipart Upload: CreateMultipartUpload, UploadPart, UploadPartCopy, CompleteMultipartUpload, AbortMultipartUpload, ListParts, ListMultipartUploads
- Buckets: ListBuckets, CreateBucket, DeleteBucket, HeadBucket, GetBucketLocation
- Auth: Full AWS SigV4 signature verification, presigned URLs, Bearer tokens
This means standard tools Just Work:
# Upload a file
aws --endpoint-url https://tgs3.example.com s3 cp backup.tar.gz s3://mybucket/
# List files
aws --endpoint-url https://tgs3.example.com s3 ls s3://mybucket/
# Generate a presigned URL (share a file for 1 hour)
aws --endpoint-url https://tgs3.example.com s3 presign s3://mybucket/backup.tar.gz --expires-in 3600
# Sync an entire directory
rclone sync ./photos tgs3:mybucket/photos/
I've tested this with aws-cli, rclone, s3cmd, the AWS SDK for Python (boto3), and the AWS SDK for JavaScript. All work without patches.
Beyond S3: The Telegram-Native Features
Since Telegram is the backend, you get some features that regular S3 doesn't have:
Telegram Bot Interface
Send a file to your bot — it's instantly stored. Use commands to browse, search, and manage:
/ls mybucket photos/ → List objects
/search vacation → Full-text search
/share mybucket photo.jpg → Create a share link
/stats → Storage statistics
Mini App (Web UI inside Telegram)
A full file browser, upload interface, and sharing manager — all inside Telegram. No external web app needed. Supports English, Chinese, Japanese, and French.
Password-Protected Sharing
Create share links with passwords, expiry dates, and download limits. The shared file gets an inline preview page — images render in-browser, videos play inline.
Media Processing (Optional)
With an optional VPS proxy, you get:
- Image format conversion (HEIC → JPEG, WebP → PNG)
- Video transcoding
- Live Photo extraction
- Large file support up to 2GB
Deploy in 5 Minutes
The whole thing runs on Cloudflare's free tier. Here's the setup:
# Clone
git clone https://github.com/gps949/tg-s3.git
cd tg-s3
# Configure
cp .env.example .env
# Edit .env: add your Telegram bot token, chat ID, and CF API token
# Deploy
./deploy.sh
The deploy script handles everything — creates the D1 database, deploys the Worker, sets up the webhook. If Docker is available, it can also set up the VPS proxy with Cloudflare Tunnel (no public ports exposed).
Prerequisites:
- Node.js 22+
- A Telegram bot (create one via @BotFather)
- A Telegram group (the "storage drive")
- A Cloudflare account (free tier works)
S3 credentials are managed through the Telegram Mini App — open it, go to the Keys tab, generate a key pair.
The Architecture Under the Hood
S3 Client ─────┐
│
Telegram Bot ───┤
├──▶ Cloudflare Worker ──▶ D1 (metadata)
Mini App ───────┤ │ R2 (cache)
│ │
Share Links ────┘ ▼
Telegram API ◀──▶ VPS Proxy (optional, >20MB)
| Component | Role | Cost |
|---|---|---|
| CF Worker | API gateway, bot handler, mini app | Free |
| CF D1 | Object/bucket metadata (SQLite) | Free |
| CF R2 | Read cache for files ≤20MB | Free (10GB) |
| Telegram | Permanent file storage | Free |
| VPS + Proxy | Large files, media processing | ~$4/mo (optional) |
Everything is TypeScript, strict mode, zero runtime dependencies. The Worker handles S3 request routing, SigV4 authentication, and translates operations to Telegram Bot API calls.
What's Not Supported (By Design)
TG-S3 doesn't try to be a full S3 replacement. These features are intentionally omitted:
- Versioning — Telegram messages are immutable; versioning would add complexity with little benefit
- Server-side encryption — Files are already encrypted in transit; at-rest encryption is on the roadmap
- Lifecycle policies — No automatic deletion/transition (Telegram storage is free, so why?)
- ACLs — Uses its own multi-credential permission system instead
- Cross-region replication — Telegram and CF handle distribution
What's Next
The project is actively developed. Coming soon:
- Telegram Stars payments — Pay-per-use storage tiers via Telegram's built-in payment system
- Managed hosting — A hosted version so you don't even need a Cloudflare account
- End-to-end encryption — Client-side encryption before files reach Telegram
- Web Crypto API — Zero-dependency encryption in the Worker runtime
Should You Use This in Production?
For backups, personal file storage, asset hosting, and side projects? Absolutely. The three-tier cache makes reads fast, and Telegram's reliability is proven.
For mission-critical enterprise workloads? Probably not (yet). You're depending on Telegram's Bot API availability and their continued goodwill toward unlimited storage.
But for the price of $0 and 5 minutes of setup, it's hard to argue with.
Built with TypeScript, Cloudflare Workers, and a healthy disrespect for cloud storage pricing.
Top comments (0)