Nested LLD
Automation via Low-Level Discovery (LLD) rarely stops at a single infrastructure layer. In complex environments you frequently deal with hierarchical structures: a database server hosting multiple instances, each containing multiple tablespaces; a hypervisor running virtual machines that each have multiple virtual disks; or a storage array with pools, volumes and LUNs.
Previously, monitoring these layered structures required separate discovery rules or custom multi-stage scripts. Starting with Zabbix 7.4, Nested LLD (discovery prototypes of type Nested) lets you build multi-level discovery hierarchies from a single data stream. A nested discovery rule reuses the JSON payload of its parent and applies preprocessing to extract and process a specific slice of that same data.
In this chapter we explore how Nested LLD works, walk through a complete configuration example, and briefly cover its use with host prototypes.
Note
This chapter assumes you are already familiar with the core concepts of Low-Level Discovery and Dependent Items. If you need a refresher, refer to the previous section on LLD with dependent items.
Nested LLD requires Zabbix 7.4 or later.
Creating Our Example Data
Before implementing the discovery rules we need structured data. Consider a database server that returns a JSON payload containing database instances and their tablespaces.
Log in to your Zabbix server or agent host via SSH and create the following file:
echo '[
{
"database": "db_sales",
"status": "online",
"tablespaces": [
{ "name": "ts_sales_data", "size_mb": 10240 },
{ "name": "ts_sales_idx", "size_mb": 4096 }
]
},
{
"database": "db_hr",
"status": "online",
"tablespaces": [
{ "name": "ts_hr_data", "size_mb": 2048 }
]
}
]' | sudo tee /home/db-cluster-status.json > /dev/null
Verify the file:
The structure has two clear levels:
- Level 1 (Parent): Database instances (
db_sales,db_hr) - Level 2 (Nested): Tablespaces belonging to each database
Step 1: Master Item and Parent LLD Rule
1. Create the Master Item
In the Zabbix frontend go to Data collection → Hosts, select your host, then Items → Create item.
| Field | Value |
|---|---|
| Name | RAW: Database cluster metrics |
| Type | Zabbix agent |
| Key | vfs.file.contents[/home/db-cluster-status.json] |
| Type of information | Text |
Tip
Use the Test button to confirm that the agent can read the file and returns the expected JSON.
Any item that produces valid JSON can serve as master item (HTTP agent, trapper, script item, etc.). A file-based item is used here purely for simplicity.
2. Create the Parent Discovery Rule
Navigate to Discovery rules on the same host and click Create discovery rule.
| Field | Value |
|---|---|
| Name | Discover databases |
| Type | Dependent item |
| Master item | RAW: Database cluster metrics |
| Key | db.discovery |
On the LLD macros tab map:
3. Create an Item Prototype for Level 1
Under the parent discovery rule go to Item prototypes → Create item prototype.
| Field | Value |
|---|---|
| Name | Status of database {#DB} |
| Type | Dependent item |
| Master item | RAW: Database cluster metrics |
| Key | db.status[{#DB}] |
| Type of information | Text |
Preprocessing:
Step 2: Configuring the Nested Discovery Prototype
We now want to discover the tablespaces of each database without an extra agent check or external query. This is done with a discovery prototype of type Nested.
How Nested type works
When the type is set to Nested, Zabbix does not re-fetch data. Instead it passes the individual JSON object that belongs to the currently discovered parent entity to the nested rule.
For the database db_sales the nested rule therefore receives:
{
"database": "db_sales",
"status": "online",
"tablespaces": [
{ "name": "ts_sales_data", "size_mb": 10240 },
{ "name": "ts_sales_idx", "size_mb": 4096 }
]
}
Preprocessing on the nested rule can then extract the next level ($.tablespaces).
1. Create the Discovery Prototype
Inside the parent rule Discover databases, open the Discovery prototypes tab and click Create discovery prototype.
| Field | Value |
|---|---|
| Name | Discover tablespaces for {#DB} |
| Type | Nested |
| Key | db.tablespace.discovery[{#DB}] |
Including {#DB} in the key guarantees uniqueness per parent entity.
2. Preprocessing on the Discovery Prototype
On the Preprocessing tab add:
This extracts the tablespace array from the single database object that the Nested type already provided.
3. Nested LLD Macros
On the LLD macros tab of the discovery prototype:
Note
LLD macros defined on the parent rule ({#DB}) are automatically inherited
and remain available inside nested discovery prototypes and all of their
child prototypes.
4. Item Prototypes for the Nested Level
Inside the discovery prototype go to Item prototypes → Create item prototype.
| Field | Value |
|---|---|
| Name | Size of tablespace {#TSNAME} on {#DB} |
| Type | Dependent item |
| Master item | RAW: Database cluster metrics |
| Key | db.ts.size[{#DB},{#TSNAME}] |
| Type of information | Numeric (unsigned) |
Preprocessing:
JSONPath Breakdown:
- $.. searches recursively through the original master item JSON.
- [?(@.database=='{#DB}')] filters the specific database instance.
- .tablespaces[?(@.name=='{#TSNAME}')] filters down to the matching tablespace object.
- .size_mb.first() extracts the integer value without returning array brackets.
Because the item is a dependent item of the original master item, the JSONPath
must locate the correct value inside the full original payload. Parent and nested
macros ({#DB} and {#TSNAME}) make the path unique.
Nested LLD on Discovered Hosts (Host Prototypes)
Nested LLD also extends to Host Prototypes. When Zabbix generates a new host entity from a Host Prototype, it passes the JSON object of that discovered entity down to any template attached to the host prototype.
If a template attached to a host prototype contains a Nested LLD rule:
Typical pattern:
- Root host runs a discovery rule that creates host prototypes (one host per database, for example).
- The template linked to those host prototypes contains a Nested LLD rule that discovers the next level (tablespaces, disks, …).
- Items and triggers for the nested level appear directly on the generated hosts.
This combination is powerful for multi-level inventory (hypervisors → VMs → disks, clusters → nodes → services, etc.).
Key Advantages of Nested LLD
- Unlimited hierarchical depth – Server → Database → Tablespace → Table, or any other hierarchy you need.
- Zero extra network or agent overhead – every level is extracted from the single JSON payload collected by the master item.
- Context preservation – parent LLD macros stay available at deeper levels, keeping item keys unique and readable.
- Cleaner configuration – one master item and a tree of discovery prototypes replace multiple independent discovery rules or custom scripts.
Questions
- What is the primary operational benefit of selecting the Nested type on a discovery prototype compared to creating a standard LLD rule?
- How are LLD macros from a parent discovery rule made available to nested LLD item prototypes?
- What role does the preprocessing step play on a Nested discovery prototype when the parent JSON contains nested arrays?