π Zero Manual Cache Management
Automatic cache invalidation. Mutations return what changed. Apollo & Relay ready. Built into PostgreSQL functions.
GraphQL Cascade is an open specification created by the FraiseQL team.
Traditional GraphQL mutations leave cache management as an exercise for the developer. FraiseQL's Cascade automatically tracks what changed and tells clients exactly what to update.
Mutations return updated entities directly. Clients don't need to make a second query after writesβ50% fewer round-trips.
Apollo and Relay update their caches automatically from _cascade metadata. No manual invalidation code.
# Client-side cache invalidation
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
}
}
# Developer must manually:
# 1. Track what changed
# 2. Invalidate related queries
# 3. Update optimistic updates
# 4. Handle cache misses
Complex, error-prone, inconsistent
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
# Cascade metadata automatically included
_cascade {
updated {
__typename
id
operation
entity { id name }
}
invalidations {
queryName
strategy
scope
}
}
}
}
Zero manual work, always consistent
CREATE OR REPLACE FUNCTION update_user(
p_user_id INTEGER,
p_name TEXT
) RETURNS JSONB AS $$
DECLARE
v_result JSONB;
v_updated_ids INTEGER[];
BEGIN
-- Update the user
UPDATE users
SET name = p_name, updated_at = NOW()
WHERE id = p_user_id;
-- Return CASCADE metadata
v_result := jsonb_build_object(
'updated', jsonb_build_array(
jsonb_build_object(
'__typename', 'User',
'id', p_user_id,
'operation', 'UPDATE',
'entity', jsonb_build_object('id', p_user_id, 'name', p_name)
)
),
'deleted', '[]'::jsonb,
'invalidations', jsonb_build_array(
jsonb_build_object(
'queryName', 'GetUser',
'strategy', 'exact',
'scope', jsonb_build_object('id', p_user_id)
)
),
'metadata', jsonb_build_object(
'timestamp', extract(epoch from now()),
'affectedCount', 1
)
);
RETURN v_result;
END;
$$ LANGUAGE plpgsql;
const UPDATE_USER = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
_cascade {
updated {
__typename
id
entity
}
invalidations {
queryName
scope
}
}
}
}
`;
// Automatic cache updates - no manual work needed
const [updateUser] = useMutation(UPDATE_USER);
const UpdateUserMutation = graphql`
mutation UpdateUserMutation($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
_cascade {
updated {
__typename
id
entity
}
}
}
}
`;
// Relay automatically handles cache updates
function commitMutation(environment, variables) {
return commitMutation(environment, {
mutation: UpdateUserMutation,
variables,
// No updater functions needed!
});
}
Mutations always return what changed. Clients stay perfectly in sync.
Eliminates unnecessary refetches. Only update what actually changed.
No manual cache management means no forgotten invalidations or stale data.
GraphQL Cascade is an open specification, not a proprietary FraiseQL feature. We believe cache invalidation is a problem the entire GraphQL ecosystem should solve together.
Specification, examples, and client integrations
Contributions welcome. Help us make GraphQL cache management easier for everyone.
Build reliable GraphQL applications without cache invalidation headaches