---
title: "Signals vs Chalk | Snowplow Signals"
description: "Chalk assumes your data sources exist. Signals collects the behavior first. Where the two overlap on serving, and when it makes sense to run both."
source: https://signals.snowplow.io/evaluate/chalk
---

[Evaluate](https://signals.snowplow.io/evaluate) / Signals vs Chalk 

# Chalk starts at the feature. Signals starts at the event. 

Both serve values fast enough to sit in a request path. They differ on what they expect to find already in place, on when the value is computed, and on who is meant to be holding the keyboard.

[Start free](https://signals.snowplow.io/start) [Talk to an engineer](https://signals.snowplow.io/start?intent=engineer) 

The short answer

1. 01  
Both serve computed values with latency low enough for a live request, and both take the problem of stale batch features seriously.
2. 02  
Chalk begins at the feature definition and resolves from the sources you point it at. Those sources are your responsibility.
3. 03  
Signals begins at collection, validates behavioral events against a schema on the way in, and computes attributes from them.

Written for architects comparing a feature platform against real-time customer context.

Side by side

## Both fast in a request path, different assumptions about what feeds them. 

| Dimension                 | Signals                                                                                            | Chalk                                                                                   |
| ------------------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| What you bring            | An SDK in your app. Behavioral events are collected and schema-validated on the way in.            | Data sources to resolve from. Collection and event schema are out of scope.             |
| Where behavior comes from | Built in. Web, mobile and server SDKs feed the same governed schema.                               | Wherever you already put it. If there is no behavioral stream, that is a project first. |
| Primary consumer          | Application surfaces and agents first, models second.                                              | Models and the engineers who build features for them.                                   |
| Who defines an attribute  | A product manager in the console, or an engineer in code through CI/CD.                            | An engineer, in Python, in the platform's own resolver model.                           |
| Entity keys               | Any entity: user, session, account, basket, listing, store.                                        | Supported, but the entity has to exist in the sources you resolve from.                 |
| Attribute update latency  | <1s from the event to the attribute being current.                                                 | Depends on the source being resolved and how it is cached.                              |
| Serving latency           | 6ms p50, 10ms p95 in-region. One call returns a whole service.                                     | Designed for request-path latency, varying with the resolvers in the path.              |
| Real-time triggers        | Conditions evaluated continuously, delivered to your app or to Braze, Kafka, webhooks and Pub/Sub. | Not the focus. Acting on a condition is a system you build beside it.                   |
| Deployment                | Managed SaaS or a private deployment in your own cloud, identical architecture.                    | Managed, or a private deployment in your own cloud account. The two are level here.     |

Based on published vendor documentation at the time of writing · confirm against the current product before quoting it

Choose Signals when 

The behavioral events do not exist yet, or exist and nobody trusts them.

The consumer is a product surface or an agent, not only a model.

A product manager needs to define an attribute without opening an engineering ticket.

You want triggers on live conditions in the same system that computes the attributes.

The event schema needs governing at collection rather than assumed correct downstream.

Choose Chalk when 

Your data sources are already in place, and resolving across them is the hard part.

The people defining features are engineers who want to express them in Python.

Your inputs come mostly from operational databases and third-party APIs rather than behavior.

The ML feature lifecycle, rather than the application surface, is what you are buying for.

You do not need collection, schema governance or triggers in the same product.

They can coexist

## Signals can be the behavioral source Chalk resolves against. 

Pattern 01 

### Signals for behavior, Chalk for everything else

Let Signals own the live behavioral half, and keep resolving your operational and third-party sources where they already are.

Pattern 02 

### Signals for the application path only

Models keep reading the feature platform. The storefront, the agent and the service desk read Signals at request time.

Pattern 03 

### Signals instead, for now

Teams whose inputs are overwhelmingly behavioral start on Signals and add a feature platform later if the model estate demands it.

6ms 

p50 in-region read, one call per service

<1s 

Event in to attribute current

1 definition 

Shared by live serving and the training set

any key 

user · session · basket · listing · store

Objections worth raising

## The questions your architect will ask. 

### Do these two actually compete?

They overlap on serving values fast enough for a request path. They diverge on collection, on governance of the event schema, and on whether a non-engineer can define an attribute.

### We already have our behavioral data somewhere. Does the collection advantage matter?

Only if you trust it. The question to ask is whether a new attribute needs a data engineering ticket today, and how long that ticket takes.

### Can we run both?

Yes. The clean split is behavior in Signals, operational and third-party sources resolved where they already live.

### What happens when serving is unreachable?

The SDK reports it and marks values stale, and your application decides whether to fall back or degrade the surface. Worth putting the same question to Chalk, because a resolver that reaches a live source at request time has more places to fail.

## Test it against your own behavior. 

Define one attribute, read it from your product, and see how much of the work was collection rather than computation.

[Start free](https://signals.snowplow.io/start) [Talk to an engineer](https://signals.snowplow.io/start?intent=engineer) 

The real engine · no card · no sales call Also in Evaluate: [Signals vs a feature store](https://signals.snowplow.io/evaluate/feature-stores), [Signals vs building it yourself](https://signals.snowplow.io/evaluate/build-vs-buy), [Signals vs a CDP](https://signals.snowplow.io/evaluate/cdps), [Signals vs Tecton](https://signals.snowplow.io/evaluate/tecton), [Signals vs Feast](https://signals.snowplow.io/evaluate/feast), and [pricing →](https://signals.snowplow.io/pricing)
