I'm possibly off base here but I track each and every hit on a per-day basis:
INSERT INTO activity ( user, hour, last, hits )
VALUES (?, ?, ?, 1)
ON DUPLICATE KEY
SET last = VALUES(last), hits = hits + 1
This provides for a general overview of their activity (hits) on an hourly basis, (primary key is user,hour) and obviously provides a last timestamp. In my case, a who is online is not delimited by a fixed value - 5 minutes, 15 minutes, 1 hour etc - but simply presented as a list which the user can expand or contract to suit. Times are not actually used anywhere - rather only differences in time. GC can aggregate historical data into more manageable blocks and prune the table to within acceptable limits on a daily / weekly basis.