Is storing data that can be inferred go against data normalization? To simplify lets say I have two tables PROJECTS and JOBS. A user creates a project and runs 1 or more jobs using a project.

So it would possible look something like this:

PROJECTS


[PK] project_id
etc.


JOB


[PK] job_id
[FK] project_id
job_run_date
etc.


Ideally I want to be able to list all projects by last used (last job run) and display them to the user. When I create a job, I can insert the job then update the project entry to have a last used; or I can just have it insert the job, then when I'm displaying all projects, I can do a join and aggregation with JOBS to get the last used date.

I figure, the drawback of the join is that as you have more jobs, performance may be slowly impacted over time to do the joins and aggregations. Whereas, being somewhat redundant increases the chance of a transaction failure and wastes a bit of space.

If I were to choose the update both tables (i.e. have a last_used` column in PROJECTS), would that be going against normalization (or good db design practices)?
Storing an attribute derived from a different table does introduce some risk of inconsistent data, if you fail to update projects after updating jobs for some reason, so you need to develop means to maintain integrity, e.g. by adding a trigger to jobs. 

It does not necessarily goes against normalization principles per se, because you can model the project entity to include the last_used attribute and then your projects table remains in the same normal form as it was before.

Storing a bit of redundant data is a valid optimization technique when warranted. Computed columns, materialized views etc. fall in that category. If you exhaust other ways to make your application perform according to the specifications, you can use denormalization, knowing and mitigating its risks.