Presigned Uploads: Direct-to-CDN Performance

When you upload a photo to your Jottings site, something interesting happens behind the scenes. Your browser doesn't send that image to my servers. Instead, it goes directly to Cloudflare R2 (Cloudflare's S3-compatible object storage) using a presigned URL I generate for you.

Most web applications handle uploads the traditional way: you submit a form, the file travels to their server, gets processed, and then gets stored somewhere. It's straightforward but inefficient. Every upload ties up server resources, eats bandwidth, and creates a bottleneck.

I built Jottings to avoid all of that.

What Are Presigned URLs?

A presigned URL is a special link that grants temporary upload permission to a specific bucket. Think of it like giving someone a house key that automatically stops working in one hour. You don't need to hand them a physical key (your server) and supervise them; they just use the temporary credential to get in and do their thing.

Here's how the upload flow works in Jottings:

  1. You click "Add Photo" in the editor
  2. Your browser asks my API: "Can I upload this file?"
  3. My API generates a presigned URL valid for 15 minutes
  4. Your browser uploads directly to R2 using that URL
  5. You confirm the upload, and it gets embedded in your jot
  6. The temporary credential expires

This takes maybe 200ms of API work total. After that, your upload is streaming directly to Cloudflare's global network without touching my servers.

Why This Matters for Performance

Traditional server-based uploads create a cascading bottleneck. If you're uploading a 5MB photo, here's what typically happens:

  • Your photo travels to the web server (network I/O)
  • The server stores it in temporary memory or disk
  • The server processes/resizes it (CPU)
  • The server uploads it to cloud storage (network I/O again)
  • The server updates the database to record the upload

That's a lot of work for a single resource-constrained server. Now multiply that by hundreds of users uploading simultaneously.

Presigned uploads cut out all the middlemen. Your photo goes directly from your device to R2's edge-optimized infrastructure. Cloudflare routes the upload to whichever data center is geographically closest to you, minimizing latency. My server never sees the raw file bytes.

The performance difference is dramatic. Uploads that might take 20-30 seconds through a traditional server take 2-5 seconds directly to R2. Users with slower connections still get reasonable upload times because they're uploading to geographically close infrastructure.

Security Without Complexity

People sometimes worry about presigned URLs: "Isn't that a security risk?" Not really, and here's why:

Temporal Limitation: Presigned URLs expire. I set Jottings uploads to expire in 15 minutes. After that, the URL is worthless. Even if someone gets the URL, they have a narrow window to use it.

Scope Restriction: A presigned URL can't be used for arbitrary operations. It's limited to a specific bucket, a specific path pattern, and a specific action (PUT for uploads). It can't delete files, modify settings, or access other buckets.

Intent Verification: Only authenticated users of Jottings can request a presigned URL. The API validates your JWT token before generating one. Random internet users can't just call my upload endpoint and get a URL.

Storage Isolation: All Jottings uploads go into a single, isolated R2 bucket. The presigned URL can't escape that bucket or write to other data. Filenames include a timestamp and your site's subdomain, preventing overwrites.

Audit Trail: Every presigned URL generation is logged. If something suspicious happened, I can trace it back to see which user requested it.

Cloudflare's R2 presigned URLs are cryptographically signed, so users can't tamper with them. It's security through constraints, not complexity.

The Architecture in Practice

Here's the complete flow with some real details:

When you request an upload URL from my API, it runs this logic:

1. Validate JWT (is this a real Jottings user?)
2. Check rate limits (are you uploading too frequently?)
3. Verify file metadata (is this a supported image format?)
4. Generate unique storage key: sites/{subdomain}/{timestamp}_{uuid}_{filename}
5. Create presigned URL for that specific key, valid for 15 minutes
6. Return URL to your browser
7. Log the request

Your browser then uploads directly to R2 using that URL. Once uploaded, the file is available on the CDN at https://static.jottings.me/{path}.

When you confirm the upload in my editor, I verify the file actually exists in R2 using a HEAD request (no data transfer, just checking). Then I embed the full media object into your jot with the CDN URL, file size, MIME type, and other metadata.

What This Means for You

As a Jottings user, you get:

  • Fast uploads: Direct to CDN, typically 2-5 seconds for most photos
  • No storage limits: Uploads don't compete with server resources
  • Reliable delivery: Your photos are served from Cloudflare's 300+ data centers worldwide
  • Bandwidth efficiency: Downloads use CDN bandwidth, not my server's
  • Cost efficiency: I pay Cloudflare's bandwidth rates, not egregious S3 bills

As someone building Jottings, I get:

  • Simplified architecture: No image processing servers, no queue workers
  • Predictable costs: Bandwidth scales with usage but doesn't spike from server load
  • Better resilience: An upload spike doesn't crash anything; it just goes to R2
  • Minimal maintenance: Cloudflare handles durability, replication, and edge delivery

The Serverless Philosophy

This is what serverless infrastructure is really about. Not "no servers" (obviously they exist), but rather delegating work to specialized services that are purpose-built and globally distributed.

Your uploads don't need a general-purpose compute server. They need a geographically distributed storage system with a CDN. Presigned uploads let you use exactly that, nothing more.

It's the same reason Jottings uses Lambda for backend logic (handles spiky traffic well), DynamoDB for storage (auto-scales, no schema headaches), and SQS for async jobs (reliable, cheap queueing). Each piece is chosen for its specific strength.


Building Jottings means obsessing over these details so you don't have to think about them. Upload a photo, and it just works. Fast, secure, reliable.

If you're building something that needs simple photo uploads and global reach, Jottings might be exactly what you're looking for. Create your site today—it takes about 30 seconds to get started.