PostHog Next.js causing memory leaks
Hi,
I have been using PostHog for a while and just discovered it is causing a serious memory leak.
I am using [email protected].
I solved the leak by lazily importing Posthog.
export const CSPostHogProvider = (props: IProps) => {
const [client, setClient] = useState<PostHog | undefined>();
useEffect(() => {
const handler = async () => {
const posthog = (await import("posthog-js")).posthog;
const client = posthog.init(
process.env["NEXT_PUBLIC_POSTHOG_KEY"] ?? "",
{
api_host: `${FRONT_END_URL}/ingest`,
capture_pageview: false,
},
);
setClient(client);
};
handler();
}, []);
if (!client) return props.children;
return <PostHogProvider client={client}>{props.children}</PostHogProvider>;
};
The above code solved the leak on the server side, but the thing is I am worried the leak is happening on clients now.
Last 14 Days memory usage. cloud run instance
Last 1 Days memory usage. cloud run instance
You can observe from the above image that the memory usage is now constant at around 15% after I pushed the above code const posthog = (await import("posthog-js")).posthog;
How I was using PostHog before:
export const CSPostHogProvider = (props: IProps) => {
const [client, setClient] = useState<PostHog | undefined>();
useEffect(() => {
const client = posthog.init(process.env["NEXT_PUBLIC_POSTHOG_KEY"] ?? "", {
api_host: `${FRONT_END_URL}/ingest`,
capture_pageview: false,
});
setClient(client);
}, []);
return <PostHogProvider client={client}>{props.children}</PostHogProvider>;
};
I tried this as well:
export const CSPostHogProvider = (props: IProps) => {
const isClientSide = typeof window !== "undefined";
if (isClientSide) {
posthog.init(process.env["NEXT_PUBLIC_POSTHOG_KEY"] ?? "", {
api_host: `${FRONT_END_URL}/ingest`,
capture_pageview: false,
});
}
return <PostHogProvider client={posthog}>{props.children}</PostHogProvider>;
};
I don't know if the leak is because of the way I configured PostHog or because of the library itself.
I am using [email protected]
Another concern is there are any plans about decreasing the size of the lib? https://github.com/PostHog/posthog-js/issues/65
that's already states in their docs bro to do the dynamic import a.k.a lazy load the components.
The photo or the screenshot is for loading the Page View component.
I clearly stated that the problem concerns the Provider component and initialization of the lib itself.
And I don't think lazily loading the provider is good for performance.
Hey, @mjad218!
I see you're using posthog slightly different from how we suggest you set it up. I believe you shouldn't be seeing any problems if you set up PostHog the following way
export const CSPostHogProvider = (props: IProps) => {
useEffect(() => {
posthog.init(process.env["NEXT_PUBLIC_POSTHOG_KEY"] ?? "", {
api_host: `${FRONT_END_URL}/ingest`,
capture_pageview: false,
});
}, []);
return <PostHogProvider client={posthog}>{props.children}</PostHogProvider>;
};
This has a couple of benefits compared to what you've been doing:
- You're not sometimes rendering the provider and sometimes not, that'll trigger a complete rerender of your tree because you changed it heavily
- You're always passing a valid
posthoginstance toPostHogProviderrather than sometimes passingundefined- which we'll prevent soon
Do you mind trying that approach and letting me know if you're still seeing memory leaks? Thank you!
Closing as a setup issue