im attempting to rotate a gameobject by 90 degrees on y axis instantly every time the r key is pressed. using transform.rotate it works except its off by +/- 2 degrees every time.

if (Input.GetKeyDown(KeyCode.R))
{
var tsr = Tempship.transform.localRotation;
var yrot = Tempship.transform.localRotation.y + 90;
Tempship.transform.Rotate(tsr.x, yrot, tsr.z);
}

the object being rotated is an empty gameobject with child objects that have meshs.

The problem is that the values in localRotation are part of a Quaternion, and do not represent angles in degrees. The internal values (x, y, z and w) of the Quaternion are based on complex numbers, and do not in any way represent angles. What you require is the Euler property from the localRotation, something like this:

if (Input.GetKeyDown(KeyCode.R))
{
var tsr = Tempship.transform.localRotation;
Vector3 tsr_eulers = tsr.eulerAngles;
Tempship.transform.Rotate(tsr_eulers.x, tsr_eulers.y + 90, tsr_eulers.z);
}

This code obtains the eulerAngles property from the localRotation, which ARE the angles in degrees. Note that transform.Rotate now uses tsr_eulers exclusively, because only tsr_eulers can provide the angles in degrees, not the x, y, z or w components of the Quaternion (localRotation).

This is why LCStark has advised you to use a rotation (through multiplication) of the quaternion by creating a quaternion out of euler angles using the static Euler method. That, too, acknowledges that the internals of quaternions are not angles.

I posted this version so you could better understand what is going wrong in your existing code, but there’s a catch. LCStark’s recommendation is, perhaps, more appropriate as a habit or paradigm to follow, that of rotating quaternions. In either case you have to be aware that quaternions by themselves are limited to accepting euler angles in the range of -180 to 180 degrees, which takes some care.