0
votes

Mongoose Model.save is taking over ~1.5+ seconds to complete, and if I user Model.collection.insert method instead its only ~50ms

The second solution unless I'm mistaken is only quicker because its using the native mongoDb driver. I have tried using console.time to isolate where the delay is and its happening just before the Model.prototype.save function is called which is really strange.

The auth.username is indexed so that shouldn't cause the slowness.

Below is an example of the model schema and how i am invoking a new model.

I am using 3.20.0 of mongoose, and 2.6.4 of mongoDB.

var userSchema = new Schema({

active: { type: Boolean, default: true },

player_id: ObjectId,
player: mongoose.Schema.Types.Mixed,

auth: {
    token: { type: String, required: true, default: 'temp' },
    username: { type: String, required: true, trim: true, lowercase: true, index: { unique: true } },
    password: { type: String, required: true },
    login_attempts: { type: Number, required: true, default: 0 },
    locked_until: { type: Number } ,
},

contact: {
    first_name: String,
    last_name: String,
    nick_name: String,
    email: { type: String, required: true, trim: true, lowercase: true, index: { unique: true } },
    phone: { type: String, required: false, trim: true, index: { unique: true, sparse: true } }
},

},{collection: 'user' });



-v-v-v-v-v-v-v-v-v-v-v-v-



var mongoose        = require('mongoose'),
    User            = mongoose.model('User');

var newUser = new User(data);

newUser.save(function (err) {

    if(err) { return cb(err); }
    // Call takes ~1.5+ seconds

});

User.collection.insert(data, function(err, user){

    if(err) { return cb(err); }
    // Call takes ~50ms

});
1
How are you actually timing this? Are you in fact accounting for the initial database connection? - Neil Lunn
Responce time for POST request is 1.5+ seconds, if it was initial DB connection, doing the same request again right after would be fine but its the same. I am using console.time('label') > console.timeEnd('label') to check where the delay is. - Labithiotis
That is not very informative. You were asked a specific question. Alter your question to show exactly how you are measuring your claimed response. That gives us something to work with, which your present question does not. - Neil Lunn
Found the cause, it was actually to do with a 'presave' model call where I was using a SALT FACTOR of 14 to hash user password, surprised how much of a difference it is between 10 to 14. Sorry to waste your time @NeilLunn - Labithiotis

1 Answers

2
votes

The cause was a 'presave' call and setting the salt factor to high:

userSchema.pre('save', function(next) {

// only hash the password if it has been modified (or is new)
if (!this.isModified('auth.password')) return next();

var user = this;

// generate a salt
bcrypt.genSalt(14 /*<< Setting to 14 from 10 caused call to be 10x slower */, function(err, salt) {
    if (err) return next(err);

    // hash the password using our new salt
    bcrypt.hash(user.auth.password, salt, function (err, hash) {
        if (err) return next(err);

        // set the hashed password back on our user document
        user.auth.password = hash;
        next();
    });
});

});