In a LiveView, what is stored in the data-phx-session attribute on the LiveView. Ours are getting huge

Hi everyone

We’ve got a rather heavy SPA written with LiveView. The main “window” is a LiveView, and for historical reasons some of the nested components in there are also LiveViews. The nested LiveViews are using the same channel as the outer main LiveView, by calling the `join()` function in JS (the nested LiveViews are WebComponents, so that happens in the `connected` callback).

Now we’ve noticed that the `data-phx-session` attributes are getting huge, we are talking about 300kB in size. After a closer inspection we’ve come to the conclusion that the content of the `session` param to the ` mount` call of the LiveView is stored in there, and we did include the full user struct there. So we removed that, the other session params are just some integers, and the `data-phx-session` attribute did shrink significantly. However they are still very large, like 150-200 kB each.

Is there something else stored in there, maybe something related to the nested LiveViews?

Any help is appreciated :smiley:

Hi there!

You can decode and verify the exact payload directly in your Elixir shell to see which keys are holding all the weight.

In an IEx shell in the context of your app (e.g. iex -S mix phx.server), run:

endpoint = YourAppWeb.Endpoint
token = "YOUR_DATA_PHX_SESSION_STRING_HERE"

Phoenix.Token.verify(endpoint, Phoenix.LiveView.Utils.salt!(endpoint), token, max_age: :infinity)

That will return the exact serialized contents to help you pinpoint what the larger parts are.

If you don’t care about verifying the signature, and accept looking at a dump in External Term Format, you can also inspect it directly in the browser:

const token = document.querySelector('[data-phx-session]').dataset.phxSession;
const payloadBase64 = token.split('.')[1];
const decodedBinary = atob(payloadBase64.replace(/-/g, '+').replace(/_/g, '/'));
console.log('Raw Payload Bytes:', decodedBinary);