Monday, September 7, 2026

YAML and JSON Explained: Two Formats, One Purpose

Introduction

In today's cloud-native and automation-driven world, configuration files play a critical role in defining infrastructure, applications, and workflows. Two of the most widely used data serialization formats are YAML (YAML Ain't Markup Language) and JSON (JavaScript Object Notation). Whether you are working with Kubernetes manifests, Ansible playbooks, REST APIs, CI/CD pipelines, or configuration management tools, you are likely to encounter one or both formats regularly.

A common question among developers and system administrators is: "Are YAML and JSON the same?" The short answer is no, but they are closely related. Both formats are designed to represent structured data such as key-value pairs, lists, and nested objects. In fact, the same information can often be expressed in either YAML or JSON, making them functionally similar in many scenarios.

This blog explores the similarities and differences between YAML and JSON, explains why both formats continue to coexist, and highlights their practical applications in Linux, DevOps, automation, and cloud environments. By the end, readers will understand when to choose YAML, when JSON is a better fit, and why modern platforms often support both.


Example

JSON

{

  "name": "David",

  "role": "Test Architect",

  "skills": ["Linux", "Python", "Automation"]

}

YAML

name: David

role: Test Architect

skills:

  - Linux

  - Python

  - Automation

Similarities

  • Both represent structured data (key-value pairs, lists, nested objects).
  • Both are commonly used for configuration files.
  • Most YAML files can be converted to JSON and vice versa.
  • Tools like Kubernetes, Ansible, GitHub Actions, and OpenShift use YAML, while APIs commonly use JSON.

Differences

Feature

JSON

YAML

Readability

More verbose

More human-readable

Syntax

Uses {}, [], ,

Uses indentation

Comments

Not supported

Supported using #

Complexity

Simpler and stricter

More flexible

Common Use

APIs, data exchange

Configuration files


Why people say "YAML and JSON are the same"

They usually mean:

"They can represent the same data structure."

For example, the JSON above and YAML above contain exactly the same information, just written in different formats.

In  Linux/Automation context

You will typically see:

  • JSON: API responses, Elastic/Kibana data, Bugzilla/Jira APIs.
  • YAML: Kubernetes manifests, Ansible playbooks, GitHub Actions, OpenShift configurations, CI/CD pipelines.

For example, a Kubernetes Pod definition is usually written in YAML:

apiVersion: v1

kind: Pod

metadata:

  name: test-pod

Internally, Kubernetes converts this YAML into a JSON-like structure for processing.



Conclusion

YAML and JSON serve the same fundamental purpose: representing and exchanging structured data. While JSON is compact, strict, and widely used for machine-to-machine communication and APIs, YAML focuses on human readability and ease of maintenance, making it the preferred choice for configuration files and infrastructure-as-code frameworks.

The statement that "YAML and JSON are the same" is only partially correct. They are different formats with distinct syntax and capabilities, but they can represent the same underlying data structures. This compatibility is one reason why many modern tools, including Kubernetes, support YAML while internally converting it into JSON for processing.

For Linux administrators, automation engineers, and DevOps practitioners, understanding both formats is essential. YAML simplifies configuration management and infrastructure definitions, while JSON remains the backbone of APIs, data exchange, and application integrations. Rather than competing technologies, YAML and JSON complement each other, each excelling in the environments for which they were designed.

As automation and cloud-native technologies continue to evolve, mastering both YAML and JSON will remain a valuable skill for anyone working in modern software development and infrastructure management. 

Saturday, August 29, 2026

Understanding NUMA Nodes and NUMA Topology in Large IBM Power Servers

Introduction

As server architectures continue to grow in scale, modern systems can contain hundreds of processor cores and terabytes of memory. Managing memory efficiently becomes critical to achieving optimal performance. This is where NUMA (Non-Uniform Memory Access) architecture comes into play.

In a NUMA-based system, processors and memory are organised into groups called NUMA nodes. Each NUMA node consists of a set of CPU cores and memory that are physically closer to each other. Accessing local memory within the same NUMA node is significantly faster than accessing memory located in another node. This design helps improve scalability and reduces memory access latency in large enterprise servers such as IBM Power systems.

Understanding NUMA nodes and NUMA topology is essential for system administrators, performance engineers, virtualization architects, and Linux developers, especially when working with large configurations, virtualization technologies, and memory-intensive workloads.

NUMA Node: A group of CPUs and memory that are physically close to each other.

NUMA Topology: The layout/map showing how all NUMA nodes are connected inside a server.

For your PowerVM work, think of NUMA as "keeping the CPU and its memory in the same neighbourhood so they can talk faster." 

NUMA Node = CPU neighbourhood + its local memory.

Best performance occurs when a workload's CPUs and memory stay in the same neighbourhood. When CPUs must fetch data from another neighbourhood, performance drops due to remote memory access.



Step 1: Understanding the Diagram

The diagram shows:

  • 256 CPU cores
  • 1 TB Memory
  • 16 NUMA Nodes
  • Each NUMA node contains:
    • 16 CPU cores
    • 64 GB Memory

NUMA Node Layout

NUMA Node

CPU Cores

Memory

Node 0

0-15

64 GB

Node 1

16-31

64 GB

Node 2

32-47

64 GB

Node 3

48-63

64 GB

Node 4

64-79

64 GB

Node 5

80-95

64 GB

Node 6

96-111

64 GB

Node 7

112-127

64 GB

Node 8

128-143

64 GB

Node 9

144-159

64 GB

Node 10

160-175

64 GB

Node 11

176-191

64 GB

Node 12

192-207

64 GB

Node 13

208-223

64 GB

Node 14

224-239

64 GB

Node 15

240-255

64 GB


Step 2: Physical Interpretation

Imagine the server has 4 processor sockets.

Socket 0

 ├── NUMA 0

 ├── NUMA 1

 ├── NUMA 2

 └── NUMA 3


Socket 1

 ├── NUMA 4

 ├── NUMA 5

 ├── NUMA 6

 └── NUMA 7


Socket 2

 ├── NUMA 8

 ├── NUMA 9

 ├── NUMA 10

 └── NUMA 11


Socket 3

 ├── NUMA 12

 ├── NUMA 13

 ├── NUMA 14

 └── NUMA 15

Each NUMA node has its own local memory.


Step 3: How Workloads Get Mapped

Example 1: Database Workload

Suppose Oracle or PostgreSQL starts.

Linux scheduler may place:

Database Process

     |

     +--> CPUs 0-15

     |

     +--> Memory from Node 0

Result:

CPU ---> Local Memory

Fastest possible access ✅


Example 2: Java Application

Suppose JVM requires:

  • 32 cores
  • 128 GB memory

Linux may place it across:

Node 4

Node 5

CPUs 64-95

Memory 128 GB

This is still good because nodes 4 and 5 are neighbours.


Example 3: SAP HANA

Large memory workload:

64 Cores

256 GB Memory

Linux may distribute across:

Node 8

Node 9

Node 10

Node 11

Socket 2

Everything remains inside one socket.

Performance is excellent.


Step 4: Bad Mapping Example

Suppose workload threads run here:

CPU Node 0

but memory gets allocated here:

Memory Node 15

Diagrammatically:

CPU Core 2

     |

     |

     +---------------------------+

                                 |

                                 V

                           Memory Node 15

Now every memory access crosses multiple interconnects.

Effects:

  • Higher latency
  • Lower throughput
  • More cache misses
  • Poor benchmark numbers


Step 5:  LPM

Before migration:

LPAR

  CPUs -> Node 0

  Memory -> Node 0

Everything local.

CPU 0

  |

  +--> Memory 0

After migration (bad case):

CPU 0

  |

  +-------------------> Memory Node 12

Remote memory access.

If Application slows down due to above mentioned selection , there are new research with solutions around this problem.


Step 6: Example MaxConfig Workload Placement

Workload A (Kernel Build)

16 Cores

32 GB Memory

Placement:

NUMA Node 0


Workload B (Stress-ng)

32 Cores

64 GB Memory

Placement:

NUMA Node 1

NUMA Node 2


Workload C (Database)

64 Cores

256 GB Memory

Placement:

NUMA Node 4

NUMA Node 5

NUMA Node 6

NUMA Node 7


Workload D (AI/ML)

128 Cores

512 GB Memory

Placement:

NUMA Node 8-15


How Linux Decides

You can view actual placement using:

numactl --hardware

Show NUMA layout.

numastat -p <pid>

Show memory used by each NUMA node.

numactl --show

Show current NUMA policy.

lscpu | grep NUMA

Show NUMA configuration.


In simple terms: NUMA is all about keeping processors and their data in the same neighbourhood so they can communicate faster and work more efficiently


Conclusion

NUMA architecture plays a crucial role in the performance and scalability of modern multi-socket servers. By grouping processors and memory into NUMA nodes, systems can provide faster local memory access and reduce communication overhead across the server. The NUMA topology serves as a roadmap that describes how these nodes are interconnected and how data flows between them.

For large Power systems and MaxConfig environments, understanding NUMA behaviour is essential for workload placement, performance tuning, virtualization, and Live Partition Mobility (LPM). Keeping CPU threads and memory within the same NUMA node whenever possible helps minimise latency and maximise application performance. As server configurations continue to grow in size and complexity, NUMA awareness becomes a key factor in achieving efficient and predictable system performance.