Real-time serving
By defining features on top of operational data sources (Redis, JDBC, REST APIs), FeatureMesh serves features as production APIs. Serving uses the same FeatureQL language as batch analytics—not a reduced query subset—so the logic doesn't diverge between training and serving. Production designs usually bind small, bounded inputs and optimize for predictable latency under concurrency.
Latency is dominated by your sources, not by us. Evaluation is a compiled prepared statement on DataFusion, in Rust, vectorized, and the engine parallelizes independent fetches across the graph. If PostgreSQL answers in 500ms, the response is around 508ms. Overhead grows with the volume of data being processed, so a graph moving large payloads costs more than one fetching a few scalars. The number that matters is your own: run it against your sources and measure.
How it works
Register the real-time sources you need:
CREATE FEATURE REDIS_SRC AS SOURCE_REDIS('redis://localhost:6379' WITH (timeout='100ms'));
CREATE FEATURE POSTGRES_SRC AS SOURCE_JDBC('postgresql://db:5432/prod' WITH (tables=ARRAY['customers']));
CREATE FEATURE API_SRC AS SOURCE_HTTP('https://api.risk.com' WITH (timeout='200ms'));
CREATE FEATURES AS
PERSIST
CUSTOMERS := ENTITY(),
CUSTOMER_ID := INPUT(BIGINT#CUSTOMERS),
-- Profile tier from Redis. KEY_TO_SCALAR drops #CUSTOMERS so the key can be text.
PROFILE_TIER := EXTERNAL_REDIS(
KEY 'customer:' || CAST(KEY_TO_SCALAR(CUSTOMER_ID) AS VARCHAR)
FIELD 'tier'
FROM REDIS_SRC
),
-- Customer balance from PostgreSQL. The bound column carries the same entity as the input.
CUSTOMER_DATA := EXTERNAL_COLUMNS(
customer_id BIGINT#CUSTOMERS BIND TO CUSTOMER_ID,
balance DECIMAL
FROM VIEW(POSTGRES_SRC[customers])
),
BALANCE := CUSTOMER_DATA[balance],
-- Credit score from a microservice
CREDIT_SCORE_JSON := EXTERNAL_HTTP(FROM API_SRC WITH (query_params=ROW(CUSTOMER_ID AS id))),
CREDIT_SCORE := JSON_PARSE_AS(CREDIT_SCORE_JSON, TYPE 'ROW(score INT)')[score]
;
Define derived features on top:
CREATE FEATURES AS
PERSIST
ELIGIBLE_FOR_LOAN := (CREDIT_SCORE > 650 AND BALANCE > 1000) OR PROFILE_TIER = 'VIP'
;
Create a prepared statement for low latency serving:
CREATE FEATURE ELIGIBLE_FOR_LOAN_PS AS
PREPARED_STATEMENT(
ELIGIBLE_FOR_LOAN
USING CUSTOMER_ID
);
Query it from anywhere:
curl -X POST "http://localhost:10090/v1/featureql" \
-H "Content-Type: application/json" \
-d '{
"statement": {
"id": "ELIGIBLE_FOR_LOAN_PS",
"inputs": {"customer_id": [12345]}
}
}' A single request fetches data from Redis, PostgreSQL, and an HTTP API, evaluates the feature graph, and returns the result. The engine handles parallelization, connection pooling, and caching.
Why not a microservice?
The typical alternative is a custom microservice: a team writes the eligibility logic in Python or Java, deploys it behind an API, and maintains it. The logic is invisible to anyone who doesn't read that codebase.
With FeatureMesh, the logic is in the registry. ELIGIBLE_FOR_LOAN is queryable, auditable, and reusable. The lending API, the mobile app, the fraud system, and the analytics dashboard all use the same definition. When the rule changes, you update one feature, not four implementations.
This also removes the deployment cycle for logic changes. Updating a feature definition changes production behavior without shipping code. That cuts both ways, so the registry is the control: every change is validated against its downstream dependents before it takes effect, lifecycle states (DEV, BETA, ACTIVE, DEPRECATED) keep unstable logic out of production, and VARIANT() with GRADUAL_ROLLOUT() lets you put a change in front of a fraction of traffic before committing to it.