Skip to content

Conversation

@Ddfulton
Copy link
Contributor

@Ddfulton Ddfulton commented Dec 12, 2025

📝 Summary

When running marimo in containers with resource limits (e.g., docker run --memory=16g), the machine stats footer shows host resources instead of container resources. This PR auto-detects containerized environments with cgroup limits and displays container resources instead.

Before: Shows host memory (512GB) even in a 16GB container
image

After: Shows actual container limits with "container memory" label
image

This is something we've been doing at Carolina Cloud for a while and have found very useful. Not sure whether it belongs in the main source code but figured I'd share to see what the community thinks.

Also did this for CPU % by using a method similar to psutil (computing average usage over a time period).

🔍 Description of Changes

Backend:

  • Added cgroup detection functions (has_cgroup_limits(), get_container_resources()) supporting both v1 and v2
  • Fixed missing cgroup v1 CPU detection bug
  • Modified /api/usage endpoint to return container stats when limits detected, with is_container flag
    Frontend:
  • Updated memory stats to show "container memory" vs "computer memory" based on is_container field
    Compatibility:
  • Only activates on Linux with cgroups (Docker, Kubernetes, Podman)
  • Safely falls back to host stats on macOS/Windows or containers without limits

📋 Checklist

  • I have read the contributor guidelines.
  • For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on Discord, or the community discussions (Please provide a link if applicable).
  • I have added tests for the changes made.
  • I have run the code and verified that it works as expected.

@vercel
Copy link

vercel bot commented Dec 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
marimo-docs Ready Ready Preview, Comment Jan 4, 2026 7:04pm

@github-actions
Copy link

github-actions bot commented Dec 12, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions github-actions bot added the bash-focus Area to focus on during release bug bash label Dec 12, 2025
@Ddfulton
Copy link
Contributor Author

I have read the CLA Document and I hereby sign the CLA

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds automatic detection of containerized environments (Docker, Kubernetes, Podman) to display accurate resource statistics when running marimo in containers with resource limits. Instead of showing misleading host-level metrics, the footer now displays container-specific memory limits when cgroup constraints are detected, with an updated label to indicate "container memory" vs "computer memory".

Key Changes:

  • Added cgroup v1 and v2 detection functions to identify and read container resource limits from Linux cgroups
  • Modified the /api/usage endpoint to return container statistics when limits are detected, adding an is_container boolean flag
  • Updated the frontend machine stats component to display appropriate memory labels based on container context

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
marimo/_utils/health.py Added has_cgroup_limits() and get_container_resources() functions to detect and read cgroup v1/v2 resource limits
marimo/_server/api/endpoints/health.py Modified /api/usage endpoint to use container resources when available and include is_container flag
tests/_server/api/endpoints/test_health.py Added assertions to verify is_container field is present and boolean in API response
packages/openapi/src/api.ts Added optional is_container boolean field to memory response type
packages/openapi/api.yaml Added is_container boolean field to memory schema definition
frontend/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx Updated memory stats tooltip to show "container memory" vs "computer memory" based on is_container flag
Comments suppressed due to low confidence (11)

marimo/_utils/health.py:204

  • File is opened but is not closed.
                open("/sys/fs/cgroup/memory.max", encoding="utf-8")

marimo/_utils/health.py:213

  • File is opened but is not closed.
                open("/sys/fs/cgroup/cpu.max", encoding="utf-8").read().strip()

marimo/_utils/health.py:226

  • File is opened but is not closed.
                open(
                    "/sys/fs/cgroup/memory/memory.limit_in_bytes",
                    encoding="utf-8",
                )

marimo/_utils/health.py:238

  • File is opened but is not closed.
                open("/sys/fs/cgroup/cpu/cpu.cfs_quota_us", encoding="utf-8")

marimo/_utils/health.py:345

  • File is opened but is not closed.
                    open("/sys/fs/cgroup/cpu.max", encoding="utf-8")

marimo/_utils/health.py:366

  • File is opened but is not closed.
                    open(
                        "/sys/fs/cgroup/cpu/cpu.cfs_quota_us", encoding="utf-8"
                    )

marimo/_utils/health.py:374

  • File is opened but is not closed.
                    open(
                        "/sys/fs/cgroup/cpu/cpu.cfs_period_us",
                        encoding="utf-8",
                    )

marimo/_utils/health.py:323

  • File is opened but is not closed.
                    open(
                        "/sys/fs/cgroup/memory/memory.usage_in_bytes",
                        encoding="utf-8",
                    )

marimo/_utils/health.py:287

  • File is opened but is not closed.
                    open("/sys/fs/cgroup/memory.max", encoding="utf-8")

marimo/_utils/health.py:315

  • File is opened but is not closed.
                    open(
                        "/sys/fs/cgroup/memory/memory.limit_in_bytes",
                        encoding="utf-8",
                    )

marimo/_utils/health.py:292

  • File is opened but is not closed.
                    open("/sys/fs/cgroup/memory.current", encoding="utf-8")

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@Light2Dark Light2Dark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a great improvement :). The frontend looks good to me.

Curious if you have tried this solution on the backend? giampaolo/psutil#1011. api docs: https://psutil.readthedocs.io/en/latest/index.html#psutil.PROCFS_PATH

@mscolnick
Copy link
Contributor

mscolnick commented Dec 15, 2025

this is a good find @Light2Dark . @Ddfulton using https://psutil.readthedocs.io/en/latest/index.html#psutil.PROCFS_PATH should hopefully clean up some code, if you are open to make the change

@Ddfulton
Copy link
Contributor Author

Ddfulton commented Dec 16, 2025

@Light2Dark @mscolnick Thanks for taking a look! I gave psutil.PROCFS_PATH a try, but ran into an issue: psutil already reads from the container's /proc by default, and /proc/meminfo shows the host's memory, not the container's limits.

I think that thread was actually about the reverse — folks wanting to get host stats from inside a container by mounting the host's /proc to the container. We need the opposite: container limits from inside the container.

When psutil.virtual_memory() runs inside a container, it reads /proc/meminfo which reflects the host's memory:

# Inside container with --memory=1g
psutil.virtual_memory().total     # → 512GB (host, from /proc/meminfo)
open("/sys/fs/cgroup/memory.max") # → 1GB (container limit)

I looked at how Docker/Kubernetes tooling handles this and found they read cgroup files directly (example from cAdvisor). The cgroup paths are part of the stable Linux kernel ABI (v1 since 2008, v2 since 2016), but I agree the file-reading approach is more verbose than ideal.

To make it more robust, I've added:

  • f.close(), per Copilot's suggestion, for all file operations
  • Smoke tests for has_cgroup_limits() and get_container_resources()
  • Rented an Alma linux machine (which has cgroups v1) and tested it there

@Light2Dark
Copy link
Contributor

Light2Dark commented Dec 16, 2025

@Light2Dark @mscolnick Thanks for taking a look! I gave psutil.PROCFS_PATH a try, but ran into an issue: psutil already reads from the container's /proc by default, and /proc/meminfo shows the host's memory, not the container's limits.

I think the suggestion from the thread is to change PROCFS_PATH to something else that contains the container information

import psutil
psutil.PROCFS_PATH =/path/to/container/procfs

However, looking at some of the threads, it seems there is no standard to do ^, and the host & container are not independent so it would not give the container information. Cmiiw. It's a rabbit hole of an issue lol. If so, I think your solution makes sense..

Separately, I do see some users reporting that they want the reverse...which means it's working correctly? Not sure how it's working for them and not here.

@Ddfulton
Copy link
Contributor Author

With you 100%. I think that's exactly right — a container-specific /proc basically doesn't exist which I too initially found hard to believe but I guess that's the nature of how the kernel manages containers? Over my head for sure.

Not familiar with that Schema Breaking Changes Check above and not clear that it's from this PR — let me know if there's anything I can do to resolve it!

Light2Dark
Light2Dark previously approved these changes Dec 31, 2025
Copy link
Contributor

@Light2Dark Light2Dark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tq! 🚀. you have some failing imports (see CI)

@Ddfulton
Copy link
Contributor Author

Fixed the test imports. Bear with me, looking into the sql tutorial failure 🤦

@Ddfulton
Copy link
Contributor Author

Re CI: Tutorial check and and tests/_server/api/endpoints/test_terminal.py failed. I lack the broader project context to fix these and it's not clear to me if they are related to my changes, any thoughts @Light2Dark?

@mscolnick
Copy link
Contributor

@Ddfulton yes there are unrelated failing tests

Copy link
Collaborator

@dmadisetti dmadisetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test looks unrelated (I'll look into it)

Thanks for your perseverance and happy New Year!

@Light2Dark
Copy link
Contributor

Light2Dark commented Jan 5, 2026

Echoing Dylan—thanks for this! And sorry for all the reviews; the PR looks great now.

@Light2Dark Light2Dark merged commit c737d8d into marimo-team:main Jan 5, 2026
37 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bash-focus Area to focus on during release bug bash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants