# CPU limits per user on TLJH

**URL:** <https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437>\
**Category:** The Littlest JupyterHub\
**Created:** [September 17, 2024, 11:16am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437 "2024-09-17T11:16:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![verdurin](https://avatars.discourse-cdn.com/v4/letter/v/b5ac83/32.png) [@verdurin](https://discourse.jupyter.org/u/verdurin)\
**Post date:** [September 17, 2024, 11:16am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437/1 "2024-09-17T11:16:30Z")

</div>

We’ve setup TLJH for an upcoming course, and the tutors are reporting that servers they’re testing with parallel code are using all available cores on the host, rather than the 2 that are configured for a single user.

Is there any way of enforcing this within TLJH?

---

<div class="post-metadata">

**Author:** ![mahendrapaipuri](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/mahendrapaipuri/32/6800_2.png) [@mahendrapaipuri](https://discourse.jupyter.org/u/mahendrapaipuri)\
**Post date:** [September 18, 2024, 7:44am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437/2 "2024-09-18T07:44:43Z")

</div>

TLJH uses [SystemdSpawner](https://github.com/jupyterhub/systemdspawner) where you can enforce limits on resources using systemd. Here are the [config](https://github.com/jupyterhub/systemdspawner?tab=readme-ov-file#configuration) details. Not sure what is the best way to do it on TLJH though!

---

<div class="post-metadata">

**Author:** ![minrk](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/minrk/32/13_2.png) [@minrk](https://discourse.jupyter.org/u/minrk)\
**Post date:** [September 22, 2024, 7:14am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437/3 "2024-09-22T07:14:52Z")

</div>

From [the docs](https://tljh.jupyter.org/en/latest/topic/tljh-config.html#user-server-limits), these should set the systemd limits:

```bash
sudo tljh-config set limits.memory 4G
sudo tljh-config set limits.cpu 2

```

Are you seeing that these limits are set but not enforced?

---

<div class="post-metadata">

**Author:** ![verdurin](https://avatars.discourse-cdn.com/v4/letter/v/b5ac83/32.png) [@verdurin](https://discourse.jupyter.org/u/verdurin)\
**Post date:** [September 23, 2024, 8:47am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437/4 "2024-09-23T08:47:23Z")

</div>

Yes, I had set these values, and `CPU_LIMIT` appears to be set correctly in the shell.  
I asked because one of the tutors for this course reported CPU usage exceeding this limit, but perhaps that wasn’t the case.

---

<div class="post-metadata">

**Author:** ![minrk](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/minrk/32/13_2.png) [@minrk](https://discourse.jupyter.org/u/minrk)\
**Post date:** [September 25, 2024, 9:03am UTC](https://discourse.jupyter.org/t/cpu-limits-per-user-on-tljh/28437/5 "2024-09-25T09:03:56Z")

</div>

ok, it should be set with those. You should be able to test if this is the case with a sample task like this:

```python
import time
from concurrent.futures import ProcessPoolExecutor

import psutil

def use_cpu(seconds: float | int):
    """busywait to use the cpu in a single thread for a number of seconds"""
    start = time.perf_counter()
    deadline = start + seconds
    while time.perf_counter() < deadline:
        x = sum(range(100_000))

p = psutil.Process()
n_cpus = 4
with ProcessPoolExecutor(n_cpus) as pool:
    # submit tasks to use all cpus for 2 seconds
    for i in range(n_cpus):
        f = pool.submit(use_cpu, seconds=2)

    # measure cpu time of all children for one second
    children = p.children()
    before_times = sum(sum(_p.cpu_times()[:2]) for _p in children)
    time.sleep(1)
    after_times = sum(sum(_p.cpu_times()[:2]) for _p in children)

cpu_usage = after_times - before_times

```

where `cpu_usage` will be the number of cpus used. If you’ve set the limit to 2, you should get a result around 2, even if you run it with 4 or 10 processes. If you get a number that’s approximately `n_cpus` even when it’s larger than the limit, that meanst he limit is not having the desired effect.
