Labithiotis
Labithiotis

Reputation: 4139

Mongoose .save call is very slow

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

});

Upvotes: 1

Views: 2625

Answers (1)

Labithiotis
Labithiotis

Reputation: 4139

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();
    });
});

});

Upvotes: 4

Related Questions