🌊 Zero Manual Cache Management

GraphQL Cascade

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.

Cascade Flow

1
Mutation Executes
PostgreSQL function with CASCADE
2
Metadata Generated
What changed, invalidations needed
3
Client Cache Updates
Apollo/Relay automatically refresh

How GraphQL Cascade Works

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.

πŸš€

No Refetch Queries

Mutations return updated entities directly. Clients don't need to make a second query after writesβ€”50% fewer round-trips.

🧠

Zero Cache Logic

Apollo and Relay update their caches automatically from _cascade metadata. No manual invalidation code.

❌ Traditional Approach

Manual Cache Management
# 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

βœ… FraiseQL Cascade

Automatic Cache Updates
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

PostgreSQL Function Pattern

PostgreSQL Function with CASCADE
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;

Apollo & Relay Integration

πŸš€ Apollo Client

Apollo Cache Updates
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);

⚑ Relay

Relay Store Updates
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!
  });
}

Why Cascade Matters

🎯

Zero Cache Staleness

Mutations always return what changed. Clients stay perfectly in sync.

⚑

Better Performance

Eliminates unnecessary refetches. Only update what actually changed.

πŸ›‘οΈ

Fewer Bugs

No manual cache management means no forgotten invalidations or stale data.

An Open Specification

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.

GitHub
graphql-cascade/graphql-cascade

Specification, examples, and client integrations

Contributions welcome. Help us make GraphQL cache management easier for everyone.

Ready for Zero Cache Management?

Build reliable GraphQL applications without cache invalidation headaches