Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Why your database benchmarking data is probably wrong (and how I fixed mine)

Eliminating hidden bottlenecks in AWS RDS PostgreSQL benchmarking

June 5, 2026
Krishna Magar
Related topics:
Application development and deliveryCloud services
Related products:
Red Hat OpenShift

    We've all been there. You've spent hours architecting a performance test, convinced you're about to uncover groundbreaking insights. You spin up a big RDS instance, fire up HammerDB, and wait for those "new orders per minute" (NOPM) numbers to skyrocket. But instead, you get a flat line (or worse, a zig-zag). You double the number of virtual users, but the throughput doesn't budge. When I started benchmarking AWS RDS PostgreSQL performance, I expected a straightforward "plug-and-play" experience. Instead, I found that without rigorous optimization, you aren't measuring your database's power—you're measuring the limitations of your testing environment. Here's how I identified and eliminated the hidden bottlenecks that were sabotaging my data.

    1. The observer effect: When the benchmarker becomes the bottleneck

    In performance benchmarking, the load generator itself can become the limiting factor if it lacks sufficient resources to sustain the intended workload. When this happens, the benchmark no longer reflects the true capacity of the system under test, but instead the limits of the client generating requests.

    The problem:

    As I increased concurrent users, the performance metrics (NOPM/TPM) stopped scaling and remained mostly flat. At first glance, it appeared that the database had stalled or reached saturation. However, the database CPU utilization remained relatively low, indicating the database was not actually under heavy stress.

    Reality check

    The real bottleneck was the HammerDB client itself. My driver instance (initially an m7i.4xlarge) was consistently reaching 85%+ CPU utilization. In this state, the client struggled to efficiently manage worker threads, scheduling, and network operations. As a result, it could not generate transaction requests fast enough to fully utilize the database. The apparent throughput plateau was therefore caused by client-side saturation rather than a database limitation.

    The fix

    To eliminate the load generator as a bottleneck, I upgraded the client instance to an m7i.12xlarge. By significantly over-provisioning the driver environment, I ensured sufficient CPU and system headroom for workload generation. This shifted the bottleneck away from the client and allowed the benchmark to accurately stress the RDS endpoint and capture reliable throughput characteristics.

    2. I/O illusion: CPU-bound vs disk-bound

    If you are trying to test a CPU's compute power, you must ensure it isn't waiting on the storage layer. This is a common trap in HammerDB due to the use_all_warehouses parameter.

    Challenge

    Setting use_all_warehouses=true sounds realistic because it touches more data. However, this forces the database into a random I/O pattern. Instead of processing transactions, the CPU enters a Wait state while the SSD controllers fetch disparate data blocks.

    The fix

    I set use_all_warehouses=false. This narrowed the working set of data, allowing it to be cached entirely within the PostgreSQL buffer pool (RAM).

    By eliminating disk latency, I forced the database into a CPU-bound state. Only then could I see the true raw processing power of the underlying architecture without the noise of EBS volume throttling or IOPS limits.

    3. Silencing the background noise: The WAL strategy

    PostgreSQL is designed for data integrity, which means it does a lot of work behind the scenes to ensure your data survives a crash. In a benchmark, this work manifests as massive performance dips.

    The WAL runway

    PostgreSQL uses a write-ahead log (WAL) to ensure durability. When the WAL fills up, the database triggers a checkpoint, flushing "dirty" buffers to disk. This process is I/O intensive and causes NOPM graphs to flatline periodically.

    The fix

    I increased max_wal_size to 200GB. This essentially gave the database a long enough of a "runway" to store every single transaction log for the duration of the test without needing to pause for cleanup.

    A word of caution for production

    While a massive max_wal_size is a "cheat code" for benchmarking only. Don't copy this to production. Increasing this value increases the time it takes for the database to recover after a crash (recovery time objective). In a benchmark, we don't care about crash recovery. We care about making the CPU the only bottleneck. In production, you have to balance performance with safety.

    The pre-flight routine

    To ensure every test run started on a level playing field, I used Red Hat Ansible Automation Platform to automate a rigorous cleanup:

    • Manual checkpoint: Forces the database to flush everything to disk before the timer starts.
    • Vacuum: Cleans up dead tuples (bloat). Without this, the autovacuum daemon might kick in during your peak load, stealing CPU cycles.

    4. Scripting for stability

    Even with the right hardware, my results were still unpredictable. I eventually realized that the way the benchmark was being cycled was the final piece of the puzzle.

    By integrating loadscript and vudestroy into my automation, the results finally became predictable. These commands ensured the script is fully parsed in memory and that zombie connections from previous runs are wiped clean. Only then did the throughput finally climb until it hit the true hardware limit of the RDS CPU.

    Benchmarking checklist

    If you want data you can actually trust, you must isolate the variables:

    1. Over-provision the client: Your tester should never be the bottleneck.
    2. Isolate the bottleneck: If you're testing CPU, stay in the buffer pool (RAM).
    3. Expand the WAL: Prevent mid-test checkpoints, but remember the trade-off with recovery time in real-world scenarios.
    4. Automate stability: Use tools like Ansible Automation Platform to run tests multiple times. Aim for a stability percentage (variation) of less than 5%.

    By removing hidden bottlenecks, I stopped measuring the noise of my configuration and finally started measuring the true performance of the cloud.

    Related Posts

    • How to automate AWS network using Ansible Automation

    • Boost OpenShift database VM density with memory overcommit

    • Discover packaging parallel database streams in RHEL 10

    • Virtualized database I/O performance improvements in RHEL 9.4

    Recent Posts

    • Installing Red Hat Enterprise Linux 10 from a bootc image with bootc

    • Why your database benchmarking data is probably wrong (and how I fixed mine)

    • Type what you want to break: AI-assisted chaos engineering with Krkn

    • Understanding evaluation collections in EvalHub

    • An overview of confidential containers on OpenShift bare metal

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.