ServiceNow
CSDM End to End: How a Single Outage Traces from a Linux Box to a Business Service (With Tables, Queries, and the Stuff Nobody Explains)
What this article is
I have set up CSDM in multiple enterprise instances and the one thing I can tell you is — the official documentation gives you a model diagram and a list of tables, but nobody walks you through what actually happens when a server goes down at 2 AM and someone needs to know which business service just broke.
This article does that. One scenario, end to end. Every layer of CSDM, every table involved, every relationship that matters, and the GlideRecord queries to prove it.
The scenario
Your company runs an online ordering system. Customers place orders on the website, the order goes through a payment gateway, hits an order processing API, writes to a database, and triggers a fulfillment workflow. All of this runs on a handful of Linux servers in AWS.
At 2:14 AM on a Tuesday, one of the database servers runs out of disk space. The order processing API starts throwing 500 errors. Within minutes, the website checkout page is broken. Customers cannot complete purchases.
Here is the question CSDM answers: how does the on-call engineer — and then the VP of Commerce — know that a full disk on server DB-PROD-03 means the "Online Ordering" business service is down?
The layers — bottom to top
CSDM is not one flat table. It is a stack of layers, each representing a different level of abstraction. The official model has 7 domains now (CSDM 5.0), but for understanding the core service chain, you need to internalize these layers:
| Layer | What it represents | Table | Example in our scenario |
|---|---|---|---|
| Infrastructure CIs | Physical or virtual compute, storage, network | cmdb_ci_server, cmdb_ci_linux_server, cmdb_ci_database | DB-PROD-03 (Linux server), OrderDB (MySQL instance) |
| Application | A discoverable running software instance | cmdb_ci_appl | Order Processing API (Node.js app running on APP-PROD-01) |
| Service Instance / Application Service | A logical grouping of applications and infra that delivers a specific technical capability | cmdb_ci_service_auto | "Order Processing Service" — the API + database + message queue working together |
| Business Application | A logical, governed representation of a software system in the portfolio | cmdb_ci_business_app | "Online Ordering Platform" — the application as leadership knows it |
| Business Service | A service published to the business, visible to users and executives | cmdb_ci_service_business | "Online Ordering" — the thing the VP of Commerce talks about in quarterly reviews |
| Business Service Offering | A specific flavor or tier of a business service with SLA commitments | service_offering | "Online Ordering - Production" (99.9% SLA) vs "Online Ordering - Staging" (best effort) |
The relationships — how they connect
The layers above are useless without relationships between them. This is where most CSDM implementations fail. Teams populate the tables but never build the connections.
ServiceNow stores CI relationships in the cmdb_rel_ci table. Each row says "CI A is related to CI B with relationship type X."
// The relationship chain for our scenario: // // DB-PROD-03 (cmdb_ci_linux_server) // | // | "Hosts" relationship // v // OrderDB (cmdb_ci_database) // | // | "Used By" relationship // v // Order Processing API (cmdb_ci_appl) // | // | "Members Of::Contains" relationship // v // Order Processing Service (cmdb_ci_service_auto) <-- Application Service // | // | "Depends On::Used By" relationship // v // Online Ordering Platform (cmdb_ci_business_app) // | // | "Managed By::Manages" relationship // v // Online Ordering (cmdb_ci_service_business) <-- Business Service // | // | related via service_offering table // v // Online Ordering - Production (service_offering) <-- with SLA commitments
Without these relationships, when DB-PROD-03 fills up, the incident just says "server disk full." Nobody knows it affects ordering. With CSDM relationships, the impact chain is visible immediately — and automated.
Setting it up — the practical steps
Step 1: Create the Business Service
Start from the top. The business service is what executives care about. You do not start with servers.
// Navigate to: cmdb_ci_service_business.list
// Create new record:
// Name: Online Ordering
// Owned by: VP of Commerce (sys_user reference)
// Support group: E-Commerce Operations (sys_user_group)
// Operational status: Operational
// Install status: Installed
// Business criticality: 1 - Most Critical
// Or via script:
var bs = new GlideRecord('cmdb_ci_service_business');
bs.initialize();
bs.name = 'Online Ordering';
bs.owned_by = 'sys_id_of_vp_commerce';
bs.support_group = 'sys_id_of_ecom_ops_group';
bs.operational_status = 1; // Operational
bs.install_status = 1; // Installed
bs.busines_criticality = 1; // Most Critical
bs.insert();
Step 2: Create the Business Application
// Navigate to: cmdb_ci_business_app.list
// Create new record:
// Name: Online Ordering Platform
// Owned by: Engineering Manager
// Managed by business service: Online Ordering
// SDLC lifecycle stage: Production
var ba = new GlideRecord('cmdb_ci_business_app');
ba.initialize();
ba.name = 'Online Ordering Platform';
ba.owned_by = 'sys_id_of_eng_manager';
ba.install_status = 1;
ba.insert();
Step 3: Create the Application Service (Service Instance)
This is the operational grouping. It represents the deployed technical stack that delivers a capability.
// Navigate to: cmdb_ci_service_auto.list
// Create new record:
// Name: Order Processing Service
// Owned by: Lead SRE
// Managed by application: Online Ordering Platform
// Environment: Production
var as = new GlideRecord('cmdb_ci_service_auto');
as.initialize();
as.name = 'Order Processing Service';
as.owned_by = 'sys_id_of_lead_sre';
as.install_status = 1;
as.insert();
Step 4: Build the relationships
This is the part that makes CSDM actually work. Without relationships, you just have disconnected records.
// Create relationship: Application Service -> Business Application
// "Depends On::Used By"
var rel = new GlideRecord('cmdb_rel_ci');
rel.initialize();
rel.parent = ba.sys_id; // Business Application (upstream)
rel.child = as.sys_id; // Application Service (downstream)
rel.type = 'sys_id_of_depends_on_used_by_rel_type';
// Look up relationship type sys_id:
// var rt = new GlideRecord('cmdb_rel_type');
// rt.addQuery('name', 'Depends on::Used by');
// rt.query(); rt.next(); // rt.sys_id is what you need
rel.insert();
// Create relationship: Business Service -> Business Application
var rel2 = new GlideRecord('cmdb_rel_ci');
rel2.initialize();
rel2.parent = bs.sys_id; // Business Service
rel2.child = ba.sys_id; // Business Application
rel2.type = 'sys_id_of_manages_managed_by_rel_type';
rel2.insert();
// Infrastructure CIs (servers, databases) are typically
// populated by Discovery, not manually. Discovery scans your
// network, finds running services, and creates the CIs
// and their relationships automatically.
The 2 AM outage — how CSDM makes it visible
Now the disk fills up on DB-PROD-03. An event fires. An incident is created. Here is what happens with CSDM in place versus without it.
Without CSDM
// Incident created: // Short description: Disk space critical on DB-PROD-03 // CI: DB-PROD-03 // Priority: calculated from impact/urgency, but nobody knows // what this server actually affects // Assignment group: Linux Admins // // The Linux admin sees a disk full alert. Cleans up temp files. // Meanwhile, orders are failing for 45 minutes. // The VP finds out from a customer tweet, not from ServiceNow.
With CSDM
// Incident created: // Short description: Disk space critical on DB-PROD-03 // CI: DB-PROD-03 // // ServiceNow automatically traces the impact: // DB-PROD-03 hosts OrderDB // OrderDB is used by Order Processing API // Order Processing API is part of Order Processing Service // Order Processing Service supports Online Ordering Platform // Online Ordering Platform is managed by "Online Ordering" business service // "Online Ordering" is Business Criticality: 1 - Most Critical // // Incident auto-escalated to P1. // Assignment group: E-Commerce Operations (from business service support group) // VP of Commerce gets an automatic notification. // SLA clock starts ticking on the 99.9% commitment.
Querying the impact chain
Here is the script that walks the relationship chain from a CI to its business service. This is what happens under the hood during impact analysis.
// Given a CI sys_id (e.g., the failing database server),
// find all business services impacted.
function getImpactedBusinessServices(ciSysId) {
var visited = {};
var businessServices = [];
function walkUp(sysId, depth) {
if (visited[sysId] || depth > 10) return;
visited[sysId] = true;
// Check if this CI is itself a business service
var check = new GlideRecord('cmdb_ci_service_business');
if (check.get(sysId)) {
businessServices.push({
name: check.getValue('name'),
owner: check.getDisplayValue('owned_by'),
criticality: check.getDisplayValue('busines_criticality')
});
return;
}
// Find upstream CIs (parents in relationships)
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('child', sysId);
rel.query();
while (rel.next()) {
walkUp(rel.getValue('parent'), depth + 1);
}
}
walkUp(ciSysId, 0);
return businessServices;
}
// Usage:
var impacted = getImpactedBusinessServices('sys_id_of_db_prod_03');
impacted.forEach(function(svc) {
gs.info('IMPACTED: ' + svc.name + ' | Owner: ' + svc.owner +
' | Criticality: ' + svc.criticality);
});
// Output: IMPACTED: Online Ordering | Owner: VP Commerce | Criticality: 1 - Most Critical
CSDM 5.0 — what changed and what you actually need to know
The model went from 5 domains in 4.0 to 7 domains in 5.0. Most of the additions are about strategic planning and AI, not about the core service chain. Here is what matters practically:
| What changed | Old name | New name / addition | Why it matters |
|---|---|---|---|
| Application Service renamed | Application Service | Service Instance (Application Service is now a subtype) | Other service types added: Data Service, Network Service, etc. Your existing Application Services still work — just reclassified. |
| Technical Service renamed | Technical Service | Technology Management Service | Just a label change. Same table, same function. |
| New: Ideation & Strategy domain | Did not exist | Product Ideas, Strategic Priorities, Goals, Targets | Connects strategic planning to service delivery. Matters for SPM users, not for day-to-day ITSM. |
| New: AI Data Model | Did not exist | dm_ai_system_digital_asset, AI Function, AI Application | If you are deploying Now Assist or AI agents, these CIs track your AI components in the CMDB. |
| New: SBOM | Did not exist | Software Bill of Materials | Tracks software component dependencies. Critical for SecOps vulnerability scanning. |
| New: Value Streams | Did not exist | Value Stream entity in Foundation domain | Maps how work flows to deliver value. Connects to Process Mining. |
For most teams doing ITSM, the core chain (Infrastructure → Application Service → Business Application → Business Service) has not changed. CSDM 5.0 is additive — it does not break your existing model.
The adoption path — Crawl, Walk, Run, Fly
ServiceNow recommends a phased approach. I have seen teams try to jump to "Run" and it always fails. Here is what each phase actually means in practice:
| Phase | What you do | What you get |
|---|---|---|
| Foundation | Clean up locations, departments, groups, users. Get your org structure right. Define lifecycle statuses. | Basic data hygiene. Nothing CSDM-specific yet, but without this the rest falls apart. |
| Crawl | Create Business Services and Business Applications. Assign owners. Map them to each other. | Portfolio visibility. Executives can see which apps support which services. No infra mapping yet. |
| Walk | Create Application Services. Connect them to infrastructure CIs via Discovery. Build the full relationship chain. | Impact analysis works. Incidents on a CI can trace to business services. Change risk assessment uses service context. |
| Run | Service Mapping validates relationships continuously. CMDB Health tracks completeness. Lifecycle management enforced. | Trusted, maintained CMDB. Automation depends on it. Now Assist uses it for context. AI agents query it. |
| Fly | Full CSDM 5.0 with Value Streams, SBOM, AI models, strategic alignment. | Enterprise-wide service intelligence. Not many organizations are here yet. |
Where teams get it wrong
I have watched enough CSDM implementations to know the patterns that kill them:
- Starting with infrastructure. Teams spend 6 months loading servers into CMDB and never get to business services. Start from the top. Business services first, then work down.
- No ownership. Every Business Application and Business Service needs an owner. If the
owned_byfield is empty, nobody is accountable. Nobody maintains the data. It rots. - Missing relationships. 500 CIs with zero relationships is a flat spreadsheet, not CSDM. The value is in the connections between layers. Run this query regularly:
// Find business applications with no relationships at all
var ba = new GlideRecord('cmdb_ci_business_app');
ba.addQuery('install_status', 1); // Installed
ba.query();
while (ba.next()) {
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', ba.sys_id);
rel.addOrCondition('child', ba.sys_id);
rel.setLimit(1);
rel.query();
if (!rel.next()) {
gs.info('ORPHAN: ' + ba.getValue('name') + ' has zero relationships');
}
}
- Using custom tables instead of CSDM tables. I have seen teams create
u_my_servicesinstead of usingcmdb_ci_service_business. Then Service Mapping does not work. Impact analysis does not work. Every ServiceNow product that reads service data expects the CSDM tables. Use them. - Treating CSDM as a one-time project. It is not. Services change, apps get retired, new infrastructure spins up. You need ongoing governance — Discovery schedules, Health Dashboard monitoring, ownership reviews. Set up a recurring monthly check or it degrades within a quarter.
The health check query
Run this to get a quick read on your CSDM maturity:
// CSDM Health Check - run in Background Scripts
var tables = [
{name: 'cmdb_ci_service_business', label: 'Business Services'},
{name: 'cmdb_ci_business_app', label: 'Business Applications'},
{name: 'cmdb_ci_service_auto', label: 'Application Services (Service Instances)'},
{name: 'service_offering', label: 'Service Offerings'}
];
tables.forEach(function(t) {
var gr = new GlideRecord(t.name);
gr.addQuery('install_status', 1);
gr.query();
var total = gr.getRowCount();
// Count those without owners
var noOwner = new GlideAggregate(t.name);
noOwner.addQuery('install_status', 1);
noOwner.addNullQuery('owned_by');
noOwner.addAggregate('COUNT');
noOwner.query();
var unowned = noOwner.next() ? parseInt(noOwner.getAggregate('COUNT')) : 0;
gs.info(t.label + ': ' + total + ' total, ' + unowned + ' without owner (' +
(total > 0 ? Math.round(unowned/total*100) : 0) + '% unowned)');
});
// Check relationship coverage
var bs = new GlideAggregate('cmdb_ci_service_business');
bs.addQuery('install_status', 1);
bs.addAggregate('COUNT');
bs.query();
var totalBS = bs.next() ? parseInt(bs.getAggregate('COUNT')) : 0;
var withRel = 0;
var bsGr = new GlideRecord('cmdb_ci_service_business');
bsGr.addQuery('install_status', 1);
bsGr.query();
while (bsGr.next()) {
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', bsGr.sys_id);
rel.addOrCondition('child', bsGr.sys_id);
rel.setLimit(1);
rel.query();
if (rel.next()) withRel++;
}
gs.info('Business Services with at least one relationship: ' +
withRel + '/' + totalBS + ' (' +
(totalBS > 0 ? Math.round(withRel/totalBS*100) : 0) + '%)');
How this connects to interview questions
If an interviewer asks you about CSDM, they are not looking for you to recite the 7 domains. They want to hear:
- That you understand why CSDM exists — connecting technical failures to business impact
- That you know the actual table names —
cmdb_ci_service_business,cmdb_ci_business_app,cmdb_ci_service_auto,cmdb_rel_ci - That you can describe a real scenario where CSDM changes the outcome — like the 2 AM outage above
- That you know the adoption path is phased, not big-bang — Foundation, Crawl, Walk, Run
- That you have an opinion on where teams fail — no ownership, no relationships, custom tables instead of OOB
That combination — table knowledge, scenario thinking, and implementation experience — is what separates someone who read a blog post from someone who has actually done it.