‹ All essays

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:

LayerWhat it representsTableExample in our scenario
Infrastructure CIsPhysical or virtual compute, storage, networkcmdb_ci_server, cmdb_ci_linux_server, cmdb_ci_databaseDB-PROD-03 (Linux server), OrderDB (MySQL instance)
ApplicationA discoverable running software instancecmdb_ci_applOrder Processing API (Node.js app running on APP-PROD-01)
Service Instance / Application ServiceA logical grouping of applications and infra that delivers a specific technical capabilitycmdb_ci_service_auto"Order Processing Service" — the API + database + message queue working together
Business ApplicationA logical, governed representation of a software system in the portfoliocmdb_ci_business_app"Online Ordering Platform" — the application as leadership knows it
Business ServiceA service published to the business, visible to users and executivescmdb_ci_service_business"Online Ordering" — the thing the VP of Commerce talks about in quarterly reviews
Business Service OfferingA specific flavor or tier of a business service with SLA commitmentsservice_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 changedOld nameNew name / additionWhy it matters
Application Service renamedApplication ServiceService 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 renamedTechnical ServiceTechnology Management ServiceJust a label change. Same table, same function.
New: Ideation & Strategy domainDid not existProduct Ideas, Strategic Priorities, Goals, TargetsConnects strategic planning to service delivery. Matters for SPM users, not for day-to-day ITSM.
New: AI Data ModelDid not existdm_ai_system_digital_asset, AI Function, AI ApplicationIf you are deploying Now Assist or AI agents, these CIs track your AI components in the CMDB.
New: SBOMDid not existSoftware Bill of MaterialsTracks software component dependencies. Critical for SecOps vulnerability scanning.
New: Value StreamsDid not existValue Stream entity in Foundation domainMaps 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:

PhaseWhat you doWhat you get
FoundationClean 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.
CrawlCreate 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.
WalkCreate 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.
RunService 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.
FlyFull 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_by field 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_services instead of using cmdb_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.