Problem Description:
- After integrating Builder.io, we have noticed a dramatic increase in our Vercel data cache writes and ISR operations.
- For one day, our Vercel data cache writes were approximately 48,000 and ISR operations were around 52,000, which is significantly higher than expected.
- This issue persists despite implementing various strategies I am at a loss of why it is doing it. My other apps with builder do not do this.
Steps to Reproduce:
- Integrate Builder.io SDK in a Next.js application with App Router.
- Implement data fetching using Builder.io as shown in the provided code snippets.
- Deploy the application on Vercel and monitor data cache writes.
Expected Behavior:
- Data cache writes should be optimized, leveraging effective caching and ISR mechanisms.
- Write operations should be minimal and only occur during revalidation periods or actual data updates.
Actual Behavior:
- Unusually high number of data cache writes and ISR operations.
- Increased operational costs due to excessive write operations.
Please see the code snippet below. If builder is removed the data cache writes decrease dramatically.
import { RenderBuilderContent } from '@/components/builder'
import Home from '@/components/server/homepage'
import { builder } from '@builder.io/sdk'
interface PageProps {
params: {
page: string[]
}
}
export default async function HomePage(props: PageProps) {
const builderModelName = 'page'
const builderContent = await builder
.get(builderModelName, {
userAttributes: {
urlPath: '/' + (props.params.page?.join('/') || ''),
},
})
// Convert the result to a promise
.toPromise()
return (
<>
<Home />
<RenderBuilderContent content={builderContent} model={builderModelName} />
</>
)
}
Hello @billcookie1,
Given your setup and the problems you’re encountering with excessive ISR operations and cache writes, you can take the following steps to optimize your implementation:
1. Check Revalidation Strategy:
Ensure that you do not over-revalidate the pages. Given the frequency of your data update, set a realistic revalidate
time period.
2. Optimizing Data Fetching:
Ensure that the Builder API requests are well-optimized and minimal. Avoid fetching unnecessary data.
3. Effective Caching:
Verify that your caching strategy is configured properly. Ensure you use getStaticProps
and getStaticPaths
correctly to fetch data at build time while keeping revalidations optimal.
4. Addressing Incremental Static Regeneration (ISR):
Ensure that ISR is configured to handle only necessary content updates and regenerations. Set revalidate
property responsibly.
Example with App Router
Implementation:
Here is how you can optimize your provided implementation:
Using Incremental Static Regeneration Efficiently:
- Fetch Only Necessary Data: Limit the amount of data fetched, omitting unused parts.
- Cache Strategy: Reduce the frequency of ISR updates.
import { RenderBuilderContent } from '@/components/builder';
import Home from '@/components/server/homepage';
import { builder } from '@builder.io/sdk';
import { revalidateProperty } from 'next';
interface PageProps {
params: {
page: string[]
}
}
// Initialize the API key
builder.init('YOUR_API_KEY'); // Replace with your actual builder API key
export default async function HomePage({ params }: PageProps) {
const builderModelName = 'page';
// Fetch the builder content
const builderContent = await builder
.get(builderModelName, {
userAttributes: {
urlPath: '/' + (params.page?.join('/') || ''),
},
})
.toPromise(); // Convert the result to a promise
// Return the page content with ISR settings
return {
props: {
builderContent: builderContent || null,
},
revalidate: 60, // Revalidate every 60 seconds, adjust based on your data change frequency
};
}
// Page Component
export default function Page({ builderContent, builderModelName }) {
if (!builderContent) {
return <h1>Content not found</h1>; // Handle missing content gracefully
}
return (
<>
<Home />
<RenderBuilderContent content={builderContent} model={builderModelName} />
</>
);
}
Key Points:
- Set
revalidate
to a realistic interval: Here it’s set to 60 seconds, but consider adjusting it based on the frequency of your data updates.
- Handle empty/bad content gracefully: The
content not found
block ensures any missing content doesn’t trigger excessive regenerations.
- Batch Operations: If applicable, use batch operations to sync or update content to minimize the number of writes.
Additional Considerations:
- Analyze Real-Time Requests: Use Vercel analytics/logs to inspect real-time ISR requests and cache writes, identifying any unexpected patterns.
- Adjust Builder Settings: Confirm that Builder’s targeting or conditions do not trigger unnecessary requests.
- Version Control and Testing: Ensure your code and dependencies are up to date. Test changes in a separate environment before deploying widely.
Reviewing and tuning ISR settings, data fetching logic, and efficient cache use should alleviate the high Vercel data cache writes and ISR operations. Maintain logs and monitor real-time traffic accordingly after updates for further tweaks. Feel free to dive deeper into the Next.js ISR documentation and the details on integrating pages with Builder for more context and advanced configurations.
Thanks,