Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nextjs-dynamodb-cache

Drop-in Next.js CacheHandler that stores ISR cache and tag-based revalidation in DynamoDB.

Built for Next.js deployments on AWS Amplify, Lambda, App Runner, ECS, or anywhere your filesystem is ephemeral — so your ISR cache and revalidateTag() calls actually survive deploys and work across instances.

npm install nextjs-dynamodb-cache

Why

The default Next.js cache handler writes to disk. On Amplify/Lambda/Fargate that means:

  • ISR pages re-render from scratch after every deploy
  • revalidateTag() only invalidates the instance that received the call
  • Multiple instances serve inconsistent stale content

This package replaces the filesystem cache with DynamoDB. Cache entries are shared across all instances and survive deploys. Tag revalidation uses a GSI so it's a single query, not a full-table scan.

Quick start

1. Create the DynamoDB table

npx nextjs-dynamodb-cache-create-table --table my-app-cache --region eu-central-1

This is idempotent. It creates the table, the tag-index GSI, and enables TTL on expiresAt. PAY_PER_REQUEST billing by default.

Or programmatically:

import { createCacheTable } from "nextjs-dynamodb-cache/create-table";

await createCacheTable({ tableName: "my-app-cache", region: "eu-central-1" });

2. Register the handler

// next.config.js
module.exports = {
  cacheHandler: require.resolve("./cache-handler.mjs"),
  cacheMaxMemorySize: 0, // disable in-memory cache so DDB is authoritative
};
// cache-handler.mjs
import { DynamoDBCacheHandler } from "nextjs-dynamodb-cache";

export default DynamoDBCacheHandler.configure({
  tableName: "my-app-cache",
  region: "eu-central-1",
  // optional: defaultTtlSeconds, keyPrefix, log, credentials
});

That's it. revalidateTag() and revalidatePath() now work cluster-wide.

IAM

The Lambda/Amplify role needs:

{
  "Effect": "Allow",
  "Action": [
    "dynamodb:GetItem",
    "dynamodb:PutItem",
    "dynamodb:DeleteItem",
    "dynamodb:Query",
    "dynamodb:BatchWriteItem"
  ],
  "Resource": [
    "arn:aws:dynamodb:eu-central-1:*:table/my-app-cache",
    "arn:aws:dynamodb:eu-central-1:*:table/my-app-cache/index/*"
  ]
}

Options

Option Default Description
tableName env NEXT_CACHE_DYNAMODB_TABLE or nextjs-cache DynamoDB table name
region env NEXT_CACHE_AWS_REGION / AWS_REGION / eu-central-1 AWS region
credentials default chain Explicit AWS credentials
tagIndexName tag-index GSI name used for revalidateTag
defaultTtlSeconds 604800 (7 days) TTL when Next.js omits revalidate
keyPrefix "" Prefix for keys (multi-app table sharing)
log true Verbose logs on errors and revalidations

How it works

  • Schema: single table, partition key key. Each entry has value, expiresAt (TTL), and optional tags.
  • Tags: for each tag a sentinel row __tag__<tag>__<key> is written. revalidateTag(t) queries the tag-index GSI on tag = t, collects the original cache keys, and batch-deletes them.
  • TTL: DynamoDB native TTL on expiresAt cleans up stale entries automatically — no cron required.
  • Resilience: every operation is wrapped in try/catch; a DynamoDB outage degrades to "cache miss," never a 500.

Status

Battle-tested in production on Next.js 16 + Amplify hosting on the HonestDog marketplace. Compatible with Next.js 14, 15, and 16 cache-handler APIs.

License

MIT

About

Drop-in Next.js 14/15/16 CacheHandler that stores ISR cache and tag revalidation in DynamoDB. Survives deploys on AWS Amplify, Lambda, App Runner, and other ephemeral runtimes.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages