Caching & Data Fetching
Relevant source files
The following files were used as context for generating this wiki page:
The Caching & Data Fetching system in TREAD Talks manages data retrieval and persistence across the frontend and backend. It integrates Next.js 16's caching mechanisms with Convex's real-time database functions to ensure efficient, consistent, and performant data delivery. The architecture emphasizes feature-based organization and strict separation between public and private data access.
Sources: AGENTS.md:68-87, README.md:6-14
Data Fetching Architecture
The project utilizes Next.js App Router for server-side fetching and Convex for database interactions. Fetching logic resides within specific queries/ directories inside each domain feature folder.
Server-Side Data Fetching
Server components and queries retrieve data using fetchQuery or fetchAuthQuery. The system strictly prohibits fetching data in layout.tsx to prevent all child components from being forced into dynamic rendering. Instead, individual components fetch their own data internally.
Sources: AGENTS.md:104-123, src/features/topics/queries/get-topics-with-talks.ts:16-18
Convex Backend Functions
Convex handles data persistence through four primary function types:
- Queries: Read-only operations that are automatically reactive.
- Mutations: Write operations that execute as transactions.
- Actions: Side-effect operations (e.g., calling external APIs) that cannot directly access the database.
- Internal Functions: Private functions accessible only by other Convex functions.
The diagram shows the flow from UI components through server layers to the Convex database.
Caching Strategy
The application uses Next.js 16's 'use cache' directive to optimize performance and reduce database load.
Cache Directives
Caching behavior is controlled by file-level directives within queries/ directories:
'use cache': Applied to public queries that do not depend on user authentication.'use cache: private': Applied to auth-dependent queries, ensuring data is cached per-user.
Sources: AGENTS.md:144-150, src/app/@sheet/_queries/get-form-options.ts:1
Cache Lifecycle and Invalidation
Cached queries define their validity using cacheLife and cacheTag.
cacheLife: Sets the duration for which the data remains fresh (e.g.,cacheLife('hours')).cacheTag: Categorizes the cached data for targeted invalidation.
Sources: AGENTS.md:152-160, src/features/topics/queries/get-topics-with-talks.ts:14-15
| Feature | Cache Type | Cache Life | Tags |
|---|---|---|---|
| Form Options | Private | Hours | form-options |
| Topics Browse | Public | Hours | topics |
| Finished Talks | Private | Hours | user-finished-talks |
| Talk Topics | Private | Hours | talks, topics |
Sources: src/app/@sheet/_queries/get-form-options.ts:11-12, src/features/topics/queries/get-topics-with-talks.ts:14-15, src/features/users/queries/get-user-finished-talks.ts:11-12
Revalidation
Manual invalidation occurs during data updates:
updateTag: Used in Server Actions for "read-your-writes" semantics, ensuring the user sees changes immediately.revalidateTag: Used for background or webhook-driven invalidation.
Sources: AGENTS.md:162-169
Interaction Patterns
Authenticated Queries
Private data is retrieved via fetchAuthQuery, which reads session cookies to identify the user. These queries are typically cached with the private directive to prevent cross-user data leakage.
'use cache: private';
export async function getTalkTopics(talkId: TalkId) {
cacheLife('hours');
cacheTag('talks');
cacheTag('topics');
return await fetchAuthQuery(api.talks.listTalkTopics, { talkId });
}
Sources: src/features/talks/queries/get-talk-topics.ts:1-14
Sequence of a Data Update
When a user performs an action, the system follows a specific sequence to maintain data integrity and cache consistency.
The sequence diagram illustrates the invalidation flow following a successful mutation. Sources: AGENTS.md:162-179
Pagination and Results
Database queries use paginationOpts to manage large datasets. Standard parameters include cursor and numItems. Queries typically return an object containing the page of results, an isDone boolean, and a continueCursor.
Sources: convex/_generated/ai/guidelines.md:118-140, src/app/@sheet/_queries/get-form-options.ts:14-17
Summary
Caching and Data Fetching in TREAD Talks balances real-time database capabilities with high-performance static rendering. By utilizing Next.js 16's caching primitives and strictly organizing data access by feature, the system ensures that user-specific data remains private and performant while public content is served efficiently from the global cache.