DEV Community

Cover image for Palantir Made Ontology Hot — Can APM Troubleshooting Stop at Ontology Alone?
databufflabs
databufflabs

Posted on • Originally published at databuff.ai

Palantir Made Ontology Hot — Can APM Troubleshooting Stop at Ontology Alone?

"Ontology" is back in fashion. Palantir Foundry is not pitched as yet another data warehouse — it builds an ontology for the enterprise: tables, streams, and sensors become "Customer," "Order," and "Device," with relationships and actions defined so data becomes a world model programs can reason over. LLMs made the pitch louder — models still need to know what exists in the world.

For our field: what is the APM ontology? And if you build it, does incident triage just work? Two separate questions.

Q1 · How to build an APM ontology

An APM ontology is two steps: extract entities and relationships from traces, then materialize them into metric tables.

Setup: service A has instances A-1 and A-2; two endpoints; both call database DB and run the same SQL1. Four traces:

# service instance endpoint call sql
T1 A A-1 ep1 DB SQL1
T2 A A-1 ep2 DB SQL1
T3 A A-2 ep1 DB SQL1
T4 A A-2 ep2 DB SQL1

Step 1 — extract. From T1: entities are service A, instance A-1, endpoint ep1, database DB, SQL1. Relationships: A has instance A-1; A exposes ep1; A-1 serves requests on ep1; ep1 calls DB; ep1 executes SQL1; DB has statement SQL1. P99, latency, and call count are not entities — they are observations attached to entities.

All four traces together:

  • Service hasInstance Instance: A → A-1, A-2
  • Service exposes Endpoint: A → ep1, ep2
  • Instance serves request on Endpoint: A-1 / A-2 both serve ep1 and ep2
  • Endpoint calls DB: ep1 → DB; ep2 → DB
  • Endpoint executes SQL: ep1 → SQL1; ep2 → SQL1
  • DB hasStatement SQL: DB → SQL1

Step 2 — materialize. Extracted entities become queryable metric tables. In DataBuff's Doris layer (schema is open source), dimension columns are entities; call_count / resp_time are observations:

Table Dimensions Observations Entities
metric_service service call_count / resp_time / error_count Service
metric_service_instance service + instance same Service, Instance
metric_service_http service + instance + endpoint same Service, Instance, Endpoint
metric_service_db service + instance + db + sql db calls / db latency Service, Instance, DB, SQL

Aggregating the four traces:

  • metric_service: service A → 1 row, 4 entry calls
  • metric_service_instance: by instance → 2 rows
  • metric_service_http: by instance + endpoint → 4 rows
  • metric_service_db: by instance + DB + SQL → 2 rows

Ontology done: traces tell you what exists and what connects; metric tables materialize those entities.

Q2 · Is ontology enough?

Entities and relationships complete — is troubleshooting solved? Consider how a connection pool actually behaves:

Connection pool branches an ER diagram cannot capture

Even if you add ConnectionPool as Service → ConnectionPool → Database, you only label the big boxes. The branches and states in between cannot be covered by adding one more entity — that layer is logic:

a) Acquire: idle → return; can grow → create; pool full → lock wait; timeout → error
b) Use / return: run SQL → return → wake waiters
c) Background maintenance: heartbeat, evict stale connections

Entity-only reasoning fails when an endpoint slows down:

Ontology only With logic
Reasoning endpoint → DB, slow ⇒ DB slow stuck in lock wait, SQL never ran
Symptom endpoint latency up DB execution may be fine
Conclusion root cause is DB root cause is waiting for a connection

First principles: program = data + logic.

Ontology Logic
Manages what exists, who connects how requests flow, where they stall
Locks onto target entities last-mile root cause
Without it no drill-down target stuck at "something is wrong"

Connection pool is one slice — it shows entity-only is not enough. See how DataBuff breaks down latency for one endpoint:

DataBuff endpoint latency breakdown

Entry average ~240ms; breakdown shows HTTP service-b ~100ms, RPC service-b ~80ms, remainder in MySQL, ES, Redis, Kafka. That is logic modeling for one entry — track entry latency and state, then each operation type after the entry.

Q3 · How to model logic

Scale to a real app: track latency and state for every entry, and for each operation type after every entry. Entries include RPC, HTTP, MQ consumers, scheduled jobs, and more.

After a request enters, it typically lands in 5 operation types + 1 behavior:

Type Key dimensions
DB remote operation dal group / table / operation / sql
Redis remote operation command
MQ remote operation exchange / routingKey / vhost
RPC remote operation downstream service / remote method
Local operation no extra attributes yet
Thrown exception exception name

For remote operations, split latency into three parts:

a) Client: connect, send, receive
b) Network: transport
c) Server: peer execution

Pool-full lock wait accrues on the clientwaiting for a connection ≠ slow SQL.

Incidents then follow one chain: which entries → local ops → remote ops (down to SQL/method) → network vs server → exceptions.

Ontology locks entities; logic locks root cause. Logic models entry → operation → remote three-part latency → exception, with latency and state at each layer. For AI to separate "waiting for a connection" from "slow SQL," it must land on entities via ontology, then walk this logic chain to the actual reason.

Top comments (0)