Instead of going deep into callbacks, break them up into easily understandable functions:
function GetUserData(id, callback) {
// db queries, etc
connection.query('...get user info...', function (err, results) {
connection.query('...get user related whatnot...', function (err, results) {
callback ();
});
});
}
connection.query('...load page data...', function (err, results) {
GetUserData( function () {
res.render('page.ejs', ... );
});
});
You could even break the more used functions off into a module so you don't have too much clutter in your code. The async package looks nice, but to me, personally, I like to see the flow. Always up to programmer's preference.