Hello Cristóbal,
I think you might have a slight misunderstanding of how Slurm works, which can cause this difference in expectation.
The MaxMemPerNode is there to allow the scheduler to plan job placement according to resources. It does not enforce limitations during job execution, only placement with the assumption that the job will not use more than the resources it requested.
One option to limit the job during execution is through cgroups, another might be using JobAcctGatherParams/OverMemoryKill but I would suspect cgroups would indeed be the better option for your use case, and see from the slurm.conf man page:
Kill processes that are being detected to use more memory than requested by steps every time accounting information is gathered by the JobAcctGather plugin. This parameter should be used with caution because a job exceeding its memory allocation may affect other processes and/or machine health.
NOTE: If available, it is recommended to limit memory by enabling task/cgroup as a TaskPlugin and making use of ConstrainRAMSpace=yes in the cgroup.conf instead of using this JobAcctGather mechanism for memory enforcement. Using JobAcctGather is polling based and there is a delay before a job is killed, which could lead to system Out of Memory events.
NOTE: When using OverMemoryKill, if the combined memory used by all the processes in a step exceeds the memory limit, the entire step will be killed/cancelled by the JobAcctGather plugin. This differs from the behavior when using ConstrainRAMSpace, where processes in the step will be killed, but the step will be left active, possibly with other processes left running.
-- Regards, Daniel Letai +972 (0)505 870 456