1. What it is
HydraDB scopes data using two identifiers:tenant_id- the top-level scoping identifier. Use it for customers, environments, or other primary data boundaries.sub_tenant_id- an optional scoping identifier within a tenant. Use it for users, workspaces, teams, or other logical partitions.
tenant_id. When sub_tenant_id is provided, it further narrows the scope for that operation. If you omit sub_tenant_id, HydraDB uses the tenant’s default sub-tenant.
Use the same scoping values consistently across writes and reads. If you write data with one sub_tenant_id and later recall with a different one, that data may not appear in the recall results.
2. When to use each
Two practical rules:
- Use a separate tenant whenever data must not mix across customers or environments.
- Use a sub-tenant for logical partitions inside a tenant, such as users, workspaces, teams, or projects.
sub_tenant_id as a substitute for separate production and staging tenants. Environments should usually be separated at the tenant_id level.
3. Recommended patterns
B2C application
Use one tenant for the application or customer account, and use each end-user as a sub-tenant.- Write user Memories with
sub_tenant_id = user_id. - Recall user Memories with the same
sub_tenant_id. - Keep shared Knowledge outside the user-specific scope.
B2B SaaS
Use one tenant per customer organization. Usesub_tenant_id for the workspace, team, project, or user scope inside that customer.
- Customer-level Knowledge uses the customer
tenant_id. - Workspace-specific data uses a workspace
sub_tenant_id. - User-specific Memories use a user-level
sub_tenant_id.
Shared Knowledge + user personalization
For personalized answers grounded in shared Knowledge, keep the two retrieval paths explicit:- Use
full_recallfor shared Knowledge - this hits the Knowledge vector store (vectorstore_statusindex1). - Use
recall_preferencesfor user-specific Memories - this hits the Memories vector store (vectorstore_statusindex0). - Merge the two results in your application before prompting the LLM.
4. How scoping works
Writes
Writes includetenant_id, and may include sub_tenant_id.
Use sub_tenant_id when the data belongs to a specific user, workspace, team, or other logical partition. Omit it when you intentionally want the data written to the tenant’s default sub-tenant.
Examples:
- A memory about John’s preferences should be written with John’s
sub_tenant_id. - Workspace-specific runbooks should be written with that workspace’s
sub_tenant_id. - Broadly shared Knowledge should use the same scope you plan to use when recalling it.
Reads
Recall requests includetenant_id, and may include sub_tenant_id. If sub_tenant_id is omitted, recall uses the tenant’s default sub-tenant.
Use the same scoping values on recall that you used when writing the data. A recall request with one sub_tenant_id should not be expected to retrieve data written under a different sub_tenant_id.
If your application needs to combine data from multiple scopes, make separate recall calls and merge the results in your application.
Use sub_tenant_id for partitioning data. Use metadata_filters for narrowing results within that scope.
Memories and Knowledge
Memory recall and Knowledge recall are separate retrieval paths:recall_preferencesretrieves Memories (user-scoped, personal).full_recallretrieves Knowledge (shared documents and app sources).
- Recall shared Knowledge with
full_recall. - Recall user Memories with
recall_preferences. - Format and merge both results into one LLM prompt.
5. Minimal working example
The example below shows a common personalized-answer flow: write a user Memory, recall that user’s preferences, recall shared Knowledge, and merge the two contexts in your application.6. Common mistakes
Mismatchedsub_tenant_id between write and read.
Data written under one sub-tenant should not be expected to surface when recalled under another. Use the same sub_tenant_id consistently for the same logical scope.
Sharing a tenant_id across environments.
Do not use one tenant for both production and staging. Create separate tenants for separate environments.
Confusing tenant_id with sub_tenant_id.
Use tenant_id for primary boundaries such as customers or environments. Use sub_tenant_id for partitions inside a tenant, such as users or workspaces.
Assuming recall automatically merges scopes.
A recall call uses the scope you provide. If your application needs data from multiple scopes, make multiple calls and merge the results yourself.
Writing shared Knowledge under a user scope by accident.
If broadly shared Knowledge is written with a user-specific sub_tenant_id, it may not appear where other users expect it. Choose the write scope based on where the content should be recalled later.
Using metadata filters as a substitute for sub-tenants.
Metadata filters narrow results inside a scope. They are not a replacement for choosing the right tenant_id and sub_tenant_id.
Using unstable identifiers.
Avoid display names, emails that may change, or user-provided labels as long-term scope identifiers. Prefer stable internal IDs such as user_123, workspace_42, or org_acme.
Related
- Memories - user-scoped context
- Knowledge - shared document context
- Recall - how scoping is applied at query time
- How to Use API Results - merging recall results into a prompt
- Create Tenant - defining tenants and their metadata schema