Fat vs Slim vs Hybrid in Redis Stack: the model that changed how I think about retrieval for LLM
When volume grows and the LLM starts losing itself in the context, the modeling decision is as important as the database choice. Fat, Slim, or Hybrid - which one stuck?
(Continuation of the previous post. If you want full context, start there.)
The other day I talked about how Redis Stack became my deterministic retrieval and analytics layer. Today I want to dig into what, in practice, most affected performance and cost: the decision of how to model the documents.
The topic sounds simple - just put everything in a JSON and index it. But when volume grows and the LLM starts consuming the result and losing itself, you discover that the modeling decision is as important as the database choice.
To avoid labor-ethics issues, I'll keep using as my example a domain I think most developers have touched: an e-commerce product catalog.
The concrete problem
Imagine a conversational assistant answering questions like:
"Got men's sneakers under $300 with free shipping and in stock?"
"Tell me more about that sneaker model you just showed me."
"Show me the 5 highest-rated bluetooth headphones."
Three different questions. Three radically different access patterns. And the LLM, smart as it is, hallucinates when you throw 80 fields at it for a context that needed 5.
The three models I tested
1. FAT - Store everything, index everything
The initial temptation: a huge document with every field the catalog API returns.
What happens:
- RAM explodes: each document with 60+ indexed fields = heavy index
- FT.SEARCH returns everything → you pass an 800-token
descricao_completato the LLM - The model hallucinates because it gets lost in the noise
- LLM cost goes up without delivering better quality
2. SLIM - Only essentials in retrieval
The second attempt: index and return only what the search agent needs.
The problem: when the user asks "tell me the return policy for this product" or "what's the weight to calculate shipping?", you don't have the fields. Then comes the temptation to expand SLIM, and you're back to FAT.
3. HYBRID - The pattern that stuck
The insight: separate the search phase from the detail phase.
RediSearch filters and orders using indexed fields. JSON.GET retrieves the complete document only when the user wants the detail of a specific item.
The schema behind the hybrid
Trade-offs of each model
RediSearch has no native BOOL type. So I learned the hard way: every boolean field becomes a TAG with string "true"/"false".
Sounds trivial. But when you receive True, 1, "yes", "TRUE" from upstream (catalog APIs are full of this), without this converter the index becomes inconsistent and the search returns zero results, with no explicit error.
What LangGraph gained from this
Each tool knows exactly how much data the LLM needs for that specific intent. That's the core of the pattern: the data model serves the intent, not the other way around.
What I took away
Fat/Slim/Hybrid modeling in Redis isn't a technical choice - it's a contract decision between retrieval and the LLM.
Throw too much data, the model loses itself. Too little, it hallucinates to fill gaps. The optimum is: the minimum necessary for the model to answer safely, with an escape to full detail when the intent demands.
In my case, it ended up like this:
- Catalog search → Slim (5 fields, N products, short context)
- Product detail →
JSON.GETof Fat → formatted asSlimDetail(20 fields, 1 product, medium context) - Aggregations →
FT.AGGREGATEdirectly, with no document going to the LLM
Each pattern has its cost. Understanding which to use in which flow was what really changed the project's bill.
The next post will be about how DSPy entered this picture to classify intent and route to the right tool - no hardcoded rules, with supervised examples and automatic prompt optimization.