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.
    • 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

How to simulate network latency in local containers

May 26, 2025
Balazs Szeti
Related topics:
ContainersDeveloper productivity
Related products:
Podman Desktop

As a developer, it can be challenging to test certain real world use cases and verify how our application behaves in case of network connectivity or performance problems. With limited resources and permissions sometimes we can't reproduce issues that we face in QA or production environments, which makes debugging and fixing them cumbersome. In this post, we'll take a look at how to use containers locally to simulate the impact of network latency on a distributed database cluster.

Generally, it's a good idea to use containers in a local environment—the developer’s inner loop, shown in Figure 1—to test how the application works in a production-like environment in certain situations (for example, limited resource availability or network issues).

Developer experience inner/outer loop
Figure 1: Developer experience overview. The inner loop is the rapid, iterative cycle of coding, building, running, testing, and debugging code on a local environment before sharing it.

If you have a Linux host, you can use Podman directly to spin up containers. On Mac or Windows, you'll need Podman Desktop to creates a Linux virtual machine (VM) under the hood to run the containers.

Before trying the following commands, read the Prepare Podman host section for guidance on how to prepare the host to load the required kernel module.

Add delay to an interface

Use Linux traffic control (tc) and NetEm to add delays or simulate other network issues on an interface. The tc operations require the NET_ADMIN capability to be added to the container when it's created (otherwise getting RTNETLINK answers: Operation not permitted). See details about using NetEm.

Install tc

Install the tc tool within the container. We can build a whole new image with a Containerfile or simply add the installation steps to the container's entry point if its user is root or it can sudo like this:

On a Fedora or Red Hat Enterprise Linux-based image:

dnf update -y && dnf install -y iproute-tc

On a Debian-based image:

apt update && apt-get install -y iproute2

Use tc

A container running locally usually has two interfaces: lo and eth0.

Add a delay to the lo interface to have an impact on a port published to the host. Run as root inside the container:

tc qdisc add dev lo root netem delay 50ms

Use interface eth0 to add delay between containers attached to the same internal network:

tc qdisc add dev eth0 root netem delay 50ms

Additional commands

Check status for all interfaces:

tc qdisc show

Remove set delay:

tc qdisc del dev lo root

Try with PostgreSQL

Start the container with published database port:

podman run -d --name mypostgres --cap-add NET_ADMIN -p 5432:5432 -e POSTGRES_PASSWORD=secret docker.io/library/postgres:17.4

Check that a SELECT is quick (less than 1 millisecond) by default. We enabled \timing, so psql logs the execution time.

If you have psql installed on your laptop:

PGPASSWORD=secret psql -h localhost -p 5432 -U postgres  postgres -c "\timing" -c "SELECT 1"

Or use psql within the container:

podman exec -it mypostgres sh -c 'psql -h 127.0.0.1 -p 5432 -U postgres postgres -c "\timing" -c "SELECT 1"'

Let's install tc and add delay to the lo interface:

podman exec -it mypostgres sh -c 'apt update && apt-get install -y iproute2 && tc qdisc add dev lo root netem delay 50ms'

Run SELECT 1 again. It should report ~100 millisecond execution time because of the added network delay.

Try 2 containers on the same network

Run a container with a 50-millisecond delay on eth0 and ping it from another container on the same internal network:

#Create container network
podman network create mynetwork
# Start container on custom network
podman run -d --name fedora --net mynetwork --cap-add NET_ADMIN fedora:42 sh -c 'dnf install -y iproute-tc && tc qdisc add dev eth0 root netem delay 50ms && sleep infinity'
# Ping from another container
podman run --rm -it --name ping --net mynetwork fedora:42 sh -c 'dnf install iputils -y && ping fedora'

Expect to see the added ~50 millisecond ping time.

Try a whole YugabyteDB cluster

YugabyteDB is a distributed PostgreSQL-compatible database. See steps in this script how to create a whole db cluster in containers simulating a five node database distributed in two different regions/datacenters with network latency in between:

  • Region-A has db-node1-2. Region-B has db-node3-5 with network latency.
  • Ports of db-node1 are published to host, to connect with psql or a test application.
  • SELECT is quick as there is no latency set for db-node1.
  • INSERT is slow because we enforced replication to all 5 nodes including the ones "in the other region."

Original use case

Here is a quick note about a real-world problem we managed to replicate and resolve using local containers as explained in the previous section. We saw significant performance degradation with a Spring Boot application caused by longer than expected execution time for inserting hundreds of rows in a database.

Creating a YugabyteDB cluster with network delays matching the production environment in containers made it possible to do an in depth analysis and debugging on our local laptops. The tools available in inner loop accelerated investigation and resulted in a short feedback loop for developers trying different approaches to fix the root cause of a problem.

In this special case, we found that enabling batch inserts was not enough to achieve performance improvement due to the distributed nature of the database, but we had to add reWriteBatchedInserts=true in our postgresql JDBC connection string to merge INSERT statements.

Using a Pod instead of a single container

If you can't install the tc tool directly in the main container (for example, if you're using Red Hat Universal Base Image without a subscription attached), you can run the tc command in another container attached to the same container network namespace.

Podman supports the concept of Pods for such purposes, similar to Kubernetes. Containers in the same Pod share the same network interface, so the network delay set in one container has an impact on the whole Pod.

For example, add latency to a published port:

# Create a Pod with a published port
podman pod create -p 5432:5432 mypod
# Run a temporary container in the Pod having the "tc" tool
podman run --pod mypod -it --rm --cap-add NET_ADMIN fedora:42 sh -c 'dnf install -y iproute-tc && tc qdisc add dev lo root netem delay 50ms'
# Run the main container in the Pod
podman run --pod mypod -d -e POSTGRES_PASSWORD=secret postgres:17.4
# Verify increased query time with "psql"
PGPASSWORD=secret psql -h localhost -p 5432 -U postgres postgres -c "\timing" -c "SELECT 1"

Similarly, increase ping time between containers:

# Create a Pod attached to a network
podman pod create --network mynetwork mypod
# Run a temporary container in the Pod having the "tc" tool
podman run --pod mypod -it --rm --cap-add NET_ADMIN fedora:42 sh -c 'dnf install -y iproute-tc && tc qdisc add dev eth0 root netem delay 50ms'
# Run the main container in the Pod
podman run --pod mypod -d redhat/ubi9 sh -c 'sleep infinity'
# Hostname to ping is the Pod's name in this case
podman run --rm -it --name ping --net mynetwork fedora:42 sh -c 'dnf install iputils -y && ping mypod'

Prepare Podman host

The preceding tc qdisc commands require the sch_netem Network Emulator kernel module to add delay to network interfaces. It's common to run into the error Specified qdisc not found if this kernel module is not available on your host. As the kernel is shared between containers, you need to enable the kernel module on your Linux host or within the Linux VM on Mac or Windows.

On Windows, you need to use Podman with Hyper-V backend instead of Windows Subsystem for Linux (WSL2). Make sure that Hyper-V is enabled on your machine and select Hyper-V as the virtualization provider during installation. You need local admin permissions.

The Linux VM machine used by Podman Desktop is based on Fedora CoreOS. See available images and repo for details. Currently image v5.3 is used by default, but you can enforce a specific version as follows:

podman machine init --image docker://quay.io/podman/machine-os:5.5

To enable the sch_netem kernel module, get a shell inside the VM:

podman machine ssh

This command will drop an error if the required module is not installed yet:

sudo modprobe sch_netem

Install the missing kernel module:

sudo rpm-ostree install kernel-modules-extra

Remove the default config blocking auto-load for this kernel module (this is a dangerous module, if you think about it):

sudo rm /etc/modprobe.d/sch_netem-blacklist.conf

Enable loading kernel module on startup:

sudo sh -c 'echo sch_netem >/etc/modules-load.d/sch_netem.conf'

Exit from the VM, then restart the machine:

podman machine stop && podman machine start

The sch_netem kernel module should be loaded now in the VM:

podman machine ssh lsmod | grep sch_netem

If you work directly on a Linux host, you need to run similar commands based on your Linux distribution to enable the sch_netem kernel module. It’s better to avoid auto-load and just activate the module with modprobe sch_netem whenever it’s needed.

Conclusion

“Shift left” is a software development approach that encourages testing and detecting performance or security problems in the earlier phases of the development life cycle. Using containers in inner loop developer experience with tools like Podman Desktop helps you test complex architectures and simulate use cases that you might run into later in a production environment.

Related Posts

  • Introducing image mode for RHEL and bootable containers in Podman Desktop

  • A quick look at large language models with Node.js, Podman Desktop, and the Granite model

  • How to install and use Podman Desktop on Windows

  • Working with Kubernetes in Podman Desktop

  • Experiment and test AI models with Podman AI Lab

  • Develop SQL Server databases on RHEL with Podman Desktop

Recent Posts

  • Federated identity across the hybrid cloud using zero trust workload identity manager

  • Confidential virtual machine storage attack scenarios

  • Introducing virtualization platform autopilot

  • Integrate zero trust workload identity manager with Red Hat OpenShift GitOps

  • Best Practice Configuration and Tuning for Linux and Windows VMs

What’s up next?

This learning path demonstrates how you can go from an initial application to a container to a fully running pod on Kubernetes using Podman Desktop and the no-cost Developer Sandbox for Red Hat OpenShift.

Start the activity
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.