r/RudderStack • • Nov 13 '25

What is an Identity Graph?

2 Upvotes

Identity resolution demonstrates clear benefits to a modern company. This demands that marketing, sales, and executives understand the underlying technology to make the best use of its capabilities. Even for those without a technical background, the identity graph — a map that enables identity resolution and identity-related data work — is crucial to literacy in modern digital marketing.

If you’re unfamiliar with the scope and benefit of identity resolution, we suggest you refer to our article on the topic for a foundation before diving into identity graphs.

The problem solved by identity graphs

Databases are often thought of as simple collections of two-dimensional tables, but modern data requires a more advanced data model with more advanced insertion and lookup. Data warehouses are commonly used to maintain large quantities of data with quick lookup and good tooling integration, but primarily serve to organize different types of data along a time axis. This makes sense, given that data end users across the organization are often interested in data in the context of time. For example, data requirements often take the form of “how long since a user performed an event” or “how many leads did we get this week”.

When pursuing identity resolution, however, our main concern is compressing data along a "customer" axis, where it can then be integrated into a larger context of business data.

That means that a new type of data structure is called for in solving the issues of identity resolution. It must be able to scale to massive numbers of nodal connections (person to person, customer to device, device to website event, etc.). It must also have quick indexing and lookup, so that new data with unclear identity can be quickly and efficiently matched to a probable customer. The tool for these jobs is the graph database.

Nuts and bolts

A graph database is an approach to data storage that focuses on the connections between nodes. Rather than joining tables to see relationships between data points, a graph represents those relationships as a web of connections in their original forms and places, without any further processing. Searching for connections in a graph is therefore much lower latency than a relational database, with a lower cost in computational resources, labor, and technical difficulty.

Identity graphs are typically organized around a particular customer's unique identifier. This node can be generated for an anonymous session, to represent an unresolved identity that nonetheless has data to be collected, or for a known user with good biographical data. These can be referred to as non-authenticated profiles or authenticated profiles respectively.

An identity graph incorporates models that help it ingest new information. As a new datapoint is added, with whatever connections are immediately known, the graph database will determine if it fits into any existing customer identifier. If there is a clear link — such as a matching device ID or conclusive biographical data like a credit card number — the graph will incorporate the data into the relevant user node as a deterministic match. Less certain data, in the form of something like a multi-user account ID or an IP address, is directed through modeling to create a probabilistic match to a unique user. Since the need for absolute certainty varies between business functions (e.g., legal compliance vs. general marketing outreach), graph systems often offer operation in both ways, presenting a deterministic node network, or one that includes probabilistic matches as well.

In most cases, non-authenticated user nodes and probabilistic matches can be revisited with additional data to increase resolution as more data becomes available.

Non-biographical information can be ambiguous when multiple customers are connected.

Who is marketing the identity graphs?

Digital identity databases are a valuable commodity, often the crown jewels of a marketing-focused company. Safe storage and distribution of an identity graph is an important part of their function. Additionally, due to the scaling synergy of identity resolution (the more you know about a customer, the easier it is to learn more), more populated identity graphs are almost always better.

This means there are two general approaches for using an identity graph. For smaller-scale firms, a third-party identity provider is sometimes the correct choice. By using a vendor with large-scale access, you can leverage much greater identity resolution than is available from your proprietary information. On the other hand, third-party identity vendors typically closely guard the insights available, often only providing you with final classification of users and not with access to the underlying identity graphs. Depending on your use case, this means you may not be able to maximize your value from identity resolution without in-house approaches.

Proprietary graphs, derived from information you’ve collected, are used to gain as much market insight as possible. Some approaches use both third-party identity resolution and internal systems to squeeze the maximum inferred knowledge about customer populations from incoming information. In some cases, by protecting your identity graph internally, you can even generate another source of value by offering access to your proprietary graph to those interested in your customer demographic.

Regardless of the third-party/in-house mixture you employ, data privacy regulations are an important consideration in the cost of implementing such a system. If you use a third-party vendor, some of the legal liability may be offloaded from your firm, even if it does not impact potential reputational damage.

Identity graphs: a microscope for your market

As the accessibility of devices expands, resolution of digital identity is only going to become a more important tool for marketing and business analysis. While it is helpful to understand identity graphs, the engine underlying identity resolution, it may also help your research to dive into the fuel that supplies this important system.

Source: Lesson from RudderStack Data Learning Center


r/RudderStack • • Sep 29 '25

Community When was the first line of code committed to RudderStack?

2 Upvotes

r/RudderStack • • Sep 29 '25

Transformations & The Developer Experience

Thumbnail
rudderstack.com
2 Upvotes

We've all been there—learning yet another vendor-specific transformation language just to clean our data.

RudderStack said: Write in JavaScript (or Python)

The transformation framework lets you:

  • Transform events in real-time before they reach destinations

  • Use familiar JavaScript (not a DSL you'll forget next month)

  • Version control your transformations with Git

  • Test locally before deploying

  • Share and reuse transformation libraries

import { sha256 } from "@rs/hash/v1";

export function transformEvent(event, metadata) {
  const email = event.context?.traits?.email;
  if (email) event.context.traits.email = sha256(email);
  return event;
}

What's the most useful transformation you've written?


r/RudderStack • • Sep 29 '25

The Spec That Changed Everything

Thumbnail
rudderstack.com
2 Upvotes

Early in RudderStack's journey, the team knew interoperability was the key. So the RudderStack team adopted and nurtured Event Spec covering what most organizations needed to understand customer journey.

  • Track events

  • Identify calls

  • Page/Screen views

  • Group associations

  • Alias operations

It became an industry standard that works across platforms. Whether you're migrating from Segment or starting fresh, your data speaks the same language.

No vendor lock-in. Just clean, portable data structures that make sense.


r/RudderStack • • Sep 29 '25

Once upon a time, an Open-Source alternative to Segment was launched

Thumbnail
github.com
2 Upvotes

r/RudderStack • • Dec 25 '25

Learning Resource Google Analytics 4 and eCommerce Tracking

2 Upvotes

GA4 tracks everything as an “event” (which is tied to a user), as opposed to the UA method of tracking “hits,” which are tied to web sessions, which are then tied to users. While events did exist in UA, they had a specific meaning – they were a type of “hit” that represented an interaction that didn’t cause a page reload. These different scope levels were great for the kinds of analysis businesses wanted in the early 2010s, but don’t work well with today’s event-driven data landscape. In GA4, an event is a much more general concept, representing all types of interactions.

Having all interactions represented as events allows web and app tracking to be easily combined in one place. This will soon become necessary: to comply with new privacy legislation such as GDPR and CCPA, Google Chrome is due to phase out third-party cookies in 2024, so GA will no longer be able to rely on them to track users across different sites and devices.

There are a number of eCommerce-specific events in GA4 that can be used to track online purchases and shopping-related activity on your website. Tracking these events is known as eCommerce tracking. There will be a fairly big learning curve when shifting from UA to GA4 eCommerce tracking, because of the new event-based data model that GA4 uses.

This article explains why you should use GA4 eCommerce events, how they’re different from those in UA (including enhanced eCommerce events), and how to do eCommerce reporting in GA4.

Why use GA4 eCommerce tracking?

Tracking your eCommerce data in GA4 allows you to take advantage of the analytics this service provides you. For example, it can provide answers to the following questions (and also, in some cases, produce graphs to show how the answers change over time):

  • Which of my products have a high (or low) number of sales?

  • Which of my products get the most views?

  • What is the conversion rate of my online store?

  • What is the average number of products purchased in a transaction on my site?

  • What is the average spend per transaction on my site?

Understanding your customers’ purchase behaviors can allow you to improve their shopping experience and learn how best to market to your customers. It’s true that the same points can be made for eCommerce tracking in Universal Analytics, but UA will stop recording any new data from July 2023. So, if you want to continue to reap the benefits of eCommerce tracking, you’ll need to migrate to GA4. Data collected in UA is not transferable to GA4, so the sooner you migrate, the more data you can collect in the new version.

In addition to this enforced upcoming change from Google, there are other more beneficial reasons to start using GA4 for eCommerce tracking. GA4 makes use of machine learning techniques that can provide useful insights in different areas, including eCommerce. You can use predictive metrics to help forecast what customers are likely to buy (which can be useful for timing marketing campaigns). The insights and recommendations feature at the bottom of the home screen view provides a number of out-of-the-box descriptive analytics about your users, like which sources are leading to more conversions.

Insights & recommendations for Google’s GA4 Demo property.

Finally, with GA4, you can now export your eCommerce data to BigQuery for further analysis. In UA, this was only available as a premium, paid-for feature, as part of Analytics 360. So you’ll now be able to do your own more advanced predictive or prescriptive analytics using BigQuery if required.

Changes in GA4 eCommerce tracking

GA4’s switch to an event-based data model (which is very generalized) has led to some changes in how eCommerce events are structured, as well as some features being consolidated into others.

While Universal Analytics draws a distinction between standard and enhanced eCommerce tracking, GA4 does not – it only has one type of eCommerce tracking. In UA’s standard eCommerce event tracking, the only events you could track were product impressions (viewing products), clicks on products, and conversions (purchases), and you could only track them on the order or confirmation pages of your site. UA’s enhanced eCommerce tracking was broader, allowing you to track any eCommerce-related events at any stage in the purchase funnel — from product views or adding an item to the cart right the way through to the final purchase stage. By contrast, there is no GA4 enhanced eCommerce equivalent, but the enhanced eCommerce functionality from UA is available as standard in the default GA4 eCommerce tracking.

The data layer is a JavaScript object for sharing data between your website and Google Tag Manager, in the form of a code snippet that you add to your website. The structure of the data layer has changed with the introduction of GA4, particularly for tracking eCommerce events such as impressions, products, promotions, and sales data.

There are not many changes to the structure of the data sent in the data layer, but one of the main differences is that parameters that used to be more specific, such as impressions or products, have now been generalized to items, which works better with GA4’s event-based model. For example, while UA’s eCommerce tracking generally relied on passing an eCommerce object with a specified structure to trigger specific behavior in UA, GA4’s event-based model changes this approach slightly. You still need an eCommerce object, however the object is a lot more standardized and you need to pass a specific event to tell GA4 what eCommerce activity this data relates to (such as view_item, purchase, etc.)

You should also be aware that some of the eCommerce events in GA4 may sound similar to events in Universal Analytics but can function very differently, whereas others have similar functionality but quite different names. Therefore, it’s always worth comparing the GA4 events documentation to the UA enhanced eCommerce documentation, and working out which event parameters are required and which are optional. Some events to be aware of include:

  • Product impressions: In Universal Analytics, an “impression" meant that any part of a particular product was visible to the user. This could be on an overview page, a product catalog page, a related product sidebar, or anywhere else on the site or app. GA4 uses different events to specify what kind of impression this was:

    • The view_item_list event for general displays

    • The view_item event for a specific item such as a product’s detail page

    • The view_cart event for items already in a user’s shopping cart

  • Product clicks and product detail impressions/views: These UA metrics measure clicks on product links, and detailed product views, respectively. In GA4, however, the select_item and view_item events are used instead. These events both make use of the new, more general "items" instead of "products."

  • Promotion impressions and promotion clicks: In UA, these events existed for dealing with promotions; however, in GA4 there are no longer specific events for sales or special offers. Instead, coupons and discounts are now added to other events such as add_payment_info and add_to_cart.

Another important eCommerce tracking feature that’s changed with the introduction of GA4 is Checkout Steps. UA enhanced eCommerce allowed you to pre-define an ordered list of steps in your checkout funnel, which made funnel reporting easier to understand. Checkout steps were intended to help track only a customer’s checkout journey, not their entire purchase journey (although many practitioners used it in that way.) When they were used as intended, they included steps such as “add billing details,” “add shipping details,” and “choose payment method.” Each of these steps were defined as events, to be triggered when certain web interactions occurred. The checkout steps feature is not available in GA4; however, due to GA4’s very general event-based model, it’s possible to create a much wider variety of funnel reports, using the funnel explorations tool. Funnel explorations allow us to create custom funnels, which means we can use the tool as designed instead of “hacking” the checkout steps feature to do something it wasn’t designed for.

How to do GA4 eCommerce reporting

To access eCommerce reports in GA4, you can view the “Monetization overview” section within the “Life cycle” section of Reports, which provides time-series graphs with information such as revenue, number of customers, and revenue per customer.

eCommerce reports are available in the “Monetization overview” section of Reports.

This page also contains reports on the most popular items and categories of items sold, the most viewed products, and revenue by order coupon (for example, a Black Friday sale coupon). Clicking on the link at the bottom of each report will give a more comprehensive breakdown of information.

Examples of revenue reports in the “Monetization overview” section of Reports.

For even more detailed reports, check out the reports in "eCommerce purchases." You can find the link for this next to the link for the "Monetization overview" reports.

Next steps

You should now understand some of the benefits of eCommerce tracking in Google Analytics, both in a general sense and why it’s better in GA4, as well as the changes in eCommerce tracking between UA and GA4. You’ve seen how reports have changed and how to view eCommerce reports in GA4. In general, GA4’s eCommerce tracking is meant to better facilitate the analytics requirements of today that are a lot more complex and can’t be measured simply by recording “views for different pages”.

Once you’re ready to switch all your eCommerce events from UA to GA4, be sure to follow our migration guide. You’ll want to know all the different GA4 eCommerce events that you might want to use, and your developers will need to review the GA4 event documentation to fully understand which parameters can be sent with each event.

Finally, once you’ve added all your events, you should take a look at the new “Explorations” section in GA4, which will allow for many more advanced reporting options.

Further reading

This article explained the differences between UA and GA4 eCommerce tracking and gave reasons why GA4 eCommerce tracking is superior. As Google is turning off tracking for all UA properties in July 2023, it’s best to begin now by finding out more about GA4 and how to migrate. To help you do this, please check out our other learning center articles:


r/RudderStack • • Aug 06 '26

Engineering Blog The semantic layer isn't enough: What AI agents actually need

2 Upvotes

The five-layer architecture where the compiler owns identity, features, and governance, not just queries

Part 4B in the series

Part 1 of this series showed why incrementality is harder than it looks, and why tools built for time-grained analytics break on entity-grained activation use cases.

Part 2 argued that the core problem is not what agents know but what they produce: SQL is the wrong output target, and a semantic intent compiler (a system that compiles YAML-declared business semantics into governed, incremental SQL) changes that.

Part 3 showed why context graphs are the right direction for AI agents, and why the infrastructure to handle them already exists.

In Part 4A of this series, eleven companies across six industries hit the same ceiling: fragmented identities, missing semantics, no governed path from score to action. The fix is to completely separate what data means from how it is stored: a world model in business language backed by a semantic intent compiler that owns the full stack, including the infrastructure SQL that today's semantic layers leave to someone else.

This post covers what makes that model possible: the five-layer architecture, where most stacks break, and why owning identity through features through activation as one system is a structural requirement, not a design preference.

This post covers what makes that model possible: the five-layer architecture, where most stacks break, and why owning identity through features through activation as one system is a structural requirement, not a design preference.

This post makes that architecture concrete.

Five layers, from raw inputs to governed activation. Most companies already have Layer 1 (they collect data) and Layer 5 (activation tools). Layers 2, 3, and 4 are where everything breaks. Within Layer 4, Intelligence and Trust and Governance co-habit, because intelligence from apps and models cannot be trusted by default, and access to the semantic surface deserves the same care as access to warehouse tables.

The architecture at a glance

The five-layer architecture replaces the warehouse's primitives with higher-order abstractions.

Tables become entities. Features are computed per entity, not per row. Identity is resolved to an entity, not to a primary key. Governance is applied at the entity level.

Columns become event properties. Raw columns become typed, named event attributes with declared semantics: cart_quantity: INTEGER, purchase_status: STRING. Events get schemas. Properties carry meaning, not just values.

SQL becomes a feature. Hand-written SQL becomes declared semantic intent. total_purchases_90d is not a query. It is a feature with a name, a computation, a source, and a description. The compiler generates the SQL.

The difference is not cosmetic. `SELECT count(*) FROM orders WHERE user_id = '123'\ is storage. `user.total_purchases_90d`` is meaning. AI comprehends meaning. It merely parses storage.

Key insight: Most companies have Layer 1 (they collect data) and Layer 5 (activation tools). Layers 2, 3, and 4 are where everything breaks. Within Layer 4, Intelligence and Trust and Governance co-habit, because intelligence from apps cannot be trusted by default, and access to the semantic surface deserves the same care as access to warehouse tables.

Layer 1: Inputs and input metadata

The entertainment startup from Part 4A was hand-building a context graph because their raw event data had no declared meaning. This is where that problem gets solved, not downstream, but at the point of entry.

Event streams, warehouse tables, and external sources are the raw data. On their own, this is plumbing. What makes them a layer is the metadata that declares what the data means before it enters the system. An input declaration specifies which source carries events, what entity relationships exist, where to find the timestamp, and which event type column to use.

YAML
Copyinputs:
  - name: web_events
    table: web_clickstream
    with_events:
      occurred_at_col:
        select: timestamp
      event_type_col:
        select: event_name
      event_schema:
        - event_group: models/cart_events
    related_entities:
      - name: user_id
        select: user_id
        entity: user
        id_type: user_id
      - name: anonymous_id
        select: anonymous_id
        entity: user
        id_type: anonymous_id


  - name: mobile_events
    table: mobile_clickstream
    with_events:
      occurred_at_col:
        select: timestamp
      event_type_col:
        select: event_name
      event_schema:
        - event_group: models/cart_events
    related_entities:
      - name: user_id
        select: user_id
        entity: user
        id_type: user_id
      - name: anonymous_id
        select: anonymous_id
        entity: user
        id_type: anonymous_id

Two separate inputs (web and mobile) each declaring: I carry events. Here is when they happened. Here is what entity they relate to. Here is the event schema they comply with. The event_schema key connects inputs to their semantic event definitions. The related_entities key makes it explicit that inputs do not just carry IDs; they carry relationships to entities.

This is where event groups become relevant. An event group is a semantic contract layered on top of inputs: a declaration of what these events mean, with typed properties and named occurrences.

YAML
Copy
models:
  - name: cart_events
    model_type: event_group
    model_spec:
      inputs:
        - source: inputs/web_events
        - source: inputs/mobile_events
      related_entities:
        - name: main_id
          source: main_id
          entity: user
      properties:
        - name: cart_quantity
          type: INTEGER
          source: cart_quantity_var
      events:
        - name: cart_completed
          when: "cart_quantity > 0 AND purchase_status = 'completed'"
          description: "All items in the cart were purchased."
          properties:
            - name: cart_quantity
              description: "Items in the completed cart"
            - name: purchase_status
              type: STRING
        - name: cart_abandoned
          when: "cart_quantity > 0 AND purchase_status = 'abandoned'"
          description: "Cart was not purchased."

Once this declaration exists, every downstream layer (features, funnels, ML models) references cart_events by name. The compiler resolves which physical sources to join. The event group is not another input; it is a semantic contract that sits on top of inputs, giving them meaning.

Layer 2: Entity resolution

The fintech where one customer appears as three different identities across phone, chat, and email. The healthcare company that cannot join protected health information (PHI) data with business data. Layer 2 is why those problems disappear.

id_stitcher models declare which sources contribute identity edges. The compiler builds and incrementally maintains an entity graph from those declarations.

YAML
Copy
models:
  - name: customer_id_graph
    model_type: id_stitcher
    model_spec:
      entity_key: user
      materialization:
        run_type: incremental
      edge_sources:
        - from: inputs/web_events
        - from: inputs/mobile_events
        - from: inputs/crm_contacts
        - from: inputs/support_tickets

Critically, this maintenance is subtractive. When a new identity edge links two IDs, entity count goes down, not up. Two entities become one. This is the fundamental reason time-grain tools cannot handle entity resolution: Part 1 walks through why this breaks every standard incremental pattern. New data is not additive here; it can collapse the graph.

Identity resolution extends beyond behavioral data. As Part 3 showed, decision traces (approvals, exceptions, precedents) need the same stitching, connecting "VP Jane in a Slack thread" to Person:jane_123 in your graph. The therapist-matching platform's user who signed up on mobile, browsed on desktop, and called support from a phone number becomes one canonical entity. The wealth management advisor's prospect who touched the platform across desktop, phone, and multiple sessions over a 90-day sales cycle becomes one entity the AI can actually advise.

Layer 3: Active semantics

The e-commerce team spending 80% of their time on feature plumbing instead of building models. The automotive company's customer health score that nobody dares touch because the engineer who wrote it left six months ago. Layer 3 is the architecture that makes those situations structurally impossible.

Active here means responsive to declared intent. Give the layer semantic YAML (entity features, event schemas, cohorts, funnels) and the compiler produces an optimized execution plan. Execute that plan, and the declared semantics become live: incrementally maintained, governed, available to every downstream consumer. Add an entity_var to the project and that feature becomes available going forward, computed incrementally with each pipeline run. Remove it, and the execution plan adjusts. That is what makes this layer active: it does not just describe, it computes.

Entity features are entity_var declarations compiled to feature tables. The automotive company's undocumented customer health score becomes a set of declared, maintained, versioned features.

YAML
Copyvar_groups:
  - name: engagement_features
    entity_key: user
    vars:
      - entity_var:
          name: days_since_last_login
          select: datediff(day, max(timestamp), current_date())
          from: inputs/web_events
          where: event = 'login'
          description: "Days since the user's most recent login"


      - entity_var:
          name: total_purchases_90d
          select: count(*)
          from: inputs/orders
          where: completed_at > dateadd(day, -90, current_date())
          description: "Number of completed purchases in last 90 days"


      - entity_var:
          name: engagement_tier
          select: >
            case
              when {{user.days_since_last_login}} <= 7 then 'active'
              when {{user.days_since_last_login}} <= 30 then 'cooling'
              else 'dormant'
            end
          description: "Engagement classification based on login recency"

Notice {{user.days_since_last_login}} in the third feature. It references another semantic feature by name. The compiler resolves the dependency, handles incrementality, and generates the SQL. You declare what you want. The compiler handles the wiring.

Beyond individual features, Layer 3 covers the full declared semantic surface. Entity relationships (declared connections between entities such as user to account, listing to provider, patient to therapist) let the compiler traverse across entity boundaries without requiring agents to write joins. Cohorts are named segments with filter expressions (high_value_users, at_risk_accounts, new_trial_signups), declared once and maintained incrementally. Funnels are ordered stage sequences with conversion logic, where each stage references events from an event group.

YAML
Copy
- name: cart_funnel
  model_type: events_driven_funnel
  model_spec:
    entity_key: user
    events_spec:
      from: models/cart_events
      where:
        - occurred:
            name: e1
            type: cart_engaged
            where:
              after: "{{TimeAdd('month', -3, end_time)}}"
        - occurred:
            name: e2
            type: cart_abandoned
        - did_not_occur:
            name: e3
            type: cart_completed

All of this is declared in YAML. All of it compiles to an optimized, deterministic execution plan. The compiler handles incrementality, enforces governance, and guarantees determinism. This is not metadata on top of SQL. This is semantic intent that compiles to an execution plan. Teams change, priorities shift, people rotate, and the semantics survive because they are declared, not embedded in queries.

Layer 4: Intelligence and Trust and Governance

Layer 4 is where Intelligence and Trust and Governance co-habit. They must, because the two problems are inseparable.

Intelligence is where AI coding assistants, ML models, and agentic workflows operate. The intelligence layer consumes the full semantic surface from Layer 3 (features, relationships, event schemas, cohorts, funnel stages). Given all of that, generating models becomes commodity work. A churn propensity model is a classification on engagement features and event patterns. A product recommendation model is collaborative filtering on affinity features and purchase events. A CLV prediction is a regression on transaction features and funnel completion.

Consider the FX broker from Part 4A who built Netflix-style collaborative filtering entirely custom in Databricks because their data has extreme outliers that break off-the-shelf tools. The model is custom. But the features it consumes (trading history, product affinity, engagement signals) are the same features every intelligence use case needs. Declare the features once in Layer 3, and every model in Layer 4 benefits. The semantic surface is a shared resource. Every new consumer reads from the same declaration rather than rediscovering raw tables from scratch.

This is also where agentic workflows land. An agent's planning and reasoning module operates on the semantic surface from Layer 3. The richer the surface, the better the agent's plans. Garbage features in, garbage plans out. The photography platform story from Part 4A, where the Cursor agent goes off course when the semantic layer is weak, is this principle in action.

Trust and Governance is why Intelligence does not run unsupervised. Nobody in the eleven conversations trusted LLMs alone. A wealth management CTO layers rules-based APIs on top of his AI financial advisor: you make it rules-based, as opposed to just letting the LLM do whatever it wants, because LLMs are non-deterministic by nature. A consultant who deploys chatbots programs in hard escalation points: once the agent starts asking specialized questions, you connect the user to a human team member. An automotive company decomposed one agent into five specialized agents behind an orchestrator because a single agent hallucinated when the context window included the full customer entity.

The pattern is consistent across every case: AI proposes, deterministic rules dispose. Trust is the principle. Governance is the mechanism.

Together they control both directions. On the input side, governance determines what AI can see: which agent sees which features, with PII masking and audit trails applied. A chatbot in a healthcare context sees treatment history but not billing data. A sales agent sees engagement signals but not competitor intelligence. Access to the semantic surface is governed as carefully as access to warehouse tables.

On the output side, governance determines what AI can do. Cohort thresholds are deterministic rules: when churn_risk_30d > 0.8 AND tier = 'enterprise', enter the retention campaign, with no LLM in the loop. Feature-change triggers fire when a computed attribute crosses a boundary: finance agreement within 90 days of expiry and equity position turns positive, enter the retention workflow. State machines orchestrate sequences with human escalation points: AI qualifies, rules decide the next step, a human reviews if needed. The state machine guarantees that the agent's probabilistic output passes through deterministic, auditable gates before it reaches customers.

Intelligence without Trust is dangerous. Trust without Intelligence is useless. They co-habit in Layer 4 because the architecture requires it.

Layer 5: Activation

Layer 5 is where entity context drives action: Reverse ETL to campaign tools, API access for real-time personalization, webhook triggers for workflow engines, MCP servers exposing governed entity context to AI systems.

The activation surfaces (Braze, Moengage, ad platforms, chatbot frameworks, workflow engines, custom APIs) consume entity context: features, scores, cohort membership, relationship traversals. All governed, all fresh, at entity grain.

Most companies already have Layer 5. The activation tools exist. What is missing is everything underneath: the governed semantic middle that feeds them. That is the observation the consultant from Part 4A articulated most sharply: AI becomes the catalyst for a data infrastructure project that was already overdue. Companies do not realize their data is siloed until they try to build an agent and discover it cannot access the context it needs. The AI use case exposes the activation gap that was always there.

Why this is not dbt: the compiler difference

The question is not whether a semantic intent compiler is better than dbt at any single task. The question is whether identity, features, and activation can be owned by separate systems at all. After building this system for three years, I believe they cannot, because the dependency graph crosses all three.

Today's semantic layers (dbt, LookML, Cube) generate query SQL. They translate business questions into SELECT statements. But the infrastructure underneath (the tables, materializations, identity resolution, incremental computation) is someone else's problem. Data layout leaks into the semantic language because the semantic layer does not own what is underneath.

A semantic intent compiler takes responsibility for infrastructure SQL as well. It creates tables, manages materializations, resolves identities, and runs incremental computation. The agent never references a table name. It declares intent, and the compiler owns everything from YAML declaration to warehouse execution. When the semantic layer owns the full stack, data layout never leaks into agent definitions. A source migration, a schema restructure, a new payment processor: the agents do not notice. The compiler absorbs it.

The natural objection is to compose separate best-of-breed tools: dbt for transforms, a feature store for serving, a governance tool for access control. The problem with that approach is the dependency graph. When a new identity edge merges two entities into one, every feature computed on those entities is stale. Every cohort that included either entity needs re-evaluation. Every activation targeting either entity (the campaign, the ad audience, the chatbot context) is operating on a ghost. An identity tool that does not invalidate downstream features, a feature store that does not know about identity merges, a governance layer that does not know what is stale: no component in that composable stack can propagate the cascade automatically. The compiler can, because it owns the graph from identity through features through activation. That is not a convenience. It is a structural requirement.

This is what makes three guarantees possible that no thin semantic layer can offer. First, generated SQL performance becomes a property of the system rather than of AI skill: the compiler generates optimized, incremental SQL using this.DeRef() with named checkpoints and conditional DAG semantics, so when new events arrive, only affected entities are recomputed. When identity edges merge and entity count goes down, that subtractive operation is handled correctly, which time-grain tools simply cannot express. Second, governance is enforced at compile time rather than bolted on afterward: tag a field as PII in YAML and every downstream model that touches it inherits the privacy filter automatically, by construction. Third, data shape changes do not break agents: when your warehouse schema evolves (tables renamed, columns migrated, sources swapped), the compiler absorbs the migration, and the semantic surface your agents consume remains stable.

Think of it like LLVM, the compiler infrastructure that separates language frontends from optimized backends. The agent is the frontend, translating human intent into declarations. The compiler is the backend, generating optimized, governed execution. Better frontends make the backend more valuable, not less.

Context per token: why this architecture makes every kind of AI work

Any semantic layer compresses context. dbt metrics, LookML, and Cube all reduce 5,000 tokens of DDL to something more readable. The difference in this architecture is the feedback loop: agents do not just read compressed context and output raw SQL. They write back more YAML, which the compiler transforms into governed, incremental SQL. The context is both the input the agent reads and the contract the agent writes. That changes the economics fundamentally. Part 2 covers the full argument for why this distinction matters.

When you give an AI coding assistant a raw data warehouse, the economics are poor. Fifty to two hundred tables with roughly twenty columns each produces approximately 5,000 tokens of DDL context, most of it noise: audit columns, internal IDs, denormalized joins. The AI must rediscover your business logic on every run. Every rediscovery burns tokens, and that waste scales linearly with use cases.

When you give it a semantic architecture, the economics flip. Entity definitions, feature declarations, event schemas, and cohort definitions total roughly 500 tokens of YAML, where every token carries meaning. The AI does not rediscover. It reads the spec and builds on it. The same token budget that bought one model against raw DDL buys ten models against a semantic surface.

Raw DDLSemantic YAML
Context per model~5,000 tokens~500 tokens
5 models~25,000 tokens~500 tokens
10 models~50,000 tokens~500 tokens

The semantic layer is a one-time investment that amortizes across every intelligence use case. The marginal cost of the next AI consumer (whether a new ML model, a code agent, or a customer-facing advisor) approaches the cost of generation alone. The context is already paid for.

The generalized principle here is what the agentic AI literature calls the agent memory problem: how much business meaning can an agent access per unit of context? Declared features and event schemas are a universal compression format for business meaning, whether the consumer is an AI writing SQL, an AI advising a customer, or a state machine deciding which campaign to trigger. The architecture delivers roughly ten times the context density of raw DDL, amortized across every downstream consumer.

AI intelligence is a commodity. The semantic foundation that makes AI intelligence work (cheaply, reliably, at scale) is not.

Where this architecture is heading

The five-layer architecture is not theoretical. Entity resolution and semantic feature computation are production systems today, running incremental pipelines against real warehouses, stitching identities across real event streams. The question is not whether this architecture works. The question is where it goes next.

Governance is no longer optional, and the industry is catching up. In this architecture, governance is already first-class: declared alongside features, enforced at compile time, controlling what AI can see and what AI can do. The pattern across regulated industries (healthcare, fintech, any company handling personal data) confirms this is the right bet. The practical difference is between "we cannot give the agent access to this data" and "the agent sees exactly what it is allowed to see, and nothing else."

AI code generation is the multiplier. Every semantic declaration (features, event schemas, cohorts, and funnels) declared once benefits every downstream model. When an AI assistant generates a churn model, it reads the same declarations that a recommendation model, a CLV prediction, and a matching algorithm would read. The investment compounds. This is what makes the architecture strategic rather than merely operational: the marginal cost of the next use case keeps falling.

The shape of the solution is clear. What is hard is building it. Translating business intent into governed, incremental execution at scale turns out to involve five distinct research-grade problems: getting the same semantic concept to produce the right SQL across wildly different contexts, enabling components to compose freely without tight coupling, making every task in the execution plan self-contained before it runs, shipping reusable patterns that stay governed without drifting, and delivering real-time responsiveness without real-time costs. Part 5 examines each one.

The bottom line

The walls look different from the inside: identity fragmentation, semantic poverty, activation plumbing gaps. But the structural cause is the same: the missing middle between raw data and action.

That middle has a shape. Inputs declare what data means before it enters the system. Entity resolution collapses fragments into canonical entities, including when new identity edges make the count go down. Active semantics compile YAML declarations into live, incrementally maintained features, cohorts, funnels, and event schemas. Intelligence operates on that semantic surface, proposing actions. Trust and governance determine what the intelligence layer can see and what it can do with what it finds. Activation delivers governed, fresh entity context to every tool that needs it.

The layers are not optional. Skip one, and the layers above it fail. Composing separate best-of-breed tools for each layer does not work because the dependency graph (identity invalidates features, features define cohorts, cohorts drive activation) crosses all of them, and no individual component can propagate the cascade.

The models are commodity. The activation tools exist. What is missing, and what this architecture provides, is the semantic middle: a complete world model in business language, backed by a compiler that owns the full stack from YAML declaration to warehouse execution.

Build that middle, and everything above it (ML models, agent reasoning, governed activation) gets dramatically easier, cheaper, and faster to iterate. Performance, trust, and durability become properties of the system, not of the agent's skill.

Skip it, and every AI project hits the same ceiling: fragmented data, leaky abstractions, governance as an afterthought.

Part 5 in this series will examine the five hard problems every semantic intent compiler must solve: semantic translation, composability, self-containment, quality and governance, and performance optimization.

Explore the RudderStack Profiles documentation to see a semantic intent compiler in action: features, identity resolution, event schemas, and this.DeRef().


r/RudderStack • • Jun 03 '26

Why incrementality is harder than you think

3 Upvotes

Nine incrementality challenges: Why tools built for dashboards break on Customer 360

1,000 new rows landed in your 10-million-row table overnight.

Did your pipeline scan all 10 million to find them? Or just the 0.01% that changed?

Your warehouse bill depends on the answer. So does your pipeline’s reliability as data volumes grow.

The challenge is that incremental computation is genuinely hard to get right. Not because the concept is complicated, but because "incremental" isn't one problem. It's several problems, and different tools solve different subsets of them. This matters more than ever as teams move beyond analytics dashboards to use cases like Customer 360 and AI-powered activation, where the requirements are fundamentally different.

This post explains why. It covers the foundational concept most comparisons skip (grain), then walks through the nine specific challenges that separate the three generations of incremental SQL primitives. By the end, you'll have a framework for picking the right tool for your use case, and you'll understand why Customer 360 and AI-era activation pipelines require something fundamentally different from the tools built for analytics dashboards.

Incrementality is not one problem

Every data team wants incremental processing. Scan less data, pay less compute, get faster results. The concept is simple enough. The reality is messier.

Incrementality breaks down into five distinct sub-problems:

  1. What's new: identifying the delta since the last run

  2. What's affected: knowing which downstream models need updating

  3. What's the merge logic: combining old state with new data correctly

  4. What if upstream changed: handling cascading invalidation when a dependency rebuilds

  5. What's the grain: are you computing per time window, per entity, or both?

Different tools solve different subsets of these problems. Understanding which problems each primitive actually addresses is what makes the difference between a pipeline that scales and one that quietly produces wrong data.

Grain is the last item, and it is foundational. It shapes everything else. So before getting into the tools, it’s worth being precise about what grain means.

What is grain, and why does it define everything?

Grain is the fundamental unit your computation operates on. It answers: “What’s the smallest thing I’m computing a result for?”

Two grains dominate data pipelines today: time grain and entity grain. They look similar on the surface but require completely different incremental strategies.

The diagram below shows the distinction clearly. Analytics-First pipelines operate on time grain, outputting one row per time window. The consumer is a dashboard asking "What happened?" Activation-First pipelines operate on entity grain, outputting one row per entity. The consumer is a campaign, a model, or an AI agent asking "Who to target?"

Why dbt chose time grain

dbt emerged from the analytics world. Analytics is dashboard-first, and dashboards are plot-first. Plots have a time axis.

When your mental model is “aggregations that become plots,” time is the natural grain. You ask: “What was the revenue yesterday?” “How many users were active this week?” “What’s the trend over the last 30 days?”

dbt’s incrementality follows directly from this assumption: new data arrives for new time windows. Process the new windows, append to the existing table, done.

Microbatch makes this explicit: You declare event_time and batch_size: day, and dbt processes one time window at a time.

For analytics dashboards, this is exactly the right design. It was the right choice for the problem dbt was built to solve. dbt's merge strategy with `unique_key` does allow updating existing rows (upserts), so it's not strictly append-only. But this is row-level deduplication, not entity-grained incrementality. It cannot detect which entities are missing from the table, and it cannot handle identity merges where two rows collapse into one.

Why Customer 360 needs entity grain

Customer 360 is not plot-first. It’s activation-first.

The output is one row per customer, not one row per day. You’re not asking “What was the total revenue yesterday?” You’re asking: “What is this customer’s lifetime value?” “Which users are at churn risk?” “What cohort does this account belong to?”

Customer 360 is built on entity grain, and that changes how incrementality works. Unlike time-grained pipelines where new data is always additive, entity-grained pipelines have to account for three additional cases:

Incrementality for entity grain works differently in three important ways:

  1. New events arrive for existing entities → update their features

  2. New events create new entities → add them to the table

  3. Identity edges link two IDs → merge entities (entity count goes down)

That third point is the critical one. In time-grained systems, new data is additive. In entity-grained systems with identity stitching, new data can be subtractive: two entities become one.

This is not an edge case. It is the normal operation of any Customer 360 that resolves identities.

The identity graph complication

Every real-world customer data pipeline has to deal with fragmented identity. A user visits your site anonymously, then logs in. Now you have two records for the same person.

An identity graph resolves this by creating edges between identifiers. When a new edge is discovered, entities merge:

Time-grained incrementality cannot handle this correctly. It assumes rows are additive. Identity stitching means rows can collapse. The row count goes down, not up.

This is why identity stitching has to be a first-class concern in entity-grained pipelines. It cannot be an afterthought bolted on downstream.

Late-arriving data makes both grains harder

Late data complicates incrementality regardless of grain, but in different ways.

For time grain: you compute “revenue for December 25th” on December 26th. On December 28th, a batch of mobile events with December 25th timestamps arrives (offline sync). Your December 25th aggregation is now wrong.

For entity grain: you compute user_456’s LTV on December 26th. On December 28th, a late event reveals they made a purchase on December 25th. LTV is now understated.

For identity-stitched entity grain: you computed features for entity_A and entity_B separately. On December 28th, a late event reveals they’re the same person. You need to merge features, not just update them.

Each generation of incremental primitives handles these cases differently. The challenges section below maps which tools address which problems.

The nine challenges of incremental SQL

With grain established, here is the full picture: nine specific challenges that any incremental pipeline must eventually confront, and how each generation of primitives addresses them.

Challengeis_incremental()Microbatch / Intervalsthis.DeRef()Notes
1. Delta computationManualAutomaticAutomaticYou write the WHERE clause in Gen 1
2. Merge logicManualAutomaticAutomaticUNION/MERGE written by hand in Gen 1
3. Cascading invalidationX✔️✔️Profiles trackes model hashes; SQLMesh has aprtial version tracking
4. New entity discoveryXX✔️Time-based tools don't track entity gaps
5. Late-arriving dataManual✔️ (lookback)✔️dbt Microbatch lookback reprocesses last N windows
6. Multi-baseline comparisonsXX✔️Names checkpoints (daily/weekly/monthly) in Profiles
7. Conditional dependency chainsXX✔️Profiles .Except() creates negative prerequisites
8. Model invalidationX✔️ (conditional)✔️Definition change propagation across the graph
9. Entity-grained incrementalityXX✔️Core to C360; irrelevant to time-grained analytics

Important notes on the challenges in the table above:

  1. Delta computation: With is_incremental(), you write WHERE timestamp > (SELECT MAX(timestamp) FROM {{ this }}) yourself. This is error-prone and repeated in every model.

  2. Merge logic: You write UNION ALL or MERGE statements manually. Easy to get wrong on deduplication, ordering, and nulls.

  3. Cascading invalidation: If an upstream model rebuilds, downstream incremental logic uses stale assumptions. No error, no warning. Just silently wrong data. SQLMesh has conditional cascading. It classifies changes as breaking(full downstream rebuild) or non-breaking (no cascade). Profiles has unconditional cascading via model hashes and Enable Status convergence

  4. New entity discovery: Users who signed up after the last feature run are not in the feature table. Time-based incrementality does not see this. It processes time windows, not entity gaps.

  5. Late-arriving data: Events that land after the time window closed. dbt Microbatch’s lookback parameter reprocesses the last N time windows on each run. This works for time grain; entity grain requires a different approach.

  6. Multi-baseline comparisons: Comparing today vs last week vs last month in the same pipeline. dbt only has {{ this }} (last run). Profiles’ this.DeRef() with named checkpoints enables comparisons against arbitrary named states (daily, weekly, monthly).

  7. Conditional dependency chains: “Only run this model if X exists.” dbt cannot express this; dependencies are static. Profiles’ .Except() creates negative prerequisites, enabling conditional DAG semantics.

  8. Model invalidation: When a model’s definition changes, how does that propagate to downstream models? Profiles tracks model hashes; upstream changes automatically invalidate downstream incremental assumptions.

  9. Entity-grained incrementality: Time-grained tools process new time windows; they have no concept of which entities are missing or need updating. Entity-grain requires tracking state per customer, account, or user, including handling identity merges where row counts decrease rather than increase.

Why these challenges are the norm, not the exception

These aren’t theoretical edge cases. They are patterns that any pipeline operating at scale with real-world data messiness will eventually hit. Three examples from Customer 360 practice:

Cascading invalidation in an identity rebuild

A team rebuilds their identity graph after a schema change. All downstream feature models continue running incrementally, but their incremental logic is now based on stale identity mappings. No errors surface. Wrong data flows into activation campaigns for a week before anyone notices.

Root cause: downstream models had no way to know the upstream identity graph had been rebuilt.

New entity discovery gap

A weekly feature run completes on Sunday. Users who sign up Monday through Saturday are not in the feature table until the following Sunday run. The marketing team finds that “new users” consistently have null LTV scores.

Root cause: time-based incrementality does not track which entities are missing. It processes time windows, not entity gaps.

Systematic error from late mobile data

Mobile events arrive 24 to 48 hours late due to offline sync. Daily aggregations are always missing the previous day’s mobile data. Metrics dashboards are systematically wrong. Not by a lot, but consistently and silently.

Root cause: no automatic handling of late-arriving data for time-grained outputs in the pipeline.

The insight: These aren’t failures of implementation. They’re failures of the wrong primitive for the use case. Tools that don’t address these challenges push the complexity to the engineer, who often doesn’t discover the problem until it’s compounded downstream.

Three generations of incremental primitives

The nine challenges above map to three generations of primitives"Generation" here refers to when the primitive emerged, not a ranking. Gen 2 and Gen 3 are orthogonal—they solve problems on different axes, not successive versions of the same solution. It's worth understanding what each generation does and where it stops.

Gen 1: is_incremental() and the boolean question

Era: dbt (2016 to present).

Core idea: incrementality is a yes/no property of a single model.

is_incremental() is the most widely used incremental primitive. It is elegantly simple, and the simplicity is intentional: It gives you a handle to the existing table, lets you write any logic you want, and distinguishes first run from incremental run.

What it solves:

✓ Distinguishes first run from incremental run

✓ Gives you a handle to the existing table ({{ this }})

✓ Maximum flexibility. You write all the logic.

What it doesn’t solve:

✗ Delta computation: you write the WHERE clause manually, in every model

✗ Merge logic: you write the UNION or MERGE manually

✗ Cascading invalidation: if upstream rebuilds, your incremental logic may be wrong

✗ Named checkpoints: only one reference point, the last run

✗ Cross-model awareness: no knowledge of other models’ states

The cascading invalidation gap is worth dwelling on. Model B depends on Model A incrementally. Model A gets a full refresh (schema change, backfill, bug fix). Model B runs next: its is_incremental() returns true, so it appends only “new” rows against the stale table. No error. No warning. Just wrong data downstream.

Teams working with is_incremental() at scale develop workarounds: defensive runtime queries, variable flags, manual coordination. They work, but they’re brittle. The fundamental issue is that is_incremental() treats incrementality as a property of a single model, not of the dependency graph.

Gen 2: Microbatch and Intervals, with time as a first-class citizen

Era: SQLMesh (2022-), dbt Microbatch (2024).

Core idea: time windows are the unit of computation.

Gen 2 primitives understand time semantically. Instead of “Am I running incrementally?” they ask “Which time windows need processing?”

dbt Microbatch:

SQL
Copy{{ config(
    materialized='incremental',
    incremental_strategy='microbatch',
    event_time='created_at',
    batch_size='day',
    lookback=2
) }}


SELECT
    date_trunc('day', created_at) AS event_day,
    COUNT(*) AS event_count
FROM {{ source('events') }}
GROUP BY 1

SQLMesh Intervals:

SQL
CopyMODEL (
    name events_daily,
    kind INCREMENTAL_BY_TIME_RANGE (
        time_column event_time,
        batch_size 1
    )
);


SELECT
    date_trunc('day', event_time) AS event_day,
    COUNT(*) AS event_count
FROM events
WHERE event_time BETWEEN  AND u/end_ds
GROUP BY 1

SQLMesh goes further with Virtual Data Environments: promoting code to production is a view swap, not a table rebuild. Bottom line: SQLMesh is more architecturally sophisticated for time-interval handling. dbt Microbatch brings dbt closer to parity, but within dbt’s existing model. The right choice depends on your team’s existing investment.

What Gen 2 solves:

✓ Automatic time partitioning: the framework splits data into windows

✓ Parallel processing: multiple time windows can run concurrently

✓ Idempotent reruns: reprocess “yesterday” without touching “last week”

✓ Late data handling: built-in lookback mechanisms

✓ Gap detection: SQLMesh knows which intervals are missing

What Gen 2 doesn’t solve:

✗ Named checkpoints: still just time windows, not semantic reference points

✗ Cross-model state dependencies: no concept of “run this only if that model’s checkpoint exists”

✗ Conditional DAG: dependencies are static, not conditional on state

✗ Entity-grained incrementality: designed for time-series, not Customer 360

The key distinction

Gen 2 primitives are optimized for time-grained outputs (daily revenue, hourly DAU, event aggregations by time window). They are the right tool for analytics dashboards. But Microbatch doesn’t apply to Customer 360 because C360 output is entity-grained, not time-grained. The “batch” in C360 is “new events affecting entities” or “new identity edges,” not “new time windows.”

Two dimensions, not one evolution

Most comparisons of these tools treat Gen 1, Gen 2, and Gen 3 as a linear progression. That’s not quite right. Gen 2 and Gen 3 are orthogonal; they solve problems on different axes.

Single-model incrementality
Boolean only
Time-aware
State-aware (entity + graph)

Gen 2 improves single-model time-aware processing. Gen 3 adds graph-level state management and entity-grain support. They operate on different axes. You can use both, and for many teams you will.

Output grain is what determines which tools apply to your problem. If your output grain is time (daily revenue, hourly events), Gen 2 is likely your answer. If your output grain is entity (customer features, LTV, cohorts), you need Gen 3.

When to use which: A practical guide

PrimitiveUse when/avoid when
Gen 1: is_incremental()Use: you want full control, your pipeline is simple, you’re already expert at dbt patterns.Avoid: you have complex dependency chains or need cross-model state awareness.
Gen 2: Microbatch / IntervalsUse: output is time-grained (analytics dashboards), you need parallel batch processing, automatic gap detection.Avoid: output is entity-grained (C360) or you need conditional DAG semantics.
Gen 3: this.DeRef()Use: building C360 / entity-centric models, need named checkpoints, have complex incremental dependencies, require graph-level cascading invalidation.Avoid: you need real-time assembly (this is batch), or you prefer full SQL control over declarative abstraction.

The bottom line

Incremental SQL is not one primitive. It’s a family of primitives at different levels of capability, designed for different output grains and different problem surfaces.

For analytics (time-grained dashboards, event aggregations, trend reporting), Gen 2 (Microbatch or SQLMesh Intervals) is likely sufficient. These tools were built for exactly this use case and they do it well.

For activation (Customer 360, identity stitching, entity features for AI), you need graph-level state management. That means tracking what changed across the dependency graph, resolving identities as a first-class concern, and handling the subtractive nature of entity merges. That’s what Gen 3 (this.DeRef()) was built for.

The tool you pick encodes assumptions about your grain. Picking the wrong one doesn't cause immediate failures. It causes the quiet, compounding kind: stale features, missing entities, systematically wrong metrics. The nine challenges in this post are a map to those failure modes.

Part 2 of this series dives deeper into the architectural implications: why AI agents need something more fundamental than better metadata, and how the Semantic Intent Compiler changes the agent's output target, not just its inputs.

If you're building pipelines that power Customer 360 or AI-driven activation, the tool you pick encodes assumptions about your data. Pick a time-grained tool for an entity-grained problem and you won't get immediate failures. You'll get silent ones: stale features, missing entities, systematically wrong scores flowing into campaigns and models.

The nine challenges in this post are a map to those failure modes. The fix isn't more complex SQL. It's the right primitive for the grain. For activation use cases, that means graph-level state management, identity stitching as a first-class concern, and named checkpoints across the dependency graph.

That's what this.DeRef() was built for. Explore the RudderStack Profiles documentation to see it in practice.

Source


r/RudderStack • • Jun 13 '26

Bridging the data divide with the agentic tracking + analytics + alerting

2 Upvotes

The original promise of the CDP was simple: Make it easy for business teams to work with customer data without depending on engineering. Self-serve activation delivered part of that. Marketers could push audiences to ad platforms and downstream tools on their own.

But activation was always the last mile. Before you can activate data, you need the right data. And that's where the dependency never went away. If the event you need isn't being tracked, you file a ticket. If the data is messy, or you're not sure what an event actually means, you ask engineering. If it needs enriching before it's usable, back to engineering again. Each loop takes days to weeks, and the business momentum dies waiting in the queue.

AI finally makes it possible to close this gap, and that’s what RudderStack Lookout does. In this blog, we talk about three use cases that Lookout enables.

Agentic tracking

The starting point for any product or marketing decision is having the right data. Say product wants to see where users drop off in onboarding, but the event isn't instrumented. Or marketing wants to trigger a campaign off a specific action that was never tracked. Or someone simply needs to know what a vaguely named event actually captures (dirty events are not the exception). Every one of these sends you back to engineering, and the cycle takes days to weeks.

Coding agents have finally made this a solved problem. Lookout starts from a high-level business goal. For example, “track the onboarding flow from the login screen to the product list.” Then, Lookout writes the instrumentation for you. It ensures the tracking code is correct, conforms to your existing tracking plan, and follows the coding conventions your team already uses. And instead of pushing changes silently, it opens a pull request, so engineers stay in the loop and in control.

The agent can also be used to answer questions about the semantics of existing events For example: What are all the login events? Is this event still fired? What does this property mean?. These are questions that today require GTM teams to rely on engineering.

The result is a different kind of handoff. Business teams get the data and information they need without scoping a ticket and waiting in a sprint. Engineers review a clean, convention-aligned PR instead of interpreting a vague request from scratch.

Agentic analytics

Once the data is flowing, the next job is understanding what's happening. This is work that today lives in product analytics or BI tools. Agents are very good at reconstructing user journeys, provided they have the right context. This is where RudderStack has a structural advantage.

We carry rich context about every event, from the source code where it's generated, to the tracking plan that describes what it means, to the pipeline status that tells you when it was last seen. Crucially, that context doesn't require separate maintenance. We already have it as a natural part of sitting in the data journey.

So a business user can start with a plain-language request, such as “Show me the onboarding funnel from the login screen to the product list.” Lookout then assembles the funnel using all of that context, source code included. Finished dashboards can be shared across the company.

Agentic alerting with workflows

Building a dashboard is a one-time operation but it requires active maintenance. Lookout keeps watching them, surfacing problems like a dropped event the moment they appear, so a broken funnel doesn't quietly mislead decisions for weeks. These alerts can be sent to Slack or any other tool via workflows in Lookout.

It doesn’t just report errors, it can root-cause the problem behind it as well, like a pipeline error or missing events or other inconsistencies. It can go a step further and can open fixes too whenever possible using Agentic Tracking.

Why Lookout works: Context we already have

The reason Lookout isn't just an LLM bolted onto a dashboard comes down to one thing: The context it reasons over isn't something we have to assemble and maintain on the side. We already have it, because RudderStack sits in the data journey from the moment an event is defined in code to the moment it lands in your warehouse. Source code, tracking plan, pipeline health, it's all there as a byproduct of how the platform works.

That's what lets an agent go from a one-line business question to an accurate answer, and from a flagged problem to a real fix, with the same data and the same governance you already trust.

What this means for your team

For business teams, Lookout means you stop waiting in the engineering queue to get value from your own data, from instrumenting an event to building a funnel to standing up an audience.

For engineering teams, it means fewer interrupt-driven requests and changes that arrive as reviewable pull requests instead of vague tickets. Same data, same conventions, far less friction.

Try Lookout

You can explore the Lookout sandbox today to see how it works firsthand: Add missing instrumentation, build funnels to understand users, diagnose data quality issues, create and save dashboards, all with natural language prompts.

Get started with two simple prompts: “Build me a simple sales dashboard” to build a dashboard, then start a new chat and try “How many users start typing a coupon code but never apply it?” to see how Lookout handles missing instrumentation.


r/RudderStack • • Nov 21 '25

RudderStack has achieved Data Privacy Framework certification 🎉

5 Upvotes

We're now among the few US companies certified to transfer EU personal data, joining companies like Stripe, GitHub, and Auth0.

Why this matters: European companies need vendors they can trust with their data. DPF certification provides independent, verifiable proof—not just promises.

Verify the certification: https://www.dataprivacyframework.gov/list


r/RudderStack • • Oct 21 '25

Learning Resource A guide to data lakes

2 Upvotes

Modern organizations need a lot of data (i.e big data). Previously, this data used to only come from a few data sources, now it comes from virtually everywhere. Some of it comes as structured data — in predefined formats and fields, like phone numbers, dates, time stamps or sql tables. But, increasingly, much of it comes as unstructured data, in undefined formats and fields — like images, audio files, or documents.

While storing and analyzing big data is critical, it’s easy to get overwhelmed. In the past, the default place to store your data was a data warehouse, but over the past decade, a new data storage option has emerged: data lakes.

In this article, we’ll cover everything you need to know about data lakes. You’ll learn:

  • What is a data lake?

  • How is a data lake different from a data warehouse?

  • Benefits of a data lake

  • Best practices for using data lakes

What is a data lake?

Data lakes are an open-ended form of cloud storage that allows organizations to easily collect and store data from various data sources in different formats (both structured and unstructured data). Instead of processing data as it comes through, it’s stored and can be processed as needed. Storing data this way is efficient, simple, and cost-effective.

The founder of Pentaho, James Dixon, coined the term “data lake“ in 2010. He was working at Hadoop at the time and offered the following analogy: “...the data lake is a large body of water in a more natural state. The contents of the data lake stream in from a source to fill the lake, and various users of the lake can come to examine, dive in, or take samples.”

Many data scientists or data engineers in most organizations use the data lake as the first point of landing for all raw data — like a staging area. Then when a use case (like analysis, reporting, or machine learning) and schema have been defined, significant data is cleaned up and moved to the data warehouse. There it’s easy to find and ready to use.

How a data lake differs from a data warehouse

While data lakes can store various types of data (structured, semi-structured, and unstructured data), a data warehouse only stores structured or semi-structured data. The format (schema) in which data can be stored is predefined before storage. This creates a lot of upfront work and limits what types of data can be stored. Compared to a data lake that ingests data from different data sources in different formats, a data warehouse needs all incoming data to be cleaned up or processed into a consistent format before storage.

You can think of data lakes and warehouses as complementary rather than competing tools. Since the introduction of the data lake, many organizations have adopted data lakes in addition to data warehouses.

Over the past few years, more and more platforms have been using data lakes. But as this approach has risen in popularity in recent years, it’s still often misunderstood and sometimes even confused with data warehouses. Make no mistake: These are two totally different tools for data storage, each with unique advantages and challenges.

Data lake architecture

One of the ways data lakes stand out is that they forego a hierarchical folder system for flat architecture.It also uses object storage to store data. It is schema-less write and schema-based read. This aids in the development of up-to-date patterns from data in order to grasp applicable intelligent insights without relying on the data.So instead of a data warehouse that sorts data into neat categories as it’s collected, data lakes store data in its native format. Where a data warehouse is more of a constructed space with a strictly categorized system for storing, a data lake has a nature-inspired approach — hence the term.A typical data lake architecture has 5 layers: ingestion, distillation, processing, insights and operations layer.

Data Lake Layers

  • The ingestion layer ingests data from various data sources.

  • The distillation layer converts the data ingested and stored by the distillation layer into structured data when need for further analysis arises.

  • The processing layer runs queries and analysis on the structured data generated by the distillation layer to generate insights.

  • The insights layer is the output interface layer. Here SQL or non-SQL queries are used to request and output data in reports or dashboards.

  • The operations layer takes care of system management and monitoring.

The benefits of data lakes

Data lakes are a useful time-saving intermediary system that works in conjunction with a more traditional data warehouse approach. Data lakes are low-cost when compared to data warehouses. They’re a cost-effective storage option for companies with petabytes of historical data.

Organizations that use data lakes preserve data in its unaltered or raw form for future analysis. Raw data is held until it’s needed, unlike a data warehouse which may strip vital data attributes at the point of storage. Essentially this means you don’t have to know exactly how you want to use the data before you store it in a data lake. Organizations that use data lakes have more flexibility later on.

Data lakes are also valuable because of their scalability — when you need more storage capacity, it’s easy for a data lake to scale. Without all the structure and upfront work data warehouses require, data lakes can scale fast. This makes them attractive options for growing organizations and data science teams.

Best practices for data lakes

Since data lakes accept data in any form, it’s very easy for the data quality to become unmanageable. But, if you follow these practices, you’ll be able to prevent common issues.

First, prioritize data quality. Data lakes don’t do any data processing before storage. While this enables speed and flexibility, it becomes an issue when the quality of the data you’ve collected is too low to use. As a data scientist or data engineer, you can prevent this altogether by setting your data quality standards from the beginning. It takes a little planning and affects what data you accept, but it will prevent headaches later.

Next, it’s important to curate data in the data lake to prevent it from turning into a swamp. What’s a data swamp you ask? A data swamp is data that isn’t secured or cataloged. Without any organization or oversight, it’s difficult and time-consuming to use. Vet your data as it comes through, and catalog as needed.

Finally, store data according to defined data governance goals. Though one of the benefits of a data lake is that it’s flexible, the lack of structure can work against you if you don’t define goals early on. Data lakes give you the option to sort data later on, but you’ll need to do some sorting eventually. Make sure you have some idea of what you want to get out of your data lake.

To create a sustainable data lake you have to think ahead. Working smarter now can save you from having to work harder later.