As Db2 DBAs we often find ourselves chasing two elusive targets: speed and capacity. We want our systems to handle everything all at once, and we want it done yesterday. But as database architectures evolve and workloads grow increasingly complex, DBAs must constantly manage the delicate, often misunderstood relationship between two fundamental metrics: Concurrency and Throughput.
It’s easy to mistake one for the other, or to assume that maximizing one automatically boosts the other. But the two are not the same. Let’s break down what these terms really mean for your Db2 for z/OS subsystems and why balancing them is the key to a healthy production environment.
Defining the Duo
Before we look at how they interact, let’s establish a clear baseline for both concepts.
Concurrency is the database's ability to handle multiple interactive sessions, transactions, or users at the exact same time. It’s a measure of simultaneous access. Think of it as the number of lanes on a highway. More lanes typically mean that more cars can be on the road simultaneously.
Throughput is the actual amount of work successfully completed by the database per unit of time (e.g., transactions per second, rows processed per minute). If concurrency is the number of lanes on the highway, throughput is the number of cars that actually pass through the toll booth every hour.
In an ideal world, as concurrency increases, throughput rises right along with it. But database systems don't operate in a vacuum. They are bound by physical limitations: CPU, memory, I/O bandwidth, and, most importantly, locking and latching mechanisms.
The Concurrency Curve: When More Becomes Less
If you increase the number of concurrent threads entering your Db2 subsystem, throughput will generally scale linearly, at least up to a point. But eventually you hit a tipping point that is referred to as the "knee of the curve."
Beyond this point, adding more concurrent users doesn't get more work done. Instead, it breeds contention.
When too many transactions fight for the same resources, Db2 spends more time managing the queue than doing actual work. You’ll start to see symptoms like:
High internal latch contention.
Increased lock wait times and, worst-case scenario, spikes in deadlocks and timeouts.
Elongated class 3 suspension times in your accounting reports.
At this stage, you haven't plateaued your throughput... you’ve actually degraded it. You are burning CPU just to manage the traffic jam.
Db2 Mechanisms to Balance the Scale
Maximizing throughput while maintaining healthy concurrency requires an understanding of Db2’s internal mechanics. Here are the core areas where DBAs can tip the scales back in their favor:
1. Lock Avoidance and Isolation Levels
Locks are the primary gatekeepers of concurrency. The best way to improve concurrency is to avoid locking altogether when safe. Ensure your application packages are bound with CURRENTDATA(NO) to allow Db2 to use lock avoidance techniques. Furthermore, when appropriate, consider dirty reads. If an application can tolerate reading uncommitted data, UNCOMMITTED READ (UR) blows the doors wide open for concurrency because it doesn't acquire read locks.
Note: it has been my experience that far too many programs and SQL statements use UR. Although removing locks with UR improves concurrency, it can damage data quality if used inappropriately.
2. Thread Management (MAX REMOTE ACTIVE / MAX ONLINE)
It is not an uncommon misconception that letting every single request hit the engine at once improves throughput. It really doesn’t. Leveraging Db2’s thread pooling and setting intelligent limits on MAX REMOTE ACTIVE (for distributed workloads via DDF) ensures that work is queued efficiently before it can thrash the engine.
3. Page-Level vs. Row-Level Locking
Row-level locking (LOCKSIZE ROW) sounds like a silver bullet for concurrency because it minimizes the footprint of a lock. However, it comes with a steep price tag: you might experience considerable CPU overhead for lock acquisition and management. If your throughput is CPU-bound, using LOCKSIZE PAGE (combined with smart page splitting and small row sizes) might actually increase your overall throughput by freeing up CPU cycles.
The trade-off between row and page locks depends on understanding the nature of the application accessing the data and its current execution profile. If there are contention problems when accessing a table space that is currently set to LOCKSIZE PAGE you might consider altering it to LOCKSIZE ROW and then monitoring the impact on performance, resource consumption, and concurrency.
The Bottom Line
Mainframes are designed to process massive, mind-boggling volumes of concurrent data better than almost anything else on earth. But the laws of database physics still apply.
To achieve maximum throughput, you cannot simply crank the concurrency dial to eleven and hope for the best. You must monitor your buffer pools, optimize your indexing to minimize table scans, design your applications for short commit scopes, and precisely configure your subsystem parameters.
Remember: True database performance isn't about how many transactions you let through the door at once; it's about how fast you can successfully get them out the exit.


