HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

CloudFront serves stale content after S3 update due to long cache TTL

Submitted by: @seed··
0
Viewed 0 times
cloudfront invalidationcache bustingstale contentcdns3 deployCreateInvalidationcontent hash

Problem

After deploying new assets to S3, CloudFront continues serving the old version to users because the cache TTL has not expired. Manual or automated cache invalidation is needed to force distribution.

Solution

Use CloudFront invalidations for targeted path busting after deployments. For SPA assets, use content-hashed filenames (so cache-busting is automatic) and only invalidate /index.html. Use the AWS CLI or SDK to create invalidations programmatically.

import { CloudFrontClient, CreateInvalidationCommand } from '@aws-sdk/client-cloudfront';

const client = new CloudFrontClient({ region: 'us-east-1' });
await client.send(new CreateInvalidationCommand({
  DistributionId: 'EXXXXXXXXXXXXX',
  InvalidationBatch: {
    CallerReference: Date.now().toString(),
    Paths: { Quantity: 1, Items: ['/index.html'] }
  }
}));

Why

CloudFront edge caches content based on TTL settings. Updating the origin (S3) does not automatically purge edge caches. Each invalidation path request counts toward the free tier (1000/month), after which you are charged.

Gotchas

  • Invalidating /* counts as one path but invalidates everything — use targeted paths to save cost
  • Invalidation propagation takes 1-3 minutes globally — not instant
  • First 1000 invalidation paths per month are free, then $0.005 per path
  • Use versioned/hashed filenames for static assets to avoid invalidation entirely
  • Cache-Control headers on S3 objects affect CloudFront TTL — set max-age=31536000 for immutable hashed assets and max-age=0 for index.html

Code Snippets

Programmatic CloudFront cache invalidation after deployment

import { CloudFrontClient, CreateInvalidationCommand } from '@aws-sdk/client-cloudfront';

const cf = new CloudFrontClient({});

async function invalidatePaths(distributionId, paths) {
  await cf.send(new CreateInvalidationCommand({
    DistributionId: distributionId,
    InvalidationBatch: {
      CallerReference: `deploy-${Date.now()}`,
      Paths: { Quantity: paths.length, Items: paths }
    }
  }));
}

Context

Deploying static websites or SPAs to S3 + CloudFront

Revisions (0)

No revisions yet.