Limiting a User To a Given Amount Of Traffic With User Levels - MikroTik Script RouterOS

If you need to limit users for amount of download and also need several user levels (different limits for groups of user), check this script.

/queue simple; :foreach i in=[find] \
do={  \
     :set sqName [get $i name]; \
     :set sqTotalBytes [get $i total-bytes]; \
     :set sqLevel [:find $sqName "\[LevelA\]"]; \
     :if ($sqLevel >= 0)  do={ \
        set $i limit-at=32000/32000 max-limit=64000/64000 burst-threshold=48000/48000 burst-limit=128000/128000 burst-time=30/30; \
        :if ($sqTotalBytes  > (100 * 1048576))  do = { \
          set $i limit-at=24000/24000 max-limit=32000/32000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
        }; \
     } else {
       :set sqLevel [:find $sqName "\[LevelB\]"]; \
       :if ($sqLevel >= 0)  do={ \
           set $i limit-at=64000/64000 max-limit=128000/128000 burst-threshold=78000/78000 burst-limit=256000/256000 burst-time=30/30; \
           :if ($sqTotalBytes  > (200 * 1048576))  do = { \
             set $i limit-at=64000/64000 max-limit=64000/64000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
           }; \
       } else { \
           :set sqLevel [:find $sqName "\[LevelC\]"]; \
           :if ($sqLevel >= 0)  do={ \
               set $i limit-at=72000/72000 max-limit=256000/256000 burst-threshold=96000/96000 burst-limit=1000000/1000000 burst-time=30/30; \
               :if ($sqTotalBytes  > (300 * 1048576))  do = { \
                  set $i limit-at=72000/72000 max-limit=72000/72000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
                }; \
            }; \
        }; \
     }; \
     :if ($sqLevel >= 0) do { \
        :put ([get $i name] . " : " . [get $i limit-at] . " : " . [get $i max-limit]  . " : " . [get $i burst-limit]   . " : " . [get $i burst-threshold]  . " : " . [get $i burst-time]) ; \
     }; \
}
This scripts checks names of simple queues and if it finds [LevelA], [LevelB] or [LevelC] in name, it sets specified parameters. It also checks total-bytes and if limit is reached it sets different parameters for a queue.

This allows you to set groups at will (it is easily expandable to needed number of groups, these three are just for an example) and easily put queue in needed group by entering group ID within name. This means you may keep custom simple queue names, just add Group ID in it.

If you want to change group for some simple queue, just change group id in that queue name.

This script should be scheduled in regular time periods, for instance every 30 minutes, and also there should be triger that resets total-bytes once a day. Recomendation is that reset is done about 2 AM.

Script runs but this is my the very first MT script for so it is possible it is not of greatest quality code. I hope some of experienced members will suggest if there are possible improvements in code.

How to reset counters:

For older MT versions:

/queue simple reset-counters
For new versions:

/queue simple reset-counters-all
Oh yes, if you use Mikrotik v3 or newer, than this script won't work (script syntax has been changed).

Try this one instead:

/queue simple; 
:foreach i in=[find] \
do={  \
     :local sqName [get $i name]; \
     :local sqTotalBytes [get $i total-bytes]; \
     :local sqLevel [:find $sqName "[LevelA]"]; \
     :if ($sqLevel >= 0)  do={ \
        set $i limit-at=32000/32000 max-limit=64000/64000 burst-threshold=48000/48000 burst-limit=128000/128000 burst-time=30/30; \
        :if ($sqTotalBytes  > (100 * 1048576))  do={ \
          set $i limit-at=24000/24000 max-limit=32000/32000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
        }; \
     } else {
       :set sqLevel [:find $sqName "[LevelB]"]; \
       :if ($sqLevel >= 0)  do={ \
           set $i limit-at=64000/64000 max-limit=128000/128000 burst-threshold=78000/78000 burst-limit=256000/256000 burst-time=30/30; \
           :if ($sqTotalBytes  > (200 * 1048576))  do={ \
             set $i limit-at=64000/64000 max-limit=64000/64000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
           }; \
       } else { \
           :set sqLevel [:find $sqName "[LevelC]"]; \
           :if ($sqLevel >= 0)  do={ \
               set $i limit-at=72000/72000 max-limit=256000/256000 burst-threshold=96000/96000 burst-limit=1000000/1000000 burst-time=30/30; \
               :if ($sqTotalBytes  > (300 * 1048576))  do={ \
                  set $i limit-at=72000/72000 max-limit=72000/72000 burst-threshold=0/0 burst-limit=0/0 burst-time=0/0; \
                }; \
            }; \

        }; \
     }; \
     :if ($sqLevel >= 0) do { \
        :put ([get $i name] . " : " . [get $i limit-at] . " : " . [get $i max-limit]  . " : " . [get $i burst-limit]   . " : " . [get $i burst-threshold]  . " : " . [get $i burst-time]) ; \
     }; \
}