improved with timeout