Case study · Preview on demand
Imago
An on-demand image CDN on AWS: one original upload, served at any preset size and format from the edge. After the first request S3 serves each variant; Lambda only runs to create a new one.
- Role
- Personal
- Status
- Preview on demand
Problem
Pages that show hundreds of images need each one in several sizes and formats. Generating every variant up front wastes storage, and resizing on every request is slow and expensive. The CDN has to create a variant once, serve it from the edge after that, and survive a flood of requests for random sizes.
Approach
- 01
Normalize at the edge. A CloudFront Function snaps the width to one of eight presets (100 to 2000 px), picks webp, avif, jpeg or png from the query or the Accept header, rejects bad paths, and rewrites the URL to the variant's key, such as /images/photo.jpg/800.webp. That path is the whole cache key.
- 02
Cache in layers. CloudFront edge cache, then Origin Shield in Singapore, then the variants bucket in S3.
- 03
S3 first, Lambda on failover. A CloudFront origin group reads the variant from S3 through Origin Access Control. Only when it does not exist yet (S3 answers 403) does CloudFront fail over to a Lambda Function URL that accepts only CloudFront-signed requests (OAC, AWS_IAM). Lambda resizes the original with Sharp, saves the variant under the same key and returns it, so each size and format is generated once.
- 04
Bounded cost. Each image has at most 32 variants (8 widths, 4 formats), so requests for random sizes cannot make Lambda generate an unlimited number of files. AWS WAF blocks any IP that sends more than 500 requests in 5 minutes, and an optional reserved concurrency caps how many Lambda instances run at once.
- 05
Infrastructure as code. Three CDK stacks. Originals live in their own stack in ap-southeast-1 and survive teardown; the certificate and WAF must be in us-east-1 and reach the CDN stack through cross-region references, with no hard-coded ARNs or URLs.
Request flow
Result
Every size and format of an image is generated once, then served from the edge cache, Origin Shield or S3. Lambda runs only for a variant that does not exist yet, each image has at most 32 variants, and with no VPC or always-on compute nothing runs between requests.
- AWS CDK
- TypeScript
- CloudFront
- Lambda
- Sharp
- S3
- WAF