Let's assume that each Task (data item related processing task) ends in a queue on your server. In order to get your 20 jobs per minute in an easy way, you could set up a recurring task, which every minute pulls maximum 20 items from the input queue and places them into a processing queue, which is then being processed by 1 or more threads.
How you do that depends on your ecosystem and programming environment.
In F#, for example, you could use the
FSharp.Control namespace to create an actor style of solution, doing just that. On C#, you could use the Task model. On Pony (yes, that is also a programming language ;) ), you could use actors (as all you do there, is to use actors). In rather low level C/C++ environments, you could allocate a small pool of threads (1..a fraction of the number of your servers cores), which then draw their tasks from the processing queue (work stealing). And so on.
This still produces load spikes on your server, since every minute it will aggressively work on the tasks of processing the scheduled items.
If you want to get a more balanced background load within the 1 minute time frame, you need to take more details about your processing code into account. If, for example, the time to process 1 item is rather a constant and not varying much in processing complexity, you could do some dynamic estimation of the processing time for 1 item and then draw your 20 items from the input queue, only to schedule a fraction of them every 60/20=3 seconds (some previous tasks might still be running, given that your server also has other stuff to do and its workload is not constant). How many to schedule is then the objective of the estimator.
The last remaining problem to worry about is back pressure. If you hard limit the processing rate of items, but the influx of new tasks is out of this servers control, your input queue will grow unboundedly. So, rather, I would try to throttle processing more or less, depending on the length of the input queue. Or add actual back pressure to the client/server communication. For example, have your server request 20 items every minute (in a batch) instead of having the client send to the server whatever they want.
Unless this is a kind of research project or there are other compelling reasons, I would not consider to get all too sophisticated on this problem. The keep it simple approach saves you time, lines of code (and as such, potential bugs) and in extreme cases the funny looks of your coworkers (if you went overboard with your solution).
If you actually program the client side (and not the server side as I assumed above) and if your server code made bad life choices (no back pressure in the protocol), you can still do what I described above to get your throttling. What I called input queue above would now be your output queue. And your task which is scheduled once per minute now simply draws max 20 items from the output queue and sends it as a batch to the server.