Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guides tenant isolation architecture in Qdrant for multi-tenant or multi-user applications. Use when someone asks 'how to isolate customer data', 'how to build multi-tenant search/RAG', 'how many collections should I create', 'how to partition tenants by payload', 'a customer's data legally has to stay in a certain country or region'. Also use when they describe a symptom: one customer's data is way bigger than the rest and slowing everyone down, or one tenant is hogging resources.
.claude/skills/qdrant-qdrant-multitenancy/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 7% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -16% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -15% | 0% |
| case-07 | ✗→✓ | ▲ Improved | -21% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 29% | 0% |
Multitenancy is how you isolate data across multiple users or tenants within a single Qdrant deployment.
Use when: you have many tenants of roughly similar, modest size. This is the recommended default for most users.
One collection holds every tenant. A payload field marks ownership, and a filter on that field at query time is what isolates each tenant's results.
is_tenant=true (the flag requires v1.11+). is_tenant tells Qdrant the field identifies tenants, so each tenant's vectors are stored together and served by sequential reads. Check .must filter on the tenant field. Without it, a query searches every tenant's data. Check Payload-based multitenancy.m=0 and payload_m to a non-zero value. Although this accelerates the indexing process, keep in mind that requests without a tenant filter will become slower as they must scan all groups. So only make this trade if you hit the bottleneck and cross-tenant search is rare. Calibrate performance.Use when: you have a realistic SaaS distribution: a few large customers and many small ones, possibly with small tenants that grow over time. Available in v1.16+. It avoids the noisy-neighbor problem, where one big tenant forces the whole cluster to scale, raising costs and degrading performance for everyone else.
Tiered multitenancy keeps small tenants together in a shared fallback shard while isolating large tenants in their own dedicated shards, all in one collection. It layers two isolation levels: payload-based tenancy for logical isolation, and custom sharding for physical/ resource-based isolation of the large tenants. A tenant that outgrows the shared shard can be promoted to a dedicated shard later with no downtime.
Use when: you have a limited number of tenants with different per-tenant embedding models or collection schemas.
Use when: data must be physically pinned to a location, e.g. regional compliance for healthcare industry (one region's data in Canada, another's in Germany). This is not only a tenant concern, a single tenant may also need to separate its own data by region.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 23,709 | 24,455 | +3% | 1 | 1 | 0% | 3,394 | 3,626 | +7% | 0 | 0 | — |
case-02 | fail→pass | 24,658 | 13,172 | -47% | 1 | 1 | 0% | 4,589 | 3,867 | -16% | 0 | 0 | — |
case-03 | fail→pass | 25,629 | 10,587 | -59% | 1 | 1 | 0% | 3,715 | 3,156 | -15% | 0 | 0 | — |
case-04 | pass→pass | 18,184 | 9,564 | -47% | 1 | 1 | 0% | 2,558 | 3,099 | +21% | 0 | 0 | — |
case-05 | pass→pass | 17,187 | 5,757 | -67% | 1 | 1 | 0% | 2,457 | 2,423 | -1% | 0 | 0 | — |
case-06 | pass→pass | 13,854 | 9,146 | -34% | 1 | 1 | 0% | 2,243 | 2,853 | +27% | 0 | 0 | — |
case-07 | fail→pass | 23,107 | 7,218 | -69% | 1 | 1 | 0% | 3,324 | 2,627 | -21% | 0 | 0 | — |
case-08 | pass→pass | 18,840 | 10,340 | -45% | 1 | 1 | 0% | 2,522 | 3,108 | +23% | 0 | 0 | — |
case-09 | pass→pass | 14,535 | 10,106 | -30% | 1 | 1 | 0% | 2,079 | 2,779 | +34% | 0 | 0 | — |
case-10 | pass→pass | 21,183 | 13,178 | -38% | 1 | 1 | 0% | 2,817 | 3,112 | +10% | 0 | 0 | — |
case-11 | pass→pass | 15,056 | 7,694 | -49% | 1 | 1 | 0% | 2,411 | 2,619 | +9% | 0 | 0 | — |
case-12 | pass→pass | 20,360 | 5,739 | -72% | 1 | 1 | 0% | 2,516 | 2,355 | -6% | 0 | 0 | — |
case-22 | pass→pass | 16,545 | 10,041 | -39% | 1 | 1 | 0% | 3,161 | 3,209 | +2% | 0 | 0 | — |
case-13 | fail→pass | 37,446 | 10,845 | -71% | 1 | 1 | 0% | 2,452 | 3,158 | +29% | 0 | 0 | — |
case-14 | pass→pass | 17,648 | 5,914 | -66% | 1 | 1 | 0% | 2,867 | 2,228 | -22% | 0 | 0 | — |
case-15 | pass→pass | 3,818 | 3,806 | -0% | 1 | 1 | 0% | 682 | 1,973 | +189% | 0 | 0 | — |
case-16 | pass→pass | 14,243 | 5,264 | -63% | 1 | 1 | 0% | 1,983 | 2,277 | +15% | 0 | 0 | — |
case-17 | pass→pass | 40,200 | 3,885 | -90% | 1 | 1 | 0% | 1,524 | 1,872 | +23% | 0 | 0 | — |
case-18 | pass→pass | 8,395 | 2,809 | -67% | 1 | 1 | 0% | 1,245 | 1,846 | +48% | 0 | 0 | — |
case-19 | pass→pass | 17,563 | 7,334 | -58% | 1 | 1 | 0% | 2,608 | 2,553 | -2% | 0 | 0 | — |
case-20 | pass→pass | 14,651 | 8,297 | -43% | 1 | 1 | 0% | 2,082 | 2,544 | +22% | 0 | 0 | — |
case-21 | pass→pass | 10,684 | 7,450 | -30% | 1 | 1 | 0% | 1,457 | 2,437 | +67% | 0 | 0 | — |
case-23 | pass→pass | 16,357 | 10,779 | -34% | 1 | 1 | 0% | 2,520 | 3,347 | +33% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +22 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.