Evaluate/Build vs buy

What building this yourself actually costs.

The cost of running an in-house profile service, row by row, next to buying the same capability.

Side by side

Everything after the first attribute.

DimensionSignalsBuild it yourself
Event collectionAdd the SDK and collection starts, schema-validated on the way in.Collectors, a schema registry and failed-event handling, before any attribute can be trusted.
Where it runsManaged SaaS, or a private deployment in your own AWS or GCP account with the same architecture.Your cloud, run by your team.
Streaming computeDescribe the attribute once. Windowing, late events and hot keys are handled in the engine, not in your code.A Flink or Spark Streaming job per attribute family. Windowing, watermarks, late events, state size.
Low-latency storeManaged store, read in 10ms at p95, in-region.Pick Redis, DynamoDB or Aerospike. Design the key schema. Solve hot keys, TTLs, eviction and cold caches.
Serving APIIncluded. Your app asks Signals with one GET.Build it, rate-limit it, and keep it inside the request path's latency budget.
AuthenticationScoped API keys exchanged for a short-lived token. Attribute reads stay server-side; triggers reach the browser through the browser plugin.Service credentials, key rotation, and a safe way to reach the browser without shipping a secret to it.
GovernanceEvery attribute group is versioned with a named owner. Editing a published one creates a new version, and the old one keeps serving until you unpublish it. Preview against recent events before you publish.Nobody can say which version of an attribute production is reading, or who owns it. An upstream change breaks it silently.
Historical featuresTurn on backfill and a new attribute is filled from Snowflake, BigQuery or Databricks on publish.A second pipeline out of the warehouse, plus reconciliation when batch and stream disagree.
Training and serving parityOne definition, computed live and from history. Structurally the same attribute.Your problem. The notebook feature and the production feature drift within weeks, and nobody notices until a model degrades.
Training datasetsLabeled, point-in-time correct datasets from the serving definitions. Name the goal event, get the table in your warehouse (Snowflake today).Hand-built point-in-time joins. One mistimed join leaks future data into training, and the model fails only in production.
Identity and keysKey attributes on anything you track. Pair with Snowplow Identities for deterministic resolution.Build stitching or accept fragmented IDs. Non-user entities need a second key schema, usually a second store.
The next attribute, and the one afterA definition change, deployed from the console or CI/CD.More platform work each time, queued behind everything else.
Self-servicePMs define attributes in the console, so the ticket never reaches you.None. Every new attribute is a ticket to your team.
TriggersReal-time triggers, delivered to your app or to Braze, Kafka, webhooks and Pub/Sub.A whole second system for condition evaluation, delivery, deduplication and outcome logging.
Handing it to a coding agentAn SDK call and one GET. Point your coding agent at the docs, the agent skill or the MCP server and it will wire it up.An agent can write the streaming job. It cannot own the state, the rebuilds or the pager after launch.
On-callOurs, including the 3am page.Your platform team, indefinitely, for a system in the request path. Long after its author has moved teams.

Build column describes a typical in-house streaming stack. Signals latency from the load-test benchmark, in-region.

Buy when

The roadmap has product work on it that this project would displace.

Nobody on the team wants to own a stateful streaming service at peak.

You need training and serving definitions to agree, permanently.

The value is in the attributes, not in the pipeline that computes them.

Build when

Real-time attribute serving is itself your differentiator.

You already run the streaming stack, staffed, with capacity to spare.

Requirements are unusual enough that no vendor model fits.

Regulatory constraints rule out both managed SaaS and a deployment in your own cloud.

6ms

p50, in-region API round trip

10ms

p95. Load-test benchmark

<1s

Event in to attribute updated

1 definition

Streaming for now, batch for history

Objections worth raising

The questions your architect will ask.

Isn't this just a stream processor and a cache?

The first attribute is. The rest of the table is the work: late events, hot keys, batch and stream reconciliation, triggers, and the on-call rotation. That is the part teams underestimate.

Are we locked in?

Events are yours and land in your warehouse. Definitions are portable. Leaving costs you the engine, not the data.

Our coding agent could build a version of this in an afternoon.

It could build the first attribute, a counter in a cache behind a function. History, late events, batch and stream parity and the rota are the same work on any stack, however it was written. Point the agent at Signals instead and the afternoon ends with something you don't have to own.

Do we need real time at all?

Not always. If next-day is fine, a nightly warehouse job is cheaper than either option on this page. Signals earns its place when the product has to react inside the session.

What if our attribute logic is unusual?

Counts, recency and ordering over windows such as ten minutes, this session or since last purchase cover the common cases. Raise the unusual ones early and we will tell you plainly whether they fit.

How do we justify this internally?

Compare against a staffing plan, not a license fee. The build cost is mostly people, and it does not end at launch.

Test the claim on your own events.

Define one attribute, read it from your product, and compare the latency to whatever you run today.