title: MongoDB executes queries sequentially instead of in parallel
body: <p>I have an API endpoint which I am trying to stress test which reads a very large <code>MongoDB</code> database collection (2 million documents). Each query takes roughly <strong>2 seconds</strong> however the problem I am having is that the connection to the database isn't being pooled correctly so each query runs <strong>sequentially</strong> instead of <strong>concurrently</strong>.</p>
  
  <p>I am using <a href="http://mongoosejs.com/" rel="nofollow noreferrer">Mongoose</a> to connect to my database and I am using <a href="https://artillery.io/" rel="nofollow noreferrer">artillery.io</a> for testing.</p>
  
  <p>Here is my connection code:</p>
  
  <pre><code>const mongoose = require('mongoose');
  const Promise = require('bluebird');
  
  const connectionString = process.env.MONGO_DB || 'mongodb://localhost/mydatabase';
  
  mongoose.Promise = Promise;
  
  mongoose.connect(connectionString, {
      server: { poolSize: 10 }
  });
  
  const db = mongoose.connection;
  
  db.on('error', console.error.bind(console, 'connection error: '));
  
  db.once('open', function() {
      console.log('Connected to: ' + connectionString);
  });
  
  module.exports = db;
  </code></pre>
  
  <p>It's your pretty bog standard connection procedure however probably the most important part is the <code>server: { poolSize: 10 }</code> line.</p>
  
  <p>I am using the following script for <strong>artillery.io</strong> testing:</p>
  
  <pre><code>config:
    target: 'http://localhost:1337'
    phases:
      -
        duration: 10
        arrivalRate: 5
        name: "Warm-up"
  
  scenarios:
    -
      name: "Search by postcodes"
      flow:
        -
          post:
            url: "/api/postcodes/gb_full/search"
            headers:
              Content-Type: 'application/json'
            json:
              postcodes:
                - ABC 123,
                - DEF 345,
                - GHI 678
  </code></pre>
  
  <p>This test executes <strong>50</strong> calls to the API over <strong>10 seconds</strong>. Now here's where the problem is, the API appears to execute queries <strong>sequentially</strong>, see the test results below:</p>
  
  <pre><code>"latency": {
    "min": 1394.1,
    "max": 57693,
    "median": 30222.7,
    "p95": 55396.8,
    "p99": 57693
  },
  </code></pre>
  
  <p>And the database logs are as follows:</p>
  
  <pre><code>connection accepted from 127.0.0.1:60770 #1 (1 connection now open)
  ...
  2017-04-10T18:45:55.389+0100 ... 1329ms
  2017-04-10T18:45:56.711+0100 ... 1321ms
  2017-04-10T18:45:58.016+0100 ... 1304ms
  2017-04-10T18:45:59.355+0100 ... 1338ms
  2017-04-10T18:46:00.651+0100 ... 1295ms
  </code></pre>
  
  <p>It appears as though the API is only using one connection, which seems correct however it was my understanding that this will automatically put the <code>poolSize</code> to good use and execute these queries <strong>concurrently</strong> instead of one at a time.</p>
  
  <p>What am I doing wrong here? How can I execute these database queries in parallel?</p>
  
  <hr>
  
  <p><strong>Edit 1</strong> - Model and Query</p>
  
  <p>To hopefully make things a little clearer, I am using the following model:</p>
  
  <pre><code>const mongoose = require('mongoose');
  const db = require('...');
  
  const postcodeSchema = mongoose.Schema({
      postcode: { type: String, required: true },
      ...
      location: {
        type: { type: String, required: true },
        coordinates: [] //coordinates must be in longitude, latitude order.
      }
  });
  
  //Define the index for the location object.
  postcodeSchema.index({location: '2dsphere'});
  
  //Export a function that will allow us to define the collection
  //name so we'll pass in something like: GB, IT, DE ect for different data sets.
  module.exports = function(collectionName) {
      return db.model('Postcode', postcodeSchema, collectionName.toLowerCase());
  };
  </code></pre>
  
  <p>Where the <code>db</code> object is the connection module explained at the top of this question.</p>
  
  <p>And I am executing a query using the following:</p>
  
  <pre><code>/**
   * Searches and returns GeoJSON data for a given array of postcodes.
   * @param {Array} postcodes - The postcode array to search.
   * @param {String} collection - The name of the collection to search, i.e 'GB'.
   */
  function search(postcodes, collection) {
      return new Promise((resolve, reject) =&gt; {
          let col = new PostcodeCollection(collection.toLowerCase());
  
          col.find({
              postcode: { $in: postcodes }
          })
          .exec((err, docs) =&gt; {
              if (err)
                  return reject(err);
  
              resolve(docs);
          });
      });
  }
  </code></pre>
  
  <p>And here is an example of how the function can be called:</p>
  
  <pre><code>search(['ABC 123', 'DEF 456', 'GHI 789'], 'gb_full')
  .then(postcodes =&gt; {
      console.log(postcodes);
  })
  .catch(...);
  </code></pre>
  
  <p>To re-iterate, these queries are executed via the <code>node.js</code> API, therefore they should <em>already</em> be asynchronous however the queries themselves are being executed one after the other. Therefore I believe the problem may be on the MongoDB side but I have no idea where to even start looking. It's almost as if MongoDB is blocking any other queries from being executed against the collection if there is already one running.</p>
  
  <p>I am running an instance of <code>mongod.exe</code> locally on a <strong>Windows 10</strong> machine.</p>