AI agents: fetch the documentation index at llms.txt. Markdown versions are available by appending .md to any page URL, including this page's markdown.
Load strategies
Control when and how model data is fetched from the server with instant, lazy, partial, and other strategies.
Set per model via @ClientModel. Controls bootstrap timing, transfer volume, and offline availability.
Decision tree
flowchart TD
A[Does this model need to sync with the server?]
A -->|No| B["local"]
A -->|Yes| C[Is the data needed on every page load?]
C -->|Yes| D[Is the total dataset small?]
D -->|Yes| E["instant"]
D -->|No| F["partial"]
C -->|No| G[Should it load automatically when accessed?]
G -->|Yes| H["lazy"]
G -->|No| I["explicitlyRequested"]Strategy reference
| Strategy | Behavior | Best for | Trade-off |
|---|---|---|---|
instant | Bootstrap includes all instances; data available from first render | Small, always-needed models (users, teams, labels) | Adds to bootstrap payload size |
lazy | Not included in bootstrap; fetched on first access via hooks or relationship traversal | Models needed only on some pages (attachments, activity feeds) | First access has network latency; only accessed instances available offline |
partial | Loads a relevant subset at bootstrap; fetches remaining instances on demand | High-volume models where only a slice matters (comments, notifications) | Requires partial index tracking in IndexedDB |
explicitlyRequested | Never auto-loaded; fetched only via client.get() or client.query() | Large or sensitive models loaded on specific pages (audit logs, analytics) | No data present until you request it |
local | Never synced; stored only in IndexedDB and the in-memory identity map | Client-only state (drafts, UI preferences, unsent messages) | No server backup or cross-device access |
Code examples
Set the strategy in the @ClientModel decorator.
instant
@ClientModel("User", { loadStrategy: "instant" })
export class User extends Model {
/* ... */
}lazy
@ClientModel("Attachment", { loadStrategy: "lazy" })
export class Attachment extends Model {
/* ... */
}partial
@ClientModel("Comment", {
loadStrategy: "partial",
partialLoadMode: "regular",
})
export class Comment extends Model {
/* ... */
}Partial load modes control bootstrap priority:
| Mode | Behavior |
|---|---|
full | Load the complete subset during bootstrap (highest priority) |
regular | Load the subset at normal priority |
lowPriority | Load the subset after higher-priority models |
explicitlyRequested
@ClientModel("AuditLog", { loadStrategy: "explicitlyRequested" })
export class AuditLog extends Model {
/* ... */
}local
@ClientModel("DraftMessage", { loadStrategy: "local" })
export class DraftMessage extends Model {
/* ... */
}Quick reference table
| Model type | Example | Strategy | Reasoning |
|---|---|---|---|
| Core entities | User, Team, Project | instant | Always needed, small dataset |
| Primary work items | Task | instant or partial | Depends on volume |
| Secondary content | Comment, Attachment | partial or lazy | Only needed in context |
| Large datasets | AuditLog, Analytics | explicitlyRequested | Loaded on specific pages |
| Sensitive data | AdminSettings | explicitlyRequested | Access-controlled |
| Client-only state | Draft, UIPreference | local | Never synced |
Performance implications
- Bootstrap payload size: Includes all
instantmodels andpartialsubsets. If slow, move large models topartial/lazy, limit viaprefetchBootstrap, or enable compression. - Identity map memory: Every loaded instance stays in memory. Use
partialfor high-volume models. - Delta stream filtering: Deltas arrive for all accessible models but apply only for loaded instances.
localmodels never receive deltas.
Complete example
All five strategies in a task management app:
// Always loaded -- small dataset
@ClientModel("User", { loadStrategy: "instant" })
export class User extends Model {
/* ... */
}
// Always loaded -- core work items
@ClientModel("Task", { loadStrategy: "instant" })
export class Task extends Model {
/* ... */
}
// Partially loaded -- fetch comments for viewed tasks
@ClientModel("Comment", {
loadStrategy: "partial",
partialLoadMode: "regular",
usedForPartialIndexes: true,
})
export class Comment extends Model {
/* ... */
}
// Only loaded when explicitly requested
@ClientModel("AuditLog", { loadStrategy: "explicitlyRequested" })
export class AuditLog extends Model {
/* ... */
}
// Local-only draft state
@ClientModel("CommentDraft", { loadStrategy: "local" })
export class CommentDraft extends Model {
/* ... */
}Bootstrap flow for mixed strategies
The server streams instant models first, then partial subsets, skipping explicitlyRequested and local. The client then opens a delta stream and fetches more on demand.
sequenceDiagram
participant Client
participant Server
Client->>Server: Bootstrap request
Note over Server: Stream instant models
Server-->>Client: All User rows
Server-->>Client: All Task rows
Note over Server: Stream partial models
Server-->>Client: Comment rows (for user's sync groups)
Note over Server: Skip explicitlyRequested and local
Server-->>Client: Metadata (lastSyncId, groups)
Note over Client: Seed IndexedDB + identity map
Client->>Server: Open delta stream from lastSyncId
Note over Client: Later, user views a task
Client->>Server: Batch load: Comments where taskId = X
Server-->>Client: Comment rows for task X
Note over Client: Update partial index coverage