Es porque estás haciendo una conversión implícita de una fecha y hora mysql a un número entero.
P.ej. mysql piensa que el tiempo (mientras escribo esto) es 2011-12-15 13:42:10 pero si le pido a mysql que reste 90 de esto, sería 20111215134210 - 90 =20111215134120 que es 13:41:20 que es 50 hace unos segundos.
Trate la hora como un número entero (convirtiendo a/desde una marca de tiempo de Unix, como sugiere licorvicar) o use las funciones de fecha para hacer operaciones matemáticas en un valor de fecha:
SELECT *,
timediff(NOW(), attempt_time) diff,
timediff(NOW(), attempt_time + INTERVAL 90 SECONDS) pending,
NOW() nw
FROM failed_login
WHERE (username = 'some_username'
OR attempt_ip = '127.0.0.1')
AND NOW() - INTERVAL 90 SECONDS > attempt_time;
(Tenga en cuenta que también reescribí la última expresión de filtro de modo que la columna de la tabla esté aislada en un lado de la expresión, lo que tiene un pequeño beneficio de velocidad cuando la columna no está indexada, pero un gran beneficio cuando está indexada).
O usando segundos desde la época....
SELECT *,
UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(attempt_time) diff,
UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(attempt_time) + 90 pending,
NOW() nw
FROM failed_login
WHERE (username = 'some_username'
OR attempt_ip = '127.0.0.1')
AND UNIX_TIMESTAMP(NOW()) - 90 > UNIX_TIMESTAMP(attempt_time);
(que obviamente no podrá utilizar la optimización de índices).