upsert + cache