Know Your Limits


Introduction
Have you ever found yourself debugging a system issue and wished you had a quick way to view all the important OS configuration limits and system information in one place?
Meet Limits: an elegant Python terminal application that provides exactly that functionality with a clean, interactive interface. Limits is a lightweight Python terminal application built with the Textual framework that displays comprehensive OS configuration and limits information. It's designed to be a debugging companion for developers and system administrators who need quick access to system resource information.
Getting Started
Ensure you have Python 3.13+ and uv installed
Clone the repository from https://github.com/rainzoo/limits
Run:
uv run limits.py
(thanks to PEP 723)Navigate with arrow keys, press
r
to refresh,q
to quit
🖥️ Basic System Info
The application displays a wide range of system metrics organized into logical sections:
CPU Information: Physical and logical core counts
Memory Information: Total RAM, available memory, and swap space
Process Resource Limits: File descriptors, stack size, process limits, virtual memory, and CPU time constraints
Filesystem Limits: Maximum filename and path lengths
Mounted Filesystems: Disk usage and inode information for all mounted drives
⚡ Alternative Usage
The application can be run in multiple ways:
# With dependency management
uv sync
uv run limits.py
# Debug mode (with textual-dev)
textual run limits.py
# Docker
docker build -f Dockerfile -t limits:latest .
docker run -it limits:latest
Dependencies
Dependencies are listed in pyproject.toml
:
Textual: Powers the terminal user interface
A clean, tabular display with zebra striping for easy reading
Interactive navigation with cursor support
Real-time refresh capability
psutil: Cross-platform system and process utilities
humanize: Makes numbers and dates more human-readable
The application intelligently handles platform differences, providing detailed resource limit information on POSIX systems (Linux, macOS) while gracefully degrading on Windows.
The get_os_info(
) gathers CPU topology and capabilities, Memory hierarchy (RAM, swap), Process resource constraints, Filesystem characteristics, and Storage device information.
This is an interesting demo whether you're a system administrator looking for a quick diagnostic tool, a developer debugging resource issues, or a Python enthusiast interested in terminal UI development.
Deep Dive
Understating these limits is vital for building robust and performant applications.
1. CPU Information
Physical & Logical Cores
Concurrency: The number of cores determines the true level of parallelism an application can achieve. For CPU-bound tasks, this number is critical for tuning thread pools or multiprocessing strategies to maximize performance without causing excessive context switching.
Performance Tuning: Knowing the core count helps developers design efficient parallel algorithms and decide on the optimal number of worker processes or threads for services like web servers or data processing jobs.
2. Process Resource Limits
These are per-process limits, often configured at the OS level to ensure system stability by preventing any single process from consuming all available resources.
Max Open Files
This is one of the most common limits hit by network services and database applications. Servers that handle many simultaneous connections (e.g., web servers, message queues) or applications that access many files can easily exhaust this limit, leading to "Too many open files" errors. Developers must monitor this and design their code to manage file descriptors efficiently (e.g., using connection pools).
Max Processes
This limit affects applications that use a multiprocess architecture (e.g., preforking web servers like older versions of Apache or Gunicorn). Exceeding the user's process limit will prevent the application from scaling out by creating new child processes, leading to service degradation.
Stack Size
This defines the amount of memory allocated for a thread's function call stack. Applications with deep recursion or large stack-allocated variables can exceed this limit, causing a stack overflow and an immediate crash. It's a critical consideration for system programmers writing recursive algorithms or complex function call chains.
Virtual Memory (Address Space)
This limits the total virtual memory a process can request. For memory-intensive applications like in-memory databases, caches, or scientific computing tools, this limit can be a bottleneck. Hitting it can cause allocation failures, even if physical RAM is available.
CPU Time Limit
This is a safeguard that kills a process after it has consumed a certain amount of CPU time. While less common in general app development, it's important in multi-user or high-performance computing (HPC) environments to prevent runaway processes from monopolizing CPU resources.
3. Filesystem and Storage Limits
Max Filename & Path Length
Applications that create or manage user-defined file structures must respect these limits to ensure cross-platform compatibility and prevent ENOENT
(No such file or directory) or ENAMETOOLONG
errors. This is especially important for applications that generate nested directory structures or long, descriptive filenames.
Disk & Inode Usage
Disk Space : Running out of disk space is a common cause of application failure. Applications that write logs, temporary files, or store data must have error handling for disk-full scenarios.
Inodes : An inode is a data structure that stores information about a file. It's possible to run out of inodes even if disk space is available, especially on systems with a large number of very small files (e.g., mail servers, caches). Applications that create many small files must be aware of this potential limit.
Curious Case of Container Limits
In containers, these are among the most important limits:
CPU Limits (Shares, Quota, Period) These control how much CPU time a container gets. Shares provide a relative weight, while quota/period provide a hard cap (e.g., "use 2 CPU cores worth of time every 100ms"). Prevents a single "noisy neighbor" container from starving others of CPU. It's fundamental for multi-tenancy and ensuring predictable performance, but setting limits too low can artificially throttle an application that needs to burst.
Memory Limit (
memory.limit_in_bytes
) The absolute maximum amount of memory a container can use. This is the most critical limit for container stability. If a container's memory usage exceeds this limit, the kernel's Out-Of-Memory (OOM) killer will immediately terminate a process inside it (often the main application), causing the container to crash. Application developers must be acutely aware of their memory footprint relative to this limit.
You run the app with the following options to limit cpu or memory using the Dockerfile
:
docker run --cpus 4 -it limits:latest
ordocker run --memory 4g -it limits:latest
Why? The data that is displayed is from the host system. In my case, I have assigned 8 Gb memory and 8 CPUs to my docker engine. This is not what the container is using.
What is the way to fix this? This is left as an exercise for the reader.
Subscribe to my newsletter
Read articles from Manas Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Manas Singh
Manas Singh
14+ Years in Enterprise Storage & Virtualization | Python Test Automation | Leading Quality Engineering at Scale