Reducing Infrastructure Complexity: Why I Ditched S3+CloudFront+Lambda

Shivam Anand
Shivam Anand09 min readAug 24, 2025
Reducing Infrastructure Complexity: Why I Ditched S3+CloudFront+Lambda

For the past five years, AWS S3 has been my digital storage backbone. Whether I was building client projects, handling enterprise applications, or just storing personal files, S3 was always there—reliable, scalable, and practically indestructible. I've pushed terabytes through it, set up complex bucket policies, and even built entire content management systems on top of it.

But here's what I learned: sometimes "enterprise-grade" is overkill.

When I finally decided to migrate my blog from Medium to a custom setup powered by Strapi, I thought the hardest part would be content migration. Turns out, I was wrong. The real challenge was something I hadn't anticipated: media management hell.

The AWS S3 Reality Check

Let me paint you a picture of my typical S3 workflow before Cloudinary:

  1. Upload images to S3: (straightforward enough)

  2. Set up CloudFront distribution: for global CDN delivery

  3. Configure Lambda@Edge functions: for image resizing

  4. Write custom code: to handle different formats (WebP, AVIF)

  5. Set up additional buckets: for processed images

  6. Monitor costs: across multiple services

  7. Debug CORS issues: (because there are always CORS issues)

For a simple blog with maybe 50-100 images, this felt like using a sledgehammer to crack a nut. Sure, S3 could handle millions of files without breaking a sweat, but I just needed my hero images to load fast and look good on both desktop and mobile.

The breaking point came when I spent an entire Saturday debugging why my Lambda function wasn't properly generating thumbnails for portrait images. I remember sitting there at 2 AM, staring at CloudWatch logs, thinking: "There has to be a better way."

Enter Cloudinary: The Accidental Discovery

I discovered Cloudinary through pure frustration. A developer friend mentioned it casually in our team Slack: "Why don't you just use Cloudinary? It's basically S3 but for people who actually want to get stuff done."

I was skeptical. After years with AWS, switching felt like abandoning a reliable friend for an unknown quantity. But my Saturday debugging sessions were getting old, so I figured I'd give their free tier a shot.

The onboarding experience was... refreshingly simple. Create account, get API keys, done. No IAM policies, no bucket configurations, no region selection analysis. Just: here's your cloud, start uploading.

The "Holy Sh*t" Moments

URL-Based Transformations Changed Everything

The first time I saw Cloudinary's URL transformations in action, it felt like discovering fire. Want to resize an image to 400x300? Just add /w_400,h_300/ to the URL. Need it as WebP? Add /f_webp/. Want to blur the background and add a sepia filter? /e_blur:300,e_sepia/.

Here's what blew my mind: I uploaded one high-resolution image (let's say 4000x3000 pixels), and suddenly I had access to unlimited variations:

  • /w_300,h_200,c_fill/ - Perfect thumbnail

  • /w_800,h_600,q_auto,f_auto/ - Responsive web version

  • /w_150,h_150,c_thumb,g_face/ - Profile picture with face detection

  • /w_1200,c_scale,q_auto:eco/ - High-quality desktop version

No preprocessing. No storage of multiple versions. No Lambda functions. Just URLs.

Smart Optimization That Actually Works

I'm naturally suspicious of "smart" and "automatic" features—they usually mean "works 70% of the time, breaks spectacularly the other 30%." But Cloudinary's automatic optimization genuinely impressed me.

I ran some tests on my blog images:

  • Original JPEG: : 2.3MB

  • Cloudinary auto-optimized: : 340KB (85% reduction)

  • Visual difference: : Honestly? I couldn't tell.

The magic isn't just compression. Cloudinary analyzes the requesting device and browser, then serves the optimal format. Chrome users get WebP, Safari users get optimized JPEGs, and older browsers get whatever they can handle. It's like having a really smart content delivery network that actually understands images.

The Strapi Integration That Just Worked

Remember my S3 setup process? Hours of configuration, environment variables, and prayer. The Cloudinary-Strapi integration:

  1. Install the plugin: npm install @strapi/provider-upload-cloudinary

  2. Add three lines to your config file

  3. Upload images through the Strapi admin panel

  4. Images automatically go to Cloudinary with zero additional setup

That's it. No CORS configuration, no signed URLs, no access policies. Just upload and go.

Real-World Usage: What I Actually Do With It

Let me get specific about how Cloudinary changed my daily workflow:

Blog Post Featured Images

Before: Upload to S3, manually resize in Photoshop, create multiple versions for different screen sizes, and upload each version separately.

Now: Upload once to Strapi, let Cloudinary handle everything. My blog template automatically generates responsive image tags:

 

<picture>
  <source media="(min-width: 1200px)" srcset="https://res.cloudinary.com/myblog/w_1200,q_auto,f_auto/featured-image.jpg">
  <source media="(min-width: 768px)" srcset="https://res.cloudinary.com/myblog/w_800,q_auto,f_auto/featured-image.jpg">
  <img src="https://res.cloudinary.com/myblog/w_400,q_auto,f_auto/featured-image.jpg" alt="Featured image">
</picture>

Image Galleries

My travel posts often include 20-30 images. With S3, I'd spend hours optimizing each one. Now I upload the full-resolution versions and let Cloudinary generate thumbnails on-demand:

  • Gallery thumbnails: /w_300,h_300,c_fill,q_auto/

  • Lightbox images: /w_1400,h_1000,c_limit,q_auto/

  • Loading placeholders: /w_50,h_50,e_blur:2000,q_auto/

Video Content

Here's where Cloudinary really shines beyond images. I occasionally include short video clips in my posts. Previously, this meant:

  1. Export multiple formats (MP4, WebM)

  2. Generate thumbnail images manually

  3. Set up complex video delivery through CloudFront

  4. Handle adaptive bitrate streaming if needed

With Cloudinary, I upload one video file and get:

  • Automatic format optimization

  • Generated thumbnails at any timestamp

  • Adaptive streaming without configuration

  • Video compression that maintains quality

Performance Impact: The Numbers

I'm a data nerd, so I tracked the performance impact of switching to Cloudinary:

Before (S3 + CloudFront):: 

  • Average page load time: 3.2 seconds

  • Lighthouse Performance Score: 76

  • Total image weight per page: ~2.1MB

  • Time spent on media optimization: 3-4 hours per blog post

After (Cloudinary):: 

  • Average page load time: 1.8 seconds

  • Lighthouse Performance Score: 94

  • Total image weight per page: ~650KB

  • Time spent on media optimization: Maybe 5 minutes

The difference isn't just in numbers—my pages feel noticeably snappier. The combination of smart optimization and global CDN delivery creates a genuinely better user experience.

Beyond the Basics: Advanced Features That Surprised Me

AI-Powered Auto-Tagging

Cloudinary automatically tags uploaded images with relevant keywords. It identified "mountain," "sunset," and "hiking" in my travel photos without any input from me. While I don't rely on this for my blog's taxonomy, it's incredibly useful for content discovery.

Background Removal

Need to remove backgrounds from product images or profile photos? Cloudinary does it automatically with /e_background_removal/. It's not perfect, but it's often good enough to skip Photoshop entirely.

Face Detection and Smart Cropping

The /c_thumb,g_face/ parameter automatically detects faces and crops thumbnails to keep them centered. Perfect for author bios or team pages where you need consistent headshots from various source images.

Advanced Video Features

  • Auto-generated subtitles: for accessibility

  • Video thumbnails: at specific timestamps

  • Animated GIF generation: from video segments

  • Quality analysis: to identify and fix compression artifacts

Transformation Chaining

You can chain multiple transformations in a single URL:
/w_800,h_600,c_fill,g_auto,e_improve,e_sharpen:100,f_auto,q_auto/

This single URL crops to 800x600, auto-focuses on the most interesting area, improves the image quality, adds sharpening, and delivers in the optimal format. It's like having a professional photo editor built into your URLs.

The Developer Experience

Coming from AWS, I was prepared for extensive documentation, complex APIs, and a steep learning curve. Cloudinary surprised me with its developer-friendly approach:

API Design

The REST API is intuitive and well-documented. Upload endpoints that actually make sense:


        // Upload with transformation
            const result = await cloudinary.uploader.upload("local-image.jpg", {
            width: 500,
            height: 500,
            crop: "fill",
            quality: "auto",
            format: "auto"
            });
        

 

SDKs That Don't Suck

I've used AWS SDKs extensively, and while powerful, they often feel like they were designed by committee. Cloudinary's JavaScript SDK is clean, well-typed (if you're using TypeScript), and genuinely pleasant to work with.

Upload Widgets

For client-side uploads, Cloudinary provides embeddable widgets that handle everything from drag-and-drop to progress indicators. Compare this to building your own S3 upload interface with presigned URLs and CORS configurations.

Cost Reality Check

Let's talk money, because this always matters for side projects and small businesses.

My Usage Pattern

  • Monthly uploads: ~50 images, 5-10 videos

  • Monthly bandwidth: ~15GB

  • Storage: ~8GB total

AWS S3 + CloudFront + Lambda@Edge costs:: 

  • S3 storage: ~$2/month

  • CloudFront data transfer: ~$8/month

  • Lambda@Edge executions: ~$3/month

  • Total: ~$13/month: 

Cloudinary costs:: 

  • Free tier covers: 25GB storage, 25GB bandwidth, 25,000 transformations

  • My usage: Well within free tier limits

  • Total: $0/month: 

For heavier usage, Cloudinary's paid plans start at $89/month, which includes 100GB storage and 100GB bandwidth. That might seem steep compared to AWS, but consider what you're getting:

  • No Lambda function costs

  • No CloudFront configuration

  • No image processing server maintenance

  • Built-in optimization and CDN

  • Advanced AI features included

The Hidden Costs of AWS

What AWS pricing doesn't show:

  • Development time: : Setting up and maintaining image processing pipelines

  • Debugging time: : Lambda function issues, CORS problems, CloudFront cache invalidation

  • Monitoring costs: : CloudWatch logs and metrics

  • Complexity tax: : The mental overhead of managing multiple services

When I factor in the 10-15 hours per month I was spending on media-related infrastructure issues, Cloudinary's pricing starts to look very reasonable.

What Could Be Better

I don't want to sound like a Cloudinary evangelist—no service is perfect, and there are legitimate reasons to stick with AWS:

Vendor Lock-in Concerns

With S3, your images are just files in a bucket. Easy to migrate, easy to backup, easy to access directly. With Cloudinary, you're more tied to their platform. While they provide APIs for bulk download and migration tools, it's not as straightforward as aws s3 sync.

Advanced Control

AWS gives you granular control over every aspect of your infrastructure. Want custom caching rules? Custom image processing algorithms? Specific geographic restrictions? AWS makes this possible (though not easy).

Cloudinary is more opinionated. Their algorithms are generally excellent, but if you need something very specific, you might be out of luck.

Enterprise Integration

If you're already deep in the AWS ecosystem with VPCs, custom IAM policies, and complex compliance requirements, Cloudinary might introduce unwanted complexity rather than reducing it.

Pricing at Scale

For very high-traffic applications, AWS's pay-for-what-you-use model can be more economical than Cloudinary's tier-based pricing. Though at that scale, you probably have a dedicated DevOps team anyway.

The Decision Framework

So when does it make sense to choose Cloudinary over S3? Based on my experience:

Choose Cloudinary if:: 

  • You're building content-heavy websites (blogs, portfolios, e-commerce)

  • You want to focus on content, not infrastructure

  • Your team is small and time is valuable

  • You need advanced image/video processing without the complexity

  • You're starting fresh (no existing S3 infrastructure)

Stick with AWS if:: 

  • You're already heavily invested in the AWS ecosystem

  • You need very specific image processing requirements

  • You have enterprise compliance requirements

  • Your traffic patterns are highly unpredictable

  • You have dedicated DevOps resources

Six Months Later: No Regrets

It's been six months since I made the switch, and I haven't looked back. My Saturday debugging sessions are a thing of the past. When I want to add an image to a blog post, I just upload it and move on.

The time savings have been dramatic. What used to be a half-day project (writing a post + handling media) is now genuinely a 2-hour task. I spend my weekends writing instead of wrestling with Lambda functions.

More importantly, my blog's performance improved across the board. Faster loading times mean better user experience, which means people actually read what I write. Isn't that the whole point?

Give It a Shot

If you're dealing with image-heavy projects and finding AWS more frustrating than helpful, try Cloudinary's free tier. Upload some images, play with the URL transformations, and see how it feels.

You might find, like I did, that sometimes the best solution isn't the most powerful one—it's the one that gets out of your way and lets you focus on what actually matters.

Because at the end of the day, nobody visits your blog to admire your Lambda functions. They come for your content. Make sure that's where you're spending your energy.