Architecture & Delivery
SupabaseJWTAuthenticationProduct ArchitectureRisk Patterns

Why Storing Large JSON Blobs in Supabase User Metadata Can Break Your App

Modern products rarely fail because of one catastrophic decision

They fail because of a string of “harmless” ones — small shortcuts that quietly grow until one day everything snaps

Supabase’s `user_metadata` is a perfect example of such a trap: useful in the beginning, dangerous at scale, and deceptively easy to misuse

Most teams treat `user_metadata` like a casual place to store user-related information. After all, it’s just JSON, right?

Yes. But JSON with a hidden consequence: Supabase injects the entire metadata object into the user’s session token (JWT). And that token is shipped back to the client with every request, living inside cookies that browsers must handle on every interaction. The more metadata you add, the larger every request becomes

This is not a database pattern

This is a payload pattern

And it has architectural consequences

Meme about guys sitting still and then cheering

The Hidden Mechanism Most Teams Miss

Here is the actual path:

1. You store user data in `auth.users.user_metadata`

2. Supabase mirrors that metadata into the JWT

3. The JWT is stored in cookies

4. Cookies travel with every request

5. Your entire delivery pipeline becomes a transport system for personal data it never needed

It works — until it doesn’t

Everything seems harmless when metadata contains a few fields. But add behavioural data, UI states, directory preferences, or profile analysis, and suddenly:

Requests grow
Headers inflate
Debugging becomes inconsistent
Authentication behaves like a short-circuited traffic light

And eventually, something breaks loudly

Common symptoms:

The app logs users out without warning
Browsers start rejecting requests
Servers return HTTP 431: Request Header Fields Too Large

At that point, it doesn’t matter how clean your codebase is

Your authentication layer has become your performance bottleneck

The Moment It Became Real

I’m not theorising. I walked into this wall myself

I spent two full weekends trying to understand why authentication suddenly felt unreliable. There were no major deployments. No complex feature launches. Just a few incremental additions to `user_metadata` — a line here, a UI state there

Nothing that looked dangerous

Everything that *was*

The issue wasn’t the database

It wasn’t the infrastructure

It wasn’t even performance in the traditional sense

It was the JWT

A token that should have been a key had turned into a suitcase full of JSON being dragged through every request. And the root cause wasn’t megabytes of data — it was a few dozen lines of metadata silently accumulating beyond sanity

Not a dramatic breach

A slow suffocation

The Architectural Principle Nobody Teaches

Session ≠ Storage

Your JWT is not a warehouse

It is not a cache

It is not a container for evolving product context

A session token should be:

Small
Predictable
Static
Boring

Everything else belongs elsewhere

If your session needs to know who a user is, fine

If it needs their preferences, analytics, UI state, recent actions, and half your roadmap — you’re storing your product inside the passport

And passports aren’t for carrying furniture

The Correct Pattern

Use `user_metadata` for things you can fit on a business card

Everything else goes into dedicated tables

Recommended rule of thumb: Identity context - `user_metadata`, else - custom tables

If it evolves over time — do not put it in the session

If it feels convenient — question it

If you’re unsure — isolate it

The Bigger Picture

This isn’t really about Supabase

It’s about the difference between products that scale and products that accumulate entropy

Small architectural mistakes don’t show up immediately

They surface at the exact moment your product finds traction — which is the worst possible time to be surprised

If your session payload already feels heavier than it should

If your authentication logs read like riddles

If you suspect that your metadata is doing more work than your database

You are standing at the beginning of an avoidable failure

The good news: this is fixable

Conclusion

Successful products don’t drown in their own data

They structure it

Authentication should be a handshake — not a cargo delivery system

If your JWT is carrying your metadata instead of your identity, you’re not scaling. You’re stalling

And you can correct that before it becomes expensive

Let’s talk clarity

Menos charla — más beneficio. Construyamos un sistema real!

Ingeniería directa a nivel de código para operaciones que no pueden permitirse fallos ni retrasos de agencia