How can I add programmatically a Tag after SAVE_ON event in case of Assets types We have to update the Asset after the SAVE_ON event, and the 

Craft::$app-&gt;elements-&gt;saveElement($asset);


Not seems to be working (it is getting timed out). So what is the best pratice to update the Asset after the save, which event should we use for example auto-tagging?

If we are trying to save the entry, it is working like charm, maybe we should query the asset parent first?

Update some additional findings:
It's turned out it is not so easy to re-save the assets after the SAVE_ON. We need to add additional parameters - based on the class rules:

$rules[] = [['newLocation'], 'required', 'on' =&gt; [self::SCENARIO_CREATE, self::SCENARIO_FILEOPS]];
$rules[] = [['tempFilePath'], 'required', 'on' =&gt; [self::SCENARIO_CREATE, self::SCENARIO_REPLACE]];


Obviously the goal is to just add some tags/category to the image (eg: getting back the tags data from cloudanary auto tagging interface via the filesystem, so we are not able to use the before save event).
So if we are simply trying to save the $asset it is not going to work, because we do not have newLocation either the tempFilePath is old as well. Instead we have to change the scenario, and save the asset after that (the idea was coming after checking the ElementController)

$element-&gt;setScenario(Element::SCENARIO_LIVE);
$element-&gt;setFieldValue('fieldHandle', $ids);
Craft::$app-&gt;getElements()-&gt;saveElement($element);


I do not have better idea for Asset save (specially because the asset itself was saved, and only the fields has to be updated), but this solution is working like charm, and the same logic is applied on the CP. If only the fields are getting updated the ElementController is getting called otherwise the AssetController. Hopes it helps for future reference
A Tag field is like every other relation field. Just insert an array of ids in the field and save the element

$element-&gt;setFieldValue('fieldHandle', [1,2,3,4,5,6]);
Craft::$app-&gt;getElements()-&gt;saveElement($element);


In order to get the current ids and add one, just do

$ids = $element-&gt;getFieldValue('fieldHandle')-&gt;ids();
$ids[] = 'yourNewTagId';
$element-&gt;setFieldValue('fieldHandle', $ids);
Craft::$app-&gt;getElements()-&gt;saveElement($element);


To Create a new Tag do

$tag = new Tag();
$tag-&gt;title = "your new tag name";
$tag-&gt;groupId = 1;
Craft::$app-&gt;getElements()-&gt;saveElement($tag);

// and add it to the element
$element = Craft::$app-&gt;getElements()-&gt;getElementById(2);
$ids = $element-&gt;getFieldValue('fieldHandle')-&gt;ids();
$ids[] = $tag-&gt;id;
$element-&gt;setFieldValue('fieldHandle', $ids);
Craft::$app-&gt;getElements()-&gt;saveElement($element);


Edit: 

Note that I'm using the setFieldValue directly instead of the magic __get and __set methods for a better performance.