When developing Database abstraction with google apps script I had real trouble simulating multiuser interactions, especially when there wasnt a reall database behind (like sheets and drive). I had a mechanism in Using named locks with Google Apps Scripts to be able to lock from updating, but it was really hard to get a good multiuser test going.
Using this paralllel running mechanism is of course perfect – since it excutes as many threads as I want in parallel with each other. If I get then all to hit the same back end at once, then I have a pretty intensive multi user test.
So starting with Sheets – here is the profile to run my usual testing except this time, I’m hitting the same sheet with multiple requests at the same time

The profiles

The first task is to set up some parameters for the sheet I’m going to hit
function dbSheetProfile() {
  var profile = [];
  var dbParameters =  {
    "siloid": "multi",
    "dbid": "1yTQFdN_O2nFb9obm7AHCTmPKpf5cwAd78uNQJiCcjPk",
    "peanut": "bruce",
    "disablecache": true


Next clear the sheet

  // get the test data
  var profileTest = {
    "name": "TEST DATA",
    "functionName": "prepareTheData",
    "skip": false,
    "options": {
      "scale": 1


Next, a reduction to bring all the test data together. In the example below I’m only getting one set of test data. As usual we’ll use the common function reduceTheResults(), that we’ve used in all the examples.

// next reduce the messages to one
  var profileReduction = [];
    "name": "reduction",


Simulate a number of users doing a whole range of operations – in this case 5 at once, and then do another reduction

// get and process all the messages
  var CHUNKS = 5;
  var profileSheets = [];
  for (var i =0; i <CHUNKS;i++ ) {
    profileSheets.push ({
      "name": "SHEET-"+i,
      "functionName": "bigTest",
      "skip": false,
      "options": {
        "driver": "cDriverSheet",
        "strain": "strain-"+i,
        "small": true,
        "parameters": dbParameters


Finally we’ll need to log the results

  profile.push( [ {
    "name": "LOG",
    "functionName": "logTheResults",
    "skip": false,
    "options": {
      "driver": "cDriverSheet",
      "clear": true,
      "parameters": {
        "siloid": "log",
        "dbid": "1yTQFdN_O2nFb9obm7AHCTmPKpf5cwAd78uNQJiCcjPk",
        "peanut": "bruce"
  } ]);

  return profile;


The only change we need to make now is to call this function to set up the run profile

function showSidebar() {
   // kicking off the sidebar executes the orchestration
   libSidebar('asyncService',ADDONNAME, dbSheetProfile () );


The executors

prepareTheData(), logTheResults() and reduceTheResults() are the same function that we used in Some hints on setting up parallel running profiles. bigTest() is the same as I always use to excercise all of the back ends. I can let you have that if you are interested. So we did not need to create any new executor functions for this – just run bigTest() multiple times simultaneously.
Here’s a snap of the run – We got 384 seconds of processing over 94 seconds and simulated some serious multiuser activity.

For more snippets like this see Google Apps Scripts snippets